自定义一个简单的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