JDBC 框架
来源:互联网 发布:无锡知谷 拖欠 编辑:程序博客网 时间:2024/05/22 17:01
有两种方法可以实现对数据库统一的增删改查操作,一个是利用反射,一个是利用元数据。前者虽然实现简单,但是反射毕竟性能较低,不适合在移动设备上使用,下面我用两种方法实现 JDBC 的一个小框架。
一、利用反射技术
思路分析:
我们对数据库的增删改查操作可以分为两类,一类是增删改即 update,一类是查询即 select。之所以这样分,是因为对数据库的增删改不需要涉及到 Bean 的操作,而查询就要分析我们要查询的对象。
首先我们考虑更新,我们需要用户将 sql 语句,参数传递给我们,然后我们可以利用 PreparedStatement 对象动态的将参数加入到预编译的 sql 中,这很简单,只需几行代码搞定,参数列表可以是数组,也可以是可变参。
查询操作我们除了需要知道上面的两个参数以外,还要知道我们操作的是什么 Bean,这也有两种方式,一种是让用户将 Bean 的 Class 字节码给我们,我们利用反射获取 Bean 里面的每一个字段,之后通过字段名内省出 Bean 的所有属性,从而达到将数据封装到 Bean 的效果。还有一种方式是用到策略模式,我们既然不知道要操作什么 Bean,那么我们就让用户来决定,我们只需要给用户暴露一个接口,将 ResultSet 传过去,用户就可以自己封装数据。为了简化用户操作,我们可以事先写好几个常用的实现类。下面我就演示如何用几行代码搞定增删改查操作:
public static <T> T crud(Class<?> type, String sql, Object... param) {Connection con = getConnection();PreparedStatement ps = null;ResultSet rs = null;T t = null;try {ps = con.prepareStatement(sql);for (int i = 1; param != null && i <= param.length; i++) {ps.setObject(i, param[i - 1]);}boolean execute = ps.execute();if (execute) {t = (T) type.newInstance();rs = ps.getResultSet();rs.next();Field[] fields = t.getClass().getDeclaredFields();for (int i = 0; i < fields.length; i++) {String fieldName = fields[i].getName();Object data = rs.getObject(fieldName);PropertyDescriptor descriptor = new PropertyDescriptor(fieldName, t.getClass());Method method = descriptor.getWriteMethod();method.invoke(t, data);}}} catch (Exception e) {throw new RuntimeException(e);} finally {release(con, ps, rs);}return t;}
二、利用元数据
思路分析:
上面的代码虽然简单,但是性能比较差,如果我们利用数据库元数据信息,就可以大大提升效率。至于数据库的元数据可以分为:DataBaseMetaData、ParameterMetaData、ResultSetMetaData。他们分别是数据库元数据,我们可以通过 DataBaseMetaData 获取与库相关的信息,比如 url、用户名、版本号、驱动名等等。ParameterMetaData 我们可以获取 sql 语句中的参数个数、参数类型。ResultSetMetaData 可以得到表的列数、指定列的名称、指定列的类型等。有了以上信息,我们为我们利用元数据实现 CRUD 很简单。这种方式我将利用策略模式实现。就是将封装数据的行为交给用户,当然,框架就是更方便的满足用户需求,我也将写两个实现类。
工具类:
package cn.dk.tools;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.sql.Statement;import com.mchange.v2.c3p0.ComboPooledDataSource;public class CrudTool {private static ComboPooledDataSource source = new ComboPooledDataSource("mysql");public static Connection getConnection() {try {return source.getConnection();} catch (Exception e) {throw new ExceptionInInitializerError(e);}}public static void release(Connection con, Statement st, ResultSet rs) {if (rs != null) {try {rs.close();} catch (SQLException e) {} finally {try {st.close();} catch (SQLException e) {} finally {try {st.close();} catch (SQLException e) {} finally {try {con.close();} catch (SQLException e) {}}}}}}public static int update(String sql, Object[] param) {Connection con = getConnection();PreparedStatement ps = null;try {ps = con.prepareStatement(sql);for (int i = 0; param != null && i < param.length; i++) {ps.setObject(i + 1, param[i]);}return ps.executeUpdate();} catch (SQLException e) {throw new RuntimeException(e);}}public static Object select(String sql, Object[] param,IResultSetHandler handler) {Connection con = getConnection();PreparedStatement ps = null;ResultSet rs = null;try {ps = con.prepareStatement(sql);for (int i = 0; param != null && i < param.length; i++) {ps.setObject(i + 1, param[i]);}rs = ps.executeQuery();return handler.fillObject(rs);} catch (SQLException e) {throw new RuntimeException(e);} finally {release(con, ps, rs);}}public static Number selectNum(String sql, Object[] param) {Connection con = getConnection();PreparedStatement ps = null;ResultSet rs = null;try {ps = con.prepareStatement(sql);for (int i = 0; param != null && i < param.length; i++) {ps.setObject(i + 1, param[i]);}rs = ps.executeQuery();if(rs.next())return (Number) rs.getObject(1);} catch (SQLException e) {throw new RuntimeException(e);} finally {release(con, ps, rs);}return 0;}}
实现类1:封装 Bean
package cn.dk.tools;import java.beans.PropertyDescriptor;import java.lang.reflect.Method;import java.sql.ResultSet;import java.sql.ResultSetMetaData;@SuppressWarnings("unchecked")public class BeanHandler implements IResultSetHandler {public BeanHandler(Class clazz) {this.clazz = clazz;}private Class clazz;public Object fillObject(ResultSet rs) {ResultSetMetaData metaData;try {Object instance = clazz.newInstance();if (rs != null && rs.next()) {metaData = rs.getMetaData();int columnCount = metaData.getColumnCount();for (int i = 0; i < columnCount; i++) {String propertyName = metaData.getColumnName(i + 1);Object object = rs.getObject(propertyName);PropertyDescriptor descriptor = new PropertyDescriptor(propertyName, clazz);Method writeMethod = descriptor.getWriteMethod();writeMethod.invoke(instance, object);}}return instance;} catch (Exception e) {throw new RuntimeException(e);}}}
实现类2:返回集合
package cn.dk.tools;import java.beans.PropertyDescriptor;import java.lang.reflect.Method;import java.sql.ResultSet;import java.sql.ResultSetMetaData;import java.util.ArrayList;import java.util.List;@SuppressWarnings("unchecked")public class BeanListHandler implements IResultSetHandler {public BeanListHandler(Class clazz) {this.clazz = clazz;}private Class clazz;public Object fillObject(ResultSet rs) {ResultSetMetaData metaData;try {List list = null;if (rs != null) {list = new ArrayList();while (rs.next()) {Object instance = clazz.newInstance();metaData = rs.getMetaData();int columnCount = metaData.getColumnCount();for (int i = 0; i < columnCount; i++) {String propertyName = metaData.getColumnName(i + 1);Object object = rs.getObject(propertyName);PropertyDescriptor descriptor = new PropertyDescriptor(propertyName, clazz);Method writeMethod = descriptor.getWriteMethod();writeMethod.invoke(instance, object);}list.add(instance);}}return list;} catch (Exception e) {throw new RuntimeException(e);}}}
这种方法就给了我们一种思想,一种解决问题的思路。
- JDBC 框架
- JDBC框架
- JDBC框架
- jdbc框架
- JDBC框架
- JDBC框架
- 、Spring JDBC框架
- 编写JDBC框架
- 自己编写jdbc框架
- 自定义一个jdbc框架
- Spring JDBC框架
- Spring的JDBC框架
- 初识JDBC框架
- 框架灵魂---JDBC
- Spring 框架JDBC
- 自定义JDBC框架
- JDBC自定义框架
- JavaWeb-JDBC连接池、JDBC框架
- SVN 权限配置详解
- liunx下常用解压命令
- 精妙的SQL
- Keil arm 编译 RO RW ZI DATA
- SQL行列转换
- JDBC 框架
- MINIGUI常见错误集及解决方法
- 禁止MDI子窗口的关闭按钮\MDI中多视排列显示方式
- 《高效的JavaScript代码编写技巧》阅读笔记
- LINUX常用命令(基础)zz
- C/C++/.NET 语言考试题(加密/解密)
- 嵌入式arm中MMU原理剖析
- 【转】MiniGUI 1.3.3 移植详解 作者:大漠孤狼
- 一到关于数组排序的算法题