萌新的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;
}

总结

当我们没法明确获悉对象的具体类型应该要想到反射和泛型,寻找相似方法的共同性和差异性并将它们提取出来,这是一种很不错的思路。

最后天道酬勤,反射内省的使用并没有想象中那么复杂,多练多用,便是我们逐渐登高的唯一途径。


  1. 伊蕾娜世界第一!

关于JDBC中查询方法的抽取的更多相关文章

  1. jdbc基本查询方法

    jdbc操作数据库时,最基本的三种接口是Statement PreparedStatment  CallableStatement (1)Statement createStatement() cre ...

  2. Spring Data JPA的Respository接口中查询方法

  3. YII AR查询方法

    ActiveRecord类文档:http://www.yiiframework.com/doc/guide/1.1/en/database.ar 对于一个Model Post 有如下的4中查询方法,返 ...

  4. 使用JDBC从数据库中查询数据的方法

    * ResultSet 结果集:封装了使用JDBC 进行查询的结果 * 1. 调用Statement 对象的 executeQuery(sql) 方法可以得到结果集 * 2. ResultSet 返回 ...

  5. <五>JDBC_利用反射及JDBC元数据编写通用的查询方法

    此类针对javaBean类写了一个通用的查询方法,List<javaBean> 通用查询更新中...:通过学习,深刻体会到学会反射就等于掌握了java基础的半壁江山! 一.使用JDBC驱动 ...

  6. [原创]java WEB学习笔记109:Spring学习---spring对JDBC的支持:使用 JdbcTemplate 查询数据库,简化 JDBC 模板查询,在 JDBC 模板中使用具名参数两种实现

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  7. 使用JDBC从数据库中查询数据

    * ResultSet 结果集:封装了使用JDBC 进行查询的结果 * 1. 调用Statement 对象的 executeQuery(sql) 方法可以得到结果集 * 2. ResultSet 返回 ...

  8. Jmeter JDBC Request 查询语句中有汉字查询结果为空的解决方法

    搜索接口我会校验返回值,查询JDBC Request 查询语句有中文字的时候查询会有问题. 解决方法很简单,在JDBC Connection Configuration的Database URL里加一 ...

  9. Java -- JDBC_利用反射及 JDBC 元数据编写通用的查询方法

    先利用 SQL 进行查询,得到结果集: 利用反射创建实体类的对象:创建对象: 获取结果集的列的别名: 再获取结果集的每一列的值, 结合 3 得到一个 Map,键:列的别名,值:列的值: 再利用反射为 ...

随机推荐

  1. 鸿蒙内核源码分析(内存汇编篇) | 谁是虚拟内存实现的基础 | 百篇博客分析OpenHarmony源码 | v14.14

    百篇博客系列篇.本篇为: v14.xx 鸿蒙内核源码分析(内存汇编篇) | 谁是虚拟内存实现的基础 | 51.c.h .o 内存管理相关篇为: v11.xx 鸿蒙内核源码分析(内存分配篇) | 内存有 ...

  2. P4783-[模板]矩阵求逆

    正题 题目链接:https://www.luogu.com.cn/problem/P4783 题目大意 给出一个矩阵,求它的逆矩阵. \(1\leq n\leq 400\) 解题思路 记给出矩阵\(P ...

  3. disruptor笔记之六:常见场景

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...

  4. 转载 使用wce进行本地和域的hash注入

    参数解释:-l 列出登录的会话和NTLM凭据(默认值)-s 修改当前登录会话的NTLM凭据 参数:<用户名>:<域名>:<LM哈希>:<NT哈希>-r ...

  5. 数据库建表权限 CREATE command denied to user for table

    今天在表中用Navicat连接服务器上的mysql账号进行建表,报了个这样类似的错, CREATE command denied to user for table 是数据库权限设置的问题,所以无法进 ...

  6. Java 集合基础入门,看这篇就够了

    集合 1.父接口:Collection java.util.Collection 是进行单对象保存的最大父接口,即每次利用 Collection 接口都只能保存一个对象信息.定义如下: public ...

  7. Java编译运行环境讨论(复古但能加深对Java项目的理解)

    Java编译运行环境讨论(复古但能加深对Java项目的理解) 如今我们大多数情况都会使用IDE来进行Java项目的开发,而一个如今众多优秀的IDE已经能够帮助我们自动的部署并调试运行我们的Java程序 ...

  8. Linear Referencing Tools(线性参考工具)

    线性参考工具 # Process: 创建路径 arcpy.CreateRoutes_lr("", "", 输出路径要素类, "LENGTH" ...

  9. 题解 Yet Another Number Sequence

    题目传送门 Description 给出 \(n,k\) ,求出: \[\sum_{i=1}^{n} f_i·i^k \] 其中 \(f_i\) 表示斐波拉契第 \(i\) 项.\(n\le 10^{ ...

  10. 合理占用服务器空闲GPU[狗头]

    合理占用服务器GPU资源[狗头] 场景:当你想进行模型训练时,发现GPU全被占用,怎么办? 解决方案1: 在终端输入如下命令:watch -n 设定刷新时间(s) nvidia-smi 然后记起来了回 ...