使用元数据简化jdbc代码---查询操作(用到反射)

一  思路分析

简化就是把共同的地方提取出来并放到一个方法里,在用到时只要调用就ok了,上一篇介绍了更新的操作,而查询的操作相对来说比较复杂,因为在查询之后不知道输出的列是多少,这是相对于框架的设计者来说的,但是如果相对于程序员是知道有多少列的,所以可以传一个接口,用实现类去给结果集赋值,并返回。

二  代码分析(根据ID获取)

1.提取简化的代码   DBManager.java

//对查询的优化

public static Object find(String sql, Object[] params, ResultSetHandler rsh) throws SQLException {

Connection con = null;

PreparedStatement st = null;

ResultSet rs = null;

try {

con = DBManager_c3p0.getConnection();

st = con.prepareStatement(sql);

for (int i = 0; i < params.length; i++) {

st.setObject(i + 1, params[i]);

}

rs = st.executeQuery();

// 对结果集的处理,不知道有多少行,给他传个方法,

// 即是调用程序员传过来对结果集进行处理 的方法

return rsh.handler(rs);

}  finally {

DBManager.release(con, st, rs);

}

}

注:Object[] params为占位符的数组

ResultSetHandler rsh对结果集的处理器,即上面所说的接口。

2.接口---用来向上一个方法中传的对象    ResultSetHandler.java

import java.sql.ResultSet;

//结果集处理器接口

public interface ResultSetHandler {

public Object handler(ResultSet rs);

}

3. 编写接口的实现类

public class MyResultSetHandler implements ResultSetHandler {

// 编写实现的类

public Object handler(ResultSet rs) {

User user = new User();

try {

if (rs.next()) {

user.setId(rs.getInt(1));

user.setName(rs.getString(2));

user.setPassword(rs.getString(3));

user.setEamil(rs.getString(4));

}

} catch (SQLException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

return user;

}

}

4.使用方法    UserDaoImpl.java

public void find() throws SQLException {

String sql = "select * from users where id=?";

Object[] params = { 5 };

MyResultSetHandler rsh = new MyResultSetHandler();

User user = (User) DBManager.find(sql, params, rsh);

System.out.println(user.toString());

}

5.测试

new UserDaoImpl().find();

三  缺陷思考和解决

1.缺陷

这样虽然可以解决查询的问题,但是只是相对于一个类,一个程序员知道类有多少列,但是如果让开发框架的人来写,他们不知道是什么类,不知道类中有多少列,所以要用到反射的机制来获取类,获取类的属性(数据库中的字段封装成的私有属性),这样实现接口的类又是一次变革。

2.实现接口的类

//作为框架的开发者,构建一个结果集的处理器,将结果集的一行记录封装在一个bean对象中

public class BeanHandler implements ResultSetHandler {

// 传递javabean对象的class对象

public Class clazz;// 一种类型的对象利用反射机制创建指定类型的对象

public BeanHandler(Class clazz) {

this.clazz = clazz;

}

public Object handler(ResultSet rs) {

try {

if (!rs.next()) {

return null;

}

// 读取结果集中的各个类封装到javabean中

// 创建的是javabean对象

Object bean = clazz.newInstance();

// 读取结果集的元数据对象-------得到结果集中有多少列

ResultSetMetaData meta = (ResultSetMetaData) rs.getMetaData();

// 得到一共有几列

int count = meta.getColumnCount();

for (int i = 1; i <= count; i++) {

// 得到第i列的列名

String columnName = meta.getColumnName(i);

// 从结果集中根据列名读取值

Object value = rs.getObject(columnName);

// 通过反射的机制得到javabean里的某一个属性对应的Field对象

Field f = bean.getClass().getDeclaredField(columnName);

f.setAccessible(true);

f.set(bean, value);

}

return bean;

} catch (Exception e) {

// 再次抛出异常,让上一级去处理

throw new RuntimeException(e);

}

}

}

3.用此方法去调用

public void findById() throws SQLException {

// 通过反射的机制去传任意一个javabean对象

String sql = "select * from users where id=?";

Object[] params = { 1 };

BeanHandler rsh = new BeanHandler(User.class);

User user = (User) DBManager.find(sql, params, rsh);

System.out.println(user.toString());

}

四  查询所有---用反射的机制获取并测试

1.查询所有并返回

public class BeanListHandler implements ResultSetHandler {

// 传递javabean对象的class对象

public Class clazz;// 一种类型的对象 利用反射机制创建指定类型的对象.

public BeanListHandler(Class clazz) {

this.clazz = clazz;

}

public Object handler(ResultSet rs) {

try {

List list = new ArrayList();

// 读取一行

while (rs.next()) {

// 封装到bean对象

Object bean = clazz.newInstance();

ResultSetMetaData meta = rs.getMetaData();

int count = meta.getColumnCount();

for (int i = 1; i <= count; i++) {

String columnName = meta.getColumnName(i);

// 通过列的名称读取列的值

Object value = rs.getObject(columnName);

// 得到属性值

Field f = clazz.getDeclaredField(columnName);

// 设置值 是私有的必须先为true,才可访问

f.setAccessible(true);

f.set(bean, value);

}

// 该bean对象加入到list集合

list.add(bean);

}

return list;

} catch (Exception e) {

throw new RuntimeException();

}

}

}

2.使用方法去调用

public List findAll() {

List list = null;

String sql = "select * from users";

Object[] params = {};

BeanListHandler rsh = new BeanListHandler(User.class);

try {

list = (List) DBManager.find(sql, params, rsh);

} catch (SQLException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

return list;

}

3.测试类

public static void main(String[] args) {

UserDaoImpl obj = new UserDaoImpl();

List<User> list = obj.findAll();

System.out.println(list.size());

for(User entity:list){

System.out.println(entity.toString());

}

}

使用元数据简化jdbc代码---查询操作(用到反射)的更多相关文章

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

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

  2. Java 使用JDBC连接查询操作数据

    import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; import java.sql. ...

  3. JDBC最原始的代码做查询操作

    首先编写一个User类. public class User { private String username; private String password; public String get ...

  4. 结合java的反射和泛型性质简化JDBC和相应的同步等服务器数据库操作代码

    github地址:https://github.com/hzphzp/HeartTrace_Server 我们的服务器端数据库并没有用sqllite, 而是直接用mysql,并且用JDBC直接进行操作 ...

  5. JDBC学习笔记(5)——利用反射及JDBC元数据编写通用的查询方法

    JDBC元数据 1)DatabaseMetaData /** * 了解即可:DatabaseMetaData是描述数据库的元数据对象 * 可以由Connection得到 */ 具体的应用代码: @Te ...

  6. 使用Spring简化JDBC操作数据库

    Spring的开发初衷是为了减轻企业级开发的复杂度,其对数据库访问的支持亦如此,使用Spring访问数据库能带来以下好处: 1.1     简化代码 使用原生的JDBC访问数据库,一般总是要执行以下步 ...

  7. 【转】JDBC学习笔记(5)——利用反射及JDBC元数据编写通用的查询方法

    转自:http://www.cnblogs.com/ysw-go/ JDBC元数据 1)DatabaseMetaData /** * 了解即可:DatabaseMetaData是描述数据库的元数据对象 ...

  8. MySQL数据库学习笔记(九)----JDBC的ResultSet接口(查询操作)、PreparedStatement接口重构增删改查(含SQL注入的解释)

    [声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...

  9. 使用Spring JDBCTemplate简化JDBC的操作

    使用Spring JDBCTemplate简化JDBC的操作 接触过JAVA WEB开发的朋友肯定都知道Hibernate框架,虽然不否定它的强大之处,但个人对它一直无感,总感觉不够灵活,太过臃肿了. ...

随机推荐

  1. C#(winform)实现不同DPI控件自适应1

    1. PicBox控件 顺便一提关键字:stretch [stretʃ] vt. 伸展,张开 //控制pictureBox图片的显示格式 this.picClose.BackgroundImageLa ...

  2. 了解SSL必须要懂得密码技术

    要理解SSL就必须理解密码系统.消息摘要函数(单向或散列函数)和数字签名,这些技术是许多文献所讨论的主题(比如[AC96),提供了保密性.完整性和认证的基础. 密码系统 假设Alice想给她的银行发一 ...

  3. oracle 树状结构递归 PL/SQL输出控制 包括空格输出控制

    树状结构 存储过程中通过递归构建,类似BBS回帖显示,代码共三段: 建表,插入数据,创建存储过程显示: 1.create table article(id number primary key,con ...

  4. IOS Masonry自动布局

    之前项目用Frame布局,这个项目登录用了VFL,后来觉得用Masonry,前天布局TableViewCell时用了下 ,觉得还不错. #import "Masonry.h" #i ...

  5. OpenTLD在VS2012和opencv246编译通过

    最近看到了TLD的跟踪视频,觉得很有意思,刚好最近在看行人检测所以就打算下载源码玩一玩,因为源码是Linux版本的(原作者写的是C++和MATLAB的混合编程)C++源码可以在我的博客TLD(一种目标 ...

  6. 如鹏网学习笔记(十三)EasyUI

    一.EasyUI简介 是一组基于JQuery的UI插件集合 主要作用:为JQuery对象提供新的方法,实现新的功能 可以快速创建出简洁.友好.美观的页面,非常适合做网站后台管理页面(不够漂亮,不适合做 ...

  7. xsl 和xml transform方法的调用

    xsl 和xml生成html,兼容多个浏览器 <html> <head> <meta charset="UTF-8"/> </head&g ...

  8. 【转载】Spring Cloud底层原理

    概述 毫无疑问,Spring Cloud是目前微服务架构领域的翘楚,无数的书籍博客都在讲解这个技术.不过大多数讲解还停留在对Spring Cloud功能使用的层面,其底层的很多原理,很多人可能并不知晓 ...

  9. java核心技术-NIO

    1.reactor(反应器)模式 使用单线程模拟多线程,提高资源利用率和程序的效率,增加系统吞吐量.下面例子比较形象的说明了什么是反应器模式: 一个老板经营一个饭店, 传统模式 - 来一个客人安排一个 ...

  10. 对JDK、JRE和JVM的一些浅薄理解

    JDK:JDK(Java Development Kit),顾名思义是java程序的开发包,任何java程序想要运行都需要相应版本的JDK,可以到oracle下载(下载之后自带JRE和编译工具等,无需 ...