引言

上一篇jdbc的文章《JDBC——概述与JDBC的使用》介绍了JDBC的概念和背景知识,同时也讨论了获取数据库连接的方式,以及简单的实现了入库操作(更新、删除同理)。

本篇博客将会聚焦 PreparedStatement 的查询操作、以及 ResultSet 的结果集处理逻辑,结合 ResultSetMetaData 和反射技术实现通用的查询方法。

一、Java与SQL对应数据类型转换表

Java类型 SQL类型
boolean BIT
byte TINYINT
short SMALLINT
int INTEGER
long BIGINT
String CHAR、VARCHAR、LONGVARCHAR
byte array BINARY、VAR BINARY
java.sql.Date DATE
java.sql.Time TIME
java.sql.timestamp TIMESTAMP

二、相关类

JDBCUtils 封装了获取连接关闭资源等通用操作(封装逻辑见《JDBC——概述与JDBC的使用》):

import java.io.InputStream;
import java.sql.*;
import java.util.Properties;public class JDBCUtils {public static Connection getConnection() {Connection connection = null;try {// 默认的识别路径就是 src 目录下InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("jdbc.properties");Properties props = new Properties();props.load(is);String url = props.getProperty("url");String username = props.getProperty("username");String password = props.getProperty("password");String driverName = props.getProperty("driverName");// 加载驱动类Class.forName(driverName);// 获取连接connection = DriverManager.getConnection(url, username, password);} catch (Exception e) {e.printStackTrace();}return connection;}public static void closeResource(Connection conn, Statement statement, ResultSet rs) {try {if (rs != null) {rs.close();}} catch (SQLException e) {e.printStackTrace();}try {if (statement != null) {statement.close();}} catch (SQLException e) {e.printStackTrace();}try {if (conn != null) {conn.close();}} catch (SQLException e) {e.printStackTrace();}}
}

二、查询一条记录

public static <T> T selectOne(Class<T> clazz, String sql, Object... args) {Connection connection = null;PreparedStatement ps = null;ResultSet rs = null;try {// 获取数据连接connection = JDBCUtils.getConnection();// 获取预编译语句对象ps = connection.prepareStatement(sql);// 填充属性值,注意下标从 1 开始for (int i = 0; i < args.length; i++) {ps.setObject(i + 1, args[i]);}// 执行查询,获取结果集rs = ps.executeQuery();// 获取结果集的元数据:ResultSetMetaDataResultSetMetaData rsmd = rs.getMetaData();// 通过元数据获取结果集中的列数int columnCount = rsmd.getColumnCount();// rs.next()方法判断是否存在下一条,相当于集合迭代器的 hasNext()if (rs.next()) {// 实体类必须包含空参构造器,才可以正常执行 newInstance()T t = clazz.newInstance();for (int i = 0; i < columnCount; i++) {// 获取别名(getColumnName()是获取列名,不建议使用)// 下标同样是从 1 开始String columnLabel = rsmd.getColumnLabel(i + 1);// 获取列值Object columnVal = rs.getObject(i + 1);// 通过反射封装对象Field field = clazz.getDeclaredField(columnLabel);field.setAccessible(true);field.set(t, columnVal);}return t;}} catch (Exception e) {e.printStackTrace();} finally {JDBCUtils.closeResource(connection, ps, rs);}return null;
}

三、查询集合

将 if (rs.next()) 换成 while(rs.next()) 即可,并通过构造一个 List 存储取得的对象元素。

总结

只要掌握了获取一条数据的通用方法,列表的处理逻辑就不在话下了。

需要关注一些重点:

1、PreparedStatement 填充占位符时,下标都是从 1 开始,通用的情况往往不知道填充的参数是何种类型,通过 setObject(..) 即可

2、与增删改不同的是,执行查询时,我们需要使用 executeQuery() 方法,并接收返回的 ResultSet 对象

3、ResultSet 并没有直接存储返回列的数量,我们需要获取到 ResultSetMetaData 获取列的数量,以及列的别名

4、rs.next() 实例方法用于判断结果集中是否存在下一条数据,它的作用相当于集合迭代器中的 hasNext() ,同时带有指针下移的操作

5、在使用 clazz.newInstance() 方法获取对象时,一定要记得实体类必须要有空参构造器

6、使用反射方法封装对象是唯一通用的方法,这样才能保证不论我们封装的是何种类型,都可以在运行时获取到对应的属性信息

JDBC——实现通用的查询相关推荐

  1. 通用表查询返回所有行(只适用于单表)

    @GetMapping(value = "/user") @ResponseBodypublic List<SysUser> getUser(String userNa ...

  2. Java、JSP通用SQL查询分析器

    技术:Java.JSP等 摘要: 本文主要针对当前很多软件都无法实现跨数据库.跨平台来执行sql语句而用户又仅需做一些基本的增删改查操作的矛盾,设计了一个能够跨平台跨数据库的软件.此软件是一个通用SQ ...

  3. properties文件的用法;utils类封装数据库连接、资源关闭、通用的增删改,以及两种通用的查询方法

    /*=========================properties文件使用===============================*/ 某*.properties文件内容例如: driv ...

  4. 通用SQL查询分析器

    技术:Java.JSP等 摘要: 本文主要针对当前很多软件都无法实现跨数据库.跨平台来执行sql语句而用户又仅需做一些基本的增删改查操作的矛盾,设计了一个能够跨平台跨数据库的软件.此软件是一个通用SQ ...

  5. Hive的JDBC连接和数据查询功能

    实验材料及说明 在Ubuntu系统的/学号(每个人之间的学号)/salesInfo目录下,有买家的购买记录文件Sales,该文件记录了买家的id,购买商品的id以及购买日期,文件为名为Sales.Sa ...

  6. java 查找一行_Java培训之工具类通用的查询一行多列,非实体

    //通用的查询方法之四:查询多行多列,但每一行又不是一个JavaBean /* * SELECT did,AVG(salary),MAX(Salary) FROM t_employee GROUP B ...

  7. php 查看 实例 的方法,php – 从Laravel 5.1中的通用数据库查询中获取Eloquent模型的实例...

    我有不同关系的模型.假设我的Entry模型属于供应商,所以通常我的模型文件中有一个supplier()方法. 到目前为止一切都那么好,当我有一些像Entry :: find(1) – >供应商这 ...

  8. c oracle 分页工具类,Util工具类 跨Oracle、MySQL通用分页查询

    /**** 跨Oracle.MySQL通用分页查询*/public classPagingUtil { public static finalString MYSQL= "MYSQL&quo ...

  9. mybatis 鉴别其_MyBatis之Mapper XML 文件详解(四)-JDBC 类型和嵌套查询

    MyBatis之Mapper XML 文件详解(四)-JDBC 类型和嵌套查询 白玉 IT哈哈 支持的 JDBC 类型 为了未来的参考,MyBatis 通过包含的 jdbcType 枚举型,支持下面的 ...

最新文章

  1. 连发10篇SCI!徐州二本学霸全奖直博香港城大引热议
  2. NYOJ 679 贪婪的商店
  3. 存储器芯片巨头动态观察:三星、美光、SK海力士都在做什么?
  4. MoinMoin Wiki 1.7优化与维护经验
  5. ARM中的ldr指令与adr、ldr伪指令之间的区别
  6. mysql varchar(20)_MySQL中采用类型varchar(20)和varchar(255)对性能上的影响
  7. python记事本_python记事本实现查询替换
  8. 零基础Python学习路线图,Python学习不容错过
  9. 专注问题本身,不是在博客上陈述自己不会的事实!!!
  10. mysql2表连接优化性能_MySQL性能优化方法二:表结构优化
  11. 自动化测试 短信验证登录
  12. ubuntu系统配置双网卡方法
  13. python源码剖析_《Python源码剖析》很值很强大!
  14. Android mvp 架构的自述
  15. 5G NR PUSCH non-codebook SRS/DMRS
  16. 如何应对社会人,如何应对平淡的物质世界
  17. MATLAB学习七(二):数组比较sortrows
  18. atlas mysql 分表,Atlas实现Mysql读写分离
  19. 用python实现植物大战僵尸(游戏截图+动态演示+源码分享)
  20. IGF1重组人胰岛素样生长因子-1解决方案

热门文章

  1. 「递归算法」看这一篇就够了|多图
  2. Python PyCharm利用PyQt5使QPlainTextEdit支持拖放文件,类提升,重写QPlainTextEdit类
  3. C++ DNN Opencv3.4 实现人脸计数和人脸检测
  4. java非检查性异常有哪些_Java异常处理-检查性异常、非检查性异常、Error
  5. java mac postgresql_PostgreSQL 的安装与使用 for mac
  6. html5群组选择器,css选择器
  7. python怎么做回归分析_如何在Python中进行二维回归分析?
  8. java开发环境怎么写_Java开发基础设置:如何配置Java运行环境
  9. element el-tree懒加载+搜索
  10. jeecg 查看 页面 父子表 横向滚动条效果 官方被禁用