自定义一个简单的jdbc框架,包含增加,修改,删除,查询方法,增,删改,比较简单 传入要执行的sql 和(prepareStatement)预编译 是需要的参数,本例子中使用可变参数 传入,通过下面代码设置预编译时需要的参数。 查询方法,将查询的的结果封装成相应的一个个对象,再将对象放入list返回。
// 设置参数 ParameterMetaData parameterMetaData = stmt.getParameterMetaData(); int count = parameterMetaData.getParameterCount(); for (int i = 1; i <= count; i++) { stmt.setObject(i, obj[i - 1]); } stmt.execute();
查询方法主要是将结果集封装成一个个javaBean 具体操作如下:
1 用rs.getMetaData();方法获得结果集元数据 ResultSetMetaData 结果集元数据 ---- 获得结果集列名称、数量、类型*/
ResultSetMetaData resultSetMetaData=rs.getMetaData();
2 获得总列数
int count =resultSetMetaData.getColumnCount();
3 内省技术获得类 要求要传入相应的 类.class */
BeanInfo beanInfo = Introspector.getBeanInfo(domainClass);
4 利用内省技术获得类中所有属性
PropertyDescriptor[] propertyDescriptors=beanInfo.getPropertyDescriptors();
5 遍历结果集
《1》 遍历所有的列
《2》 将所有的属性和每一列的字段比较 ,如果属性名和列的字段名相同 利用反射技术将该列的的值赋给和该列名字相同的属性。
内省:
内省(Introspector)是Java语言对JavaBean类属性、事件的处理方法
例如类User中有属性name,那么必定有getName,setName方法,我们可以通过他们来获取或者设置值,这是常规操作。
Java提供了一套API来访问某个属性的getter/setter方法,这些API存放在java.beans中
反射:
Java反射机制是在运行中,对任意一个类,能够获取得到这个类的所有属性和方法;
对于任意一个对象,都能够调用它的任意一个方法;
这种动态获取类信息以及动态调用类对象方法的功能叫做Java语言的反射机制
/*1 ResultSetMetaData 结果集元数据 ---- 获得结果集列名称、数量、类型*/ ResultSetMetaData resultSetMetaData=rs.getMetaData(); /*2 获得总列数*/ int count =resultSetMetaData.getColumnCount(); /*3 内省技术获得类 要求要传入相应的 类.class */ BeanInfo beanInfo = Introspector.getBeanInfo(domainClass); /*4 获得所有属性*/ PropertyDescriptor[] propertyDescriptors=beanInfo.getPropertyDescriptors(); /*5 遍历结果集*/ while(rs.next()){ /*<1> 获取泛型实例对象*/ T t=domainClass.newInstance(); /*<2>遍历每一个数据库中的字段 看是否与属性名字匹配 如果匹配就将 数据库中的取得的字段值放入属性中*/ for(int i=1;i<=count;i++){ //获得列名 String columnName=resultSetMetaData.getColumnName(i); for(PropertyDescriptor pd:propertyDescriptors){ /*属性名字和数据库中的名字匹配的时候为属性赋值*/ if(columnName.equals(pd.getName())){ /*username public void com.goke.User.setUsername(java.lang.String)pd.getWriteMethod() userpwd public void com.goke.User.setUserpwd(java.lang.String)pd.getWriteMethod() userdesc public void com.goke.User.setUserdesc(java.lang.String)pd.getWriteMethod() id 没有set 方法则显示 */ //获得对应的set 方法 Method setMethod=pd.getWriteMethod(); setMethod.invoke(t, new Object[]{rs.getObject(columnName)}); } } } list.add(t); }
详细代码如下:
package com.goke; import java.beans.BeanInfo; import java.beans.IntrospectionException; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.sql.Connection; import java.sql.ParameterMetaData; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; import com.rl.JDBCUtil; public class JDBCIfram { public static void main(String[] args) { BeanHanderInterface<User> beanHander=new BeanHanderImpl<>(User.class); /*String sqlInsert="insert into user (username,userpwd) values(?,?)"; Object [] obje={"liming","liming"}; insert(sqlInsert, obje); String sql="delete from user where username=? and userpwd=?"; //Object [] obj={"zhang","lei"}; delete(sql, new Object[]{"zhang","lei"}); */ String sql="select * from user"; System.out.println(query(sql, beanHander, null)); } /*查询*/ public static <T> List<T> query(String sql, BeanHanderInterface<T> beanHander,Object ...arg){ T obj = null; List<T> list=new ArrayList<>(); Connection conn = null; PreparedStatement stmt = null; ResultSet rs = null; try { conn = JDBCUtil.getConnection(); stmt = conn.prepareStatement(sql); // 设置参数 ParameterMetaData parameterMetaData = stmt.getParameterMetaData(); int count = parameterMetaData.getParameterCount(); for (int i = 1; i <= count; i++) { stmt.setObject(i, arg[i - 1]); } rs = stmt.executeQuery(); list = beanHander.hander(rs); } catch (SQLException e) { e.printStackTrace(); } finally { //JDBCUtil.colseResource(conn, stmt, rs); } return list; } /*插入*/ public static void insert(String sql ,Object[] obj){ Connection conn = null; PreparedStatement stmt = null; ResultSet rs = null; try { conn = JDBCUtil.getConnection(); stmt = conn.prepareStatement(sql); // 设置参数 ParameterMetaData parameterMetaData=stmt.getParameterMetaData(); int count =parameterMetaData.getParameterCount(); for (int i = 1; i <= count; i++) { stmt.setObject(i, obj[i - 1]); } stmt.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } finally { JDBCUtil.colseResource(conn, stmt, rs); } } /*修改*/ public static void update(String sql ,Object[] obj){ Connection conn = null; PreparedStatement stmt = null; ResultSet rs = null; try { conn = JDBCUtil.getConnection(); stmt = conn.prepareStatement(sql); // 设置参数 ParameterMetaData parameterMetaData = stmt.getParameterMetaData(); int count = parameterMetaData.getParameterCount(); for (int i = 1; i <= count; i++) { stmt.setObject(i, obj[i - 1]); } stmt.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } finally { JDBCUtil.colseResource(conn, stmt, rs); } } /*删除*/ public static void delete(String sql ,Object[] obj){ Connection conn = null; PreparedStatement stmt = null; ResultSet rs = null; try { conn = JDBCUtil.getConnection(); stmt = conn.prepareStatement(sql); // 设置参数 ParameterMetaData parameterMetaData = stmt.getParameterMetaData(); int count = parameterMetaData.getParameterCount(); for (int i = 1; i <= count; i++) { stmt.setObject(i, obj[i - 1]); } stmt.execute(); } catch (SQLException e) { e.printStackTrace(); } finally { JDBCUtil.colseResource(conn, stmt, rs); } } } /*创建 封装查询结果为实体类的接口*/ interface BeanHanderInterface<T> { public List<T> hander(ResultSet rs);//将结果集传过来 封装成T实体类 } /*接口实现类*/ class BeanHanderImpl<T> implements BeanHanderInterface<T>{ private Class<T> domainClass; public BeanHanderImpl(Class<T> domainClass) { super(); this.domainClass = domainClass; } @Override public List<T> hander(ResultSet rs) { List<T> list=new ArrayList<>(); try { /*1 ResultSetMetaData 结果集元数据 ---- 获得结果集列名称、数量、类型*/ ResultSetMetaData resultSetMetaData=rs.getMetaData(); /*2 获得总列数*/ int count =resultSetMetaData.getColumnCount(); /*3 内省技术获得类 要求要传入相应的 类.class */ BeanInfo beanInfo = Introspector.getBeanInfo(domainClass); /*4 获得所有属性*/ PropertyDescriptor[] propertyDescriptors=beanInfo.getPropertyDescriptors(); /*5 遍历结果集*/ while(rs.next()){ /*<1> 获取泛型实例对象*/ T t=domainClass.newInstance(); /*<2>遍历每一个数据库中的字段 看是否与属性名字匹配 如果匹配就将 数据库中的取得的字段值放入属性中*/ for(int i=1;i<=count;i++){ //获得列名 String columnName=resultSetMetaData.getColumnName(i); for(PropertyDescriptor pd:propertyDescriptors){ /*属性名字和数据库中的名字匹配的时候为属性赋值*/ if(columnName.equals(pd.getName())){ /*username public void com.goke.User.setUsername(java.lang.String)pd.getWriteMethod() userpwd public void com.goke.User.setUserpwd(java.lang.String)pd.getWriteMethod() userdesc public void com.goke.User.setUserdesc(java.lang.String)pd.getWriteMethod() id 没有set 方法则显示 */ //获得对应的set 方法 Method setMethod=pd.getWriteMethod(); setMethod.invoke(t, new Object[]{rs.getObject(columnName)}); } } } list.add(t); } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IntrospectionException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InvocationTargetException e) { // TODO Auto-generated catch block e.printStackTrace(); } return list; } }
本列中简单实现了增加,删除,修改,和查询方法, 在查询中将结果封装成类时是考虑数据库字段和属性名相同的情况,没有对数据库字段和属性名不同的情况做处理, 如 数据库字段为user_name 属性字段为username