JDBC——实现通用的查询
引言
上一篇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——实现通用的查询相关推荐
- 通用表查询返回所有行(只适用于单表)
@GetMapping(value = "/user") @ResponseBodypublic List<SysUser> getUser(String userNa ...
- Java、JSP通用SQL查询分析器
技术:Java.JSP等 摘要: 本文主要针对当前很多软件都无法实现跨数据库.跨平台来执行sql语句而用户又仅需做一些基本的增删改查操作的矛盾,设计了一个能够跨平台跨数据库的软件.此软件是一个通用SQ ...
- properties文件的用法;utils类封装数据库连接、资源关闭、通用的增删改,以及两种通用的查询方法
/*=========================properties文件使用===============================*/ 某*.properties文件内容例如: driv ...
- 通用SQL查询分析器
技术:Java.JSP等 摘要: 本文主要针对当前很多软件都无法实现跨数据库.跨平台来执行sql语句而用户又仅需做一些基本的增删改查操作的矛盾,设计了一个能够跨平台跨数据库的软件.此软件是一个通用SQ ...
- Hive的JDBC连接和数据查询功能
实验材料及说明 在Ubuntu系统的/学号(每个人之间的学号)/salesInfo目录下,有买家的购买记录文件Sales,该文件记录了买家的id,购买商品的id以及购买日期,文件为名为Sales.Sa ...
- java 查找一行_Java培训之工具类通用的查询一行多列,非实体
//通用的查询方法之四:查询多行多列,但每一行又不是一个JavaBean /* * SELECT did,AVG(salary),MAX(Salary) FROM t_employee GROUP B ...
- php 查看 实例 的方法,php – 从Laravel 5.1中的通用数据库查询中获取Eloquent模型的实例...
我有不同关系的模型.假设我的Entry模型属于供应商,所以通常我的模型文件中有一个supplier()方法. 到目前为止一切都那么好,当我有一些像Entry :: find(1) – >供应商这 ...
- c oracle 分页工具类,Util工具类 跨Oracle、MySQL通用分页查询
/**** 跨Oracle.MySQL通用分页查询*/public classPagingUtil { public static finalString MYSQL= "MYSQL&quo ...
- mybatis 鉴别其_MyBatis之Mapper XML 文件详解(四)-JDBC 类型和嵌套查询
MyBatis之Mapper XML 文件详解(四)-JDBC 类型和嵌套查询 白玉 IT哈哈 支持的 JDBC 类型 为了未来的参考,MyBatis 通过包含的 jdbcType 枚举型,支持下面的 ...
最新文章
- 连发10篇SCI!徐州二本学霸全奖直博香港城大引热议
- NYOJ 679 贪婪的商店
- 存储器芯片巨头动态观察:三星、美光、SK海力士都在做什么?
- MoinMoin Wiki 1.7优化与维护经验
- ARM中的ldr指令与adr、ldr伪指令之间的区别
- mysql varchar(20)_MySQL中采用类型varchar(20)和varchar(255)对性能上的影响
- python记事本_python记事本实现查询替换
- 零基础Python学习路线图,Python学习不容错过
- 专注问题本身,不是在博客上陈述自己不会的事实!!!
- mysql2表连接优化性能_MySQL性能优化方法二:表结构优化
- 自动化测试 短信验证登录
- ubuntu系统配置双网卡方法
- python源码剖析_《Python源码剖析》很值很强大!
- Android mvp 架构的自述
- 5G NR PUSCH non-codebook SRS/DMRS
- 如何应对社会人,如何应对平淡的物质世界
- MATLAB学习七(二):数组比较sortrows
- atlas mysql 分表,Atlas实现Mysql读写分离
- 用python实现植物大战僵尸(游戏截图+动态演示+源码分享)
- IGF1重组人胰岛素样生长因子-1解决方案
热门文章
- 「递归算法」看这一篇就够了|多图
- Python PyCharm利用PyQt5使QPlainTextEdit支持拖放文件,类提升,重写QPlainTextEdit类
- C++ DNN Opencv3.4 实现人脸计数和人脸检测
- java非检查性异常有哪些_Java异常处理-检查性异常、非检查性异常、Error
- java mac postgresql_PostgreSQL 的安装与使用 for mac
- html5群组选择器,css选择器
- python怎么做回归分析_如何在Python中进行二维回归分析?
- java开发环境怎么写_Java开发基础设置:如何配置Java运行环境
- element el-tree懒加载+搜索
- jeecg 查看 页面 父子表 横向滚动条效果 官方被禁用