关于JDBC中查询方法的抽取
萌新的JAVA学习笔记[1]
先来张伊蕾娜镇场~~

简单描述
起初我们的查询方法时分为单个查询和全部查询,过于局限与繁琐,如此一来我们能不能想一个办法将所有类型的查询抽取出来并整合成为一个单独的工具方法,并使之具有较为方便的通用性。
-----------------------------------------------------------------------------------
思路整理
想要进行整合,首先我们得先寻找其中的差异点,以及共同点;
共同点:
都需要SQL语句;
都需要获取连接对象;
都需要获取结果集对象;
都需要获取语句对象;
都需要将从SQL语句中读到的数据信息赋给用于封装数据的对象;
以及都需要关闭资源。
差异点:
查询范围不同;
因为查询范围不同而导致的SQL语句不同;
传入的参数不同;
返回的值类型不同(但都可以用集合接收输出)。
| 如此一来,思路便逐渐清晰了起来 |
但同时又面临新的问题,因为通用性问题,我们并不知道我们所用来封装数据的时候所用到的对象的类型,这里很容易让人想到反射以及泛型;
同时,我们也并不知道当执行查询的时候所用到的SQL语句的参数是什么类型,这里我们可以用Object...params数组来解决。
那么,我们便开始吧~~
分步明晰
首先,是我们的方法所需要传入的参数,第一个就是我们执行SQL所需要使用的SQL语句了,这个需要调用者根据不同的查询范围自行传入;
第二个便是我们用来封装对象的类的字节码对象了,这个在我们使用内省操作字段的时候需要使用,因为不知道对象类型,所以我们这里使用泛型;
最后我们再设置SQL语句执行所需要调用的参数,因为参数类型繁多,我们这里使用Object...params,代表传入的值可以有0-n个。
java String sql, Class<T> type, Object...params
再接着,是各个对象的声明(在外面声明,不然在之后没法关)以及用来接收封装数据对象的集合的创建,这里使用上面声明的泛型;
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
List<T> list = new ArrayList<>();
然后是不厌其烦的获取连接对象以及语句对象,这里使用我们已经写好的获取连接对象的方法;
conn = JDBCUtil.getConnection();
ps = conn.prepareStatement(sql);
再接下来,是为传入的SQL语句的占位符"?"设置值,这里使用循环遍历params数组就行了;
for (int i = 0; i < params.length; i++) {
ps.setObject(i + 1, params[i]);
}
下面我们来获取结果集对象,再对它进行遍历,使用getObject方法将其中的数据取出来,然后通过内省将数据封装进对象中,最后再用list集合接收;
rs = ps.executeQuery();
// 直到next方法返回false时结束
while (rs.next()) {
// 获取这一行中的指定列的数据
//使用反射创建对象
T t = type.newInstance();
//将数据从结果集中获取到,并设置给对象t
//通常情况下,属性名和列名一样,所以我们可以根据属性名去获取对应列的值
BeanInfo beanInfo = Introspector.getBeanInfo(t.getClass(),
Object.class);
PropertyDescriptor[] pds =
beanInfo.getPropertyDescriptors();
//操作每个属性
for (PropertyDescriptor pd : pds) {
//获取到属性名
String name = pd.getName();
//根据这个属性名从结果集中获取到数据
Object value = rs.getObject(name);
//获取到属性对应的set方法
Method writeMethod = pd.getWriteMethod();
writeMethod.invoke(t, value);
}
list.add(t);
因为这步中的代码有点长,所以我们来稍微解析一下循环中内容。
首先获取实例对象到获取类中的属性就不细说了,然后是遍历获取到的包含了所有属性的描述器数组;
获取属性名之后通过getObject得到我们所需要的属性所对应的值,再通过各个属性描述器获取到对应属性的set方法;
最后调用invok方法将遍历结果集得到的值传入,并将的到的对象存入集合中。
完整代码
/**
* 处理查询操作
* <T>:是声明泛型类型
* List<T>, Class<T>使用声明好的T
* @param sql 要执行的SQL语句
* @param type 将每行数据封装的对象类型
* @param params 执行的SQL需要的参数
* @return 返回查询到的结果,统一放到List集合中
*/
public static <T> List<T> executeQuery(String sql, Class<T> type, Object...params){
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
List<T> list = new ArrayList<>();
try {
conn = JDBCUtil.getConnection();
ps = conn.prepareStatement(sql);
//为占位符设值
for (int i = 0; i < params.length; i++) {
ps.setObject(i + 1, params[i]);
}
rs = ps.executeQuery();
// 直到next方法返回false时结束
while (rs.next()) {
// 获取这一行中的指定列的数据
//使用反射创建对象
T t = type.newInstance();
//将数据从结果集中获取到,并设置给对象t
//通常情况下,属性名和列名一样,所以我们可以根据属性名去获取对应列的值
BeanInfo beanInfo = Introspector.getBeanInfo(t.getClass(),
Object.class);
PropertyDescriptor[] pds =
beanInfo.getPropertyDescriptors();
//操作每个属性
for (PropertyDescriptor pd : pds) {
//获取到属性名
String name = pd.getName();
//根据这个属性名从结果集中获取到数据
Object value = rs.getObject(name);
//获取到属性对应的set方法
Method writeMethod = pd.getWriteMethod();
writeMethod.invoke(t, value);
}
list.add(t);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtil.close(conn, ps, rs);
}
return list;
}
总结
当我们没法明确获悉对象的具体类型应该要想到反射和泛型,寻找相似方法的共同性和差异性并将它们提取出来,这是一种很不错的思路。
最后天道酬勤,反射内省的使用并没有想象中那么复杂,多练多用,便是我们逐渐登高的唯一途径。
伊蕾娜世界第一! ︎
关于JDBC中查询方法的抽取的更多相关文章
- jdbc基本查询方法
jdbc操作数据库时,最基本的三种接口是Statement PreparedStatment CallableStatement (1)Statement createStatement() cre ...
- Spring Data JPA的Respository接口中查询方法
- YII AR查询方法
ActiveRecord类文档:http://www.yiiframework.com/doc/guide/1.1/en/database.ar 对于一个Model Post 有如下的4中查询方法,返 ...
- 使用JDBC从数据库中查询数据的方法
* ResultSet 结果集:封装了使用JDBC 进行查询的结果 * 1. 调用Statement 对象的 executeQuery(sql) 方法可以得到结果集 * 2. ResultSet 返回 ...
- <五>JDBC_利用反射及JDBC元数据编写通用的查询方法
此类针对javaBean类写了一个通用的查询方法,List<javaBean> 通用查询更新中...:通过学习,深刻体会到学会反射就等于掌握了java基础的半壁江山! 一.使用JDBC驱动 ...
- [原创]java WEB学习笔记109:Spring学习---spring对JDBC的支持:使用 JdbcTemplate 查询数据库,简化 JDBC 模板查询,在 JDBC 模板中使用具名参数两种实现
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...
- 使用JDBC从数据库中查询数据
* ResultSet 结果集:封装了使用JDBC 进行查询的结果 * 1. 调用Statement 对象的 executeQuery(sql) 方法可以得到结果集 * 2. ResultSet 返回 ...
- Jmeter JDBC Request 查询语句中有汉字查询结果为空的解决方法
搜索接口我会校验返回值,查询JDBC Request 查询语句有中文字的时候查询会有问题. 解决方法很简单,在JDBC Connection Configuration的Database URL里加一 ...
- Java -- JDBC_利用反射及 JDBC 元数据编写通用的查询方法
先利用 SQL 进行查询,得到结果集: 利用反射创建实体类的对象:创建对象: 获取结果集的列的别名: 再获取结果集的每一列的值, 结合 3 得到一个 Map,键:列的别名,值:列的值: 再利用反射为 ...
随机推荐
- anchor-animation
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- ARC122C-Calculator【乱搞,构造】
正题 题目链接:https://atcoder.jp/contests/arc122/tasks/arc122_c 题目大意 一个数对开始是\((0,0)\),每次可以选择一个数加一或者让一个数加上另 ...
- Java(一)——基础知识
引言 之前一直对 Java 怀有固执的偏见,以为 Java 是编写前端的语言,作为一个机械生,非常抗拒去学它. 但是最近接触一点以后,完全改观了先前的看法,于是开启了对 Java 的大学习. 一.数据 ...
- 域名系统-DNS
域名系统DNS 域名系统DNS(Domain Name System)是互联网使用的命名系统,用来把便于人们使用的机器名转化为IP地址,域名系统就是名字系统. 很多应用层的软件经常直接使用DNS.DN ...
- MySQL高可用架构-MMM、MHA、MGR、PXC
主从复制如何工作 在主库把数据记录到binlog(二进制日志). 备库开IO线程把binlog复制到自己的relaylog(中继日志). 备库读取中继日志,重放到备库上. 半同步复制 半同步复制可以确 ...
- Java初步学习——2021.10.12每日总结,第六周周二
(1)今天做了什么: (2)明天准备做什么? (3)遇到的问题,如何解决? 今天学习了菜鸟教程Java实例,数组 1.数组的排序和元素的查找--sort和binarySearch方法 import j ...
- Java(28)集合三Map
作者:季沐测试笔记 原文地址:https://www.cnblogs.com/testero/p/15228436.html 博客主页:https://www.cnblogs.com/testero ...
- fastjson及其反序列化分析--TemplatesImpl
fastjson及其反序列化分析 源码取自 https://www.github.com/ZH3FENG/PoCs-fastjson1241 参考 (23条消息) Json详解以及fastjson使用 ...
- Visual Studio Debug only user code with Just My Code
Debug only user code with Just My Code By default, the debugger skips over non-user code (if you wan ...
- .NET CLI简单教程和项目结构
WHAT IS .NET CLI ? .NET 命令行接口 (CLI) 工具是用于开发.生成.运行和发布 .NET 应用程序的跨平台工具链. 来源:.NET CLI | Microsoft Docs ...