前面介绍了通过JDBC如何管理数据库,当时提到Statement专门提供了executeQuery方法用于查询操作,为什么查询操作这么特殊呢?这是因为其它语句跑完一次就了事了,顶多像insert、update、delete再返回受影响的记录数量,但select命令跟它们不一样,查询语句可能会返回多条记录,每条记录又包含多个字段。似此多条记录多个字段的情景,返回值无论定义为哪种类型都不太好办,故而干脆给个单独的executeQuery方法,该方法的返回值也设置成专属的ResultSet类型,表示查询方法返回了一个结果集,详细的记录结果请到结果集中遍历获得。
据此可将记录查询的操作过程分成以下四个步骤:
1、获取数据库连接:该步骤调用DriverManager类的getConnection方法获得连接对象。
2、创建该连接的执行报告:该步骤调用Connection对象的createStatement方法获得执行报告。
3、命令报告执行查询语句:该步骤调用报告对象的executeQuery方法来执行查询语句,并返回查询记录的结果集。
4、循环遍历结果集里面的所有记录:通常该步骤需调用结果集对象的next方法不断往后遍历,也就是将结果集的指示游标一步一步向后移动。在遍历过程当中,可能要调用结果集对象的其它方法进一步操作,ResultSet的常见方法分成三类,说明如下:
1、移动游标
该类方法可将当前游标移动到指定位置,主要包括下列方法:
next:将游标移到后一条记录。该方法返回true表示尚未移到末尾,返回false表示已经移到末尾。
absolute:将游标移到第几条记录,如果参数为负数则表示倒数的第几条。
first:将游标移到第一条记录。
last:将游标移到最后一条记录。
previous:将游标移到前一条记录。
beforeFirst:将游标移到第一条记录之前。
afterLast:将游标移到最后一条记录之后。
2、判断游标位置
该类方法可判断当前游标是否处于某个位置,主要包括下列方法:
isFirst:游标是否指向第一条记录。
isLast:游标是否指向最后一条记录。
isBeforeFirst:游标是否在第一条记录之前。
isAfterLast:游标是否在最后一条记录之后。
3、从当前游标获取数据
该类方法可从当前游标指向的记录中获取字段值,当方法参数为整型时,表示获取指定序号的字段值;当方法参数为字符串时,表示获取指定名称的字段值。相关的获取方法罗列如下:
getInt:获取指定序号或者指定名称的字段整型值。
getLong:获取指定序号或者指定名称的字段长整值。
getFloat:获取指定序号或者指定名称的字段浮点值。
getDouble:获取指定序号或者指定名称的字段双精度值。
getString:获取指定序号或者指定名称的字段字符串值。
getDate:获取指定序号或者指定名称的字段日期值。

接下来举几个具体应用的例子,首先要从teacher表中查询所有记录,则依次连接数据库、创建连接的报告、执行查询语句,再循环遍历结果集获取每条记录的字段信息。这一连串的查询代码示例如下:

   // 查询所有记录(默认排序)private static void showAllRecord() {String sql = "select * from teacher";// 连接数据库、创建连接的报告、执行查询语句try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword);Statement stmt = conn.createStatement();ResultSet rs = stmt.executeQuery(sql)) {while (rs.next()) { // 循环遍历结果集里面的所有记录int gonghao = rs.getInt("gonghao"); // 获取指定字段的整型值String name = rs.getString("name"); // 获取指定字段的字符串值Date birthday = rs.getDate("birthday"); // 获取指定字段的日期值int sex = rs.getInt("sex"); // 获取指定字段的整型值String course = rs.getString("course"); // 获取指定字段的字符串值String desc = String.format("工号为%d,姓名为%s,出生日期为%s,性别为%s,任教课程为%s。", gonghao, name, getFormatDate(birthday), sex==0 ? "男性" : "女性", course);System.out.println("当前教师信息为:"+desc);}} catch (SQLException e) {e.printStackTrace();}}

注意MySQL未提供将日期转成字符串的to_char函数,因而只能先取到Date类型的字段值,再将其通过Java代码转为字符串。日期类型转换为字符串类型的方法代码如下所示:

  // 获取指定格式的日期字符串public static String getFormatDate(Date date) {// 创建一个日期格式化的工具SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");// 将当前日期时间按照指定格式输出格式化后的日期时间字符串return sdf.format(date);}

接着运行上面的查询方法showAllRecord,观察到日志窗口完整输出了如下的五条记录信息。

当前教师信息为:工号为1,姓名为张老师,出生日期为1983-03-03,性别为女性,任教课程为语文。
当前教师信息为:工号为2,姓名为李老师,出生日期为1984-04-04,性别为男性,任教课程为数学。
当前教师信息为:工号为3,姓名为王老师,出生日期为1985-05-05,性别为女性,任教课程为英语。
当前教师信息为:工号为4,姓名为赵老师,出生日期为1986-06-06,性别为男性,任教课程为物理。
当前教师信息为:工号为5,姓名为刘老师,出生日期为1987-07-07,性别为女性,任教课程为化学。

然后在原语句增加排序条件,让所有记录按照生日字段降序排列,则修改后的查询代码如下所示:

  // 查询所有记录(按照生日倒序)private static void showAllRecordByBirthday() {String sql = "select * from teacher order by birthday desc";// 连接数据库、创建连接的报告、执行查询语句try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword);Statement stmt = conn.createStatement();ResultSet rs = stmt.executeQuery(sql)) {while (rs.next()) { // 循环遍历结果集里面的所有记录int gonghao = rs.getInt("gonghao"); // 获取指定字段的整型值String name = rs.getString("name"); // 获取指定字段的字符串值Date birthday = rs.getDate("birthday"); // 获取指定字段的日期值int sex = rs.getInt("sex"); // 获取指定字段的整型值String course = rs.getString("course"); // 获取指定字段的字符串值String desc = String.format("工号为%d,姓名为%s,出生日期为%s,性别为%s,任教课程为%s。", gonghao, name, getFormatDate(birthday), sex==0 ? "男性" : "女性", course);System.out.println("当前教师信息为:"+desc);}} catch (SQLException e) {e.printStackTrace();}}

增加了showAllRecordByBirthday方法之后,再次运行测试程序,从日志窗口可见这次的记录结果以生日字段降序显示了。

当前教师信息为:工号为5,姓名为刘老师,出生日期为1987-07-07,性别为女性,任教课程为化学。
当前教师信息为:工号为4,姓名为赵老师,出生日期为1986-06-06,性别为男性,任教课程为物理。
当前教师信息为:工号为3,姓名为王老师,出生日期为1985-05-05,性别为女性,任教课程为英语。
当前教师信息为:工号为2,姓名为李老师,出生日期为1984-04-04,性别为男性,任教课程为数学。
当前教师信息为:工号为1,姓名为张老师,出生日期为1983-03-03,性别为女性,任教课程为语文。

排序条件仅仅调整返回记录的顺序,然而分组条件就不一样了。因为分组条件存在统计操作,像count、sum、max这些函数只返回运算结果,但从结果集中取数据有赖于字段名称,所以需要在统计函数之后加个别名,相当于该函数的运算结果暂存于该别名变量。比如表达式“count(sex) count”说的就是计数结果以count命名,游标从count字段获取到的即为计数值。下面是对teacher表按照性别字段分组统计的查询代码例子:

   // 查询性别分组。注意要给count之类的函数结果分配别名private static void showRecordGroupBySex() {String sql = "select sex,count(sex) count from teacher group by sex order by sex asc";// 连接数据库、创建连接的报告、执行查询语句try (Connection conn = DriverManager.getConnection(dbUrl, dbUserName, dbPassword);Statement stmt = conn.createStatement();ResultSet rs = stmt.executeQuery(sql)) {while (rs.next()) { // 循环遍历结果集里面的所有记录int sex = rs.getInt("sex"); // 获取指定字段的整型值int count = rs.getInt("count"); // 获取指定字段的整型值String desc = String.format("%s老师有%d位;", sex==0 ? "男" : "女", count);System.out.print(desc);}} catch (SQLException e) {e.printStackTrace();}}

运行包含showRecordGroupBySex方法的测试程序,果然正确输出了预期的统计日志如下所示。

男老师有2位;女老师有3位;  


更多Java技术文章参见《Java开发笔记(序)章节目录》

转载于:https://www.cnblogs.com/pinlantu/p/11494099.html

Java开发笔记(一百四十八)通过JDBC查询数据记录相关推荐

  1. getvalue参数计数不匹配_OpenCV开发笔记(六十八):红胖子8分钟带你使用特征点Flann最邻近差值匹配识别...

    若该文为原创文章,未经允许不得转载 原博主博客地址:https://blog.csdn.net/qq21497936 原博主博客导航:https://blog.csdn.net/qq21497936/ ...

  2. Android开发笔记(六十八)工程库打包

    写好一个Android模块,比如说一个自定义控件或某个功能的sdk,然后开放出来给别人使用,就得通过某种方式把源码提供给对方.常见的打包方式有: 一.直接给源码,由开发者把代码加入到自己的工程中 该方 ...

  3. Java开发笔记(五十六)利用枚举类型实现高级常量

    前面介绍了联合利用final和static可实现常量的定义,该方式用于简单的常量倒还凑合,要是用于复杂的.安全性高的常量,那就力不从心了.例如以下几种情况,final结合static的方式便缺乏应对之 ...

  4. Android开发笔记(五十八)铃声与震动

    拖动条SeekBar SeekBar继承自进度条ProcessBar,有关ProcessBar的介绍见<Android开发笔记(四十九)异步任务处理AsyncTask>.SeekBar与P ...

  5. Java开发笔记(五十)几种开放性修饰符

    前面介绍子类继承父类的时候,提到了public(公共)和private(私有)两个修饰符,其中public表示它所修饰的实体是允许外部访问的:而private表示它所修饰的实体不允许外部访问,只能在当 ...

  6. java学习笔记(二十八)——开发一个小项目(VMeeting3.0)

    上篇文章按照较规范的产品需求文档梳理了项目的逻辑,感觉开发起来明晰了很多:挂上一篇文章java学习笔记(二十七)--开发一个小项目(VMeeting2.0)_Biangbangbing的博客-CSDN ...

  7. 【Java学习笔记之二十八】深入了解Java8新特性

    前言: Java 8 已经发布很久了,很多报道表明java 8 是一次重大的版本升级.在Java Code Geeks上已经有很多介绍Java 8新特性的文章,例如Playing with Java ...

  8. Android开发笔记(七十八)异常容错处理

    Exception Java的异常分两类,运行时异常RuntimeException和非运行时异常. 运行时异常包括空指针异常NullPointerException.数组越界异常IndexOutOf ...

  9. Android开发笔记(三十八)列表类视图

    AdapterView AdapterView顾名思义是适配器视图,Spinner.ListView和GridView都间接继承自AdapterView,这三个视图都存在多个元素并排展示的情况,所以需 ...

  10. Android开发笔记(二十八)利用Application实现内存读写

    全局变量 C/C++有所谓的全局变量,因为全局变量保存在内存中,所以操作全局变量就是操作内存,其速度远比操作数据库或者操作文件快得多,而且工程里的任何代码都可以引用全局变量,因此很多时候全局变量是共享 ...

最新文章

  1. Javascript Java C++系列
  2. df.isnull使用细节
  3. mysql导入source数据库sql的C++实现和封装
  4. php实现文字向左跑马灯,js实现文字跑马灯效果
  5. Spring MVC 接收POST表单请求,获取参数总结
  6. 为什么float只有四个字节,存储范围却大于有八个字节的long类型?
  7. 热释电传感器三个引脚_热释电传感器电路图大全(六款热释电传感器电路设计原理图详解)...
  8. 纯电动两档箱实际项目模型,本模型基于Cruise软件和搭建完成,本资料包包含所有源文件
  9. WebRAY幻影--防火墙中的战斗机即将起飞
  10. 不能为属性:[commandName]找到setter 方法
  11. mysql中 经纬度用什么类型存储_MySQL数据库之***mysql中经度纬度字段用什么存储(关于mysql的float和decimal区别)...
  12. matlab 化学方程式配平
  13. 亮道剧学铭:激光雷达系统量产上车没那么容易
  14. 2021年茶艺师(中级)考试报名及茶艺师(中级)考试试卷
  15. python四瓣花图形_Python竟能画这么漂亮的花,帅呆了(代码分享)
  16. 为什么书呆子不受欢迎? 《黑客与画家》
  17. AtCoder ABC161 E - Yutori
  18. 使用Postman玩转接口测试
  19. UVA 10570 Meeting with Aliens (枚举)
  20. CSR蓝牙芯片修改RF传输功率的方法

热门文章

  1. android intent json,如何从android中的Intent服务中的服务器获取Json响应?
  2. mysql 表的存储类型_MySQL的表类型和存储引擎
  3. 数学建模(零)入门统领
  4. 两个页面用url传值 和设置页面字段为不可编辑或是只读
  5. python图片x轴数据过多_一个操作证明python数据可视化比excel强百倍:X轴刻度间隔显示...
  6. jQuery基础(jQuery概念,jQuery与js入口函数的区别及其入口函数的其他写法和冲突问题)
  7. IDEA 这么设置 Maven,再也不用担心依赖下载失败了
  8. spring 包的依赖问题
  9. IntelliJ IDEA创建和配置Maven项目并运行
  10. 2.12.PHP7.1 狐教程-【PHP 全局变量】