数据库CRUD封装
数据库CRUD封装
在一个项目中,我们会进行后台数据库的连接。所以会频繁的使用数据库的CRUD操作,所以我们能不能抽取公共部分,并形成一个工具类呢?我们来试试。
- CRUD方法封装
public class CRUDUtils {
/**
* @Description: 增删改的sql封装
* @Param: [sql:具体的sql语句; params:字段信息(使用prepareStatement)]
* @return: int
*/
public static int update(String sql,Object... params){
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
//1.获取连接,DbUtil工具类的获取见末尾文章。
con = DbUtil.getConn();
//2.预处理sql语句
ps = con.prepareStatement(sql);
//3.params.length 获取可变长度的长度,进行?填充
for (int i = 0; i < params.length; i++) {
ps.setObject(i + 1,params[i]);
}
/*4.返回执行结果(int),数字是受影响的行数,如果为0表示一行数据都没有影响到,不代表数据库执行错*/
return ps.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
//这个就是执行失败返回0
return 0;
}finally {
try {
//5.数据源关闭
DbUtil.release(con,ps,rs);
} catch (Exception e) {
e.printStackTrace();
}
}
return 0;
}
/**
* @Description:封装查询语句
* @Param: [sql:查询的sql语句, handler:接口,可以指定传入的对象类型, params:字段信息(使用 * prepareStatement)]
* @return: T
*/
public static <T> T query(String sql, IResultSetHandler<T> handler, Object... params) {
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
//1.获取连接
con = DbUtil.getConn();
//2.执行查询
ps = con.prepareStatement(sql);
for (int i = 0; i < params.length; i++) {
ps.setObject(i + 1,params[i]);
}
rs = ps.executeQuery();
return handler.handle(rs);
} catch (Exception e) {
e.printStackTrace();
} finally {
DbUtil.release(con,ps,rs);
}
return null;
}
}
- handler接口
public interface IResultSetHandler <T>{
/**
* @Description: 接口中抽象方法,实现对结果集的处理,返回所指定的类型
* @Param: [rs]
* @return: T
*/
T handle(ResultSet rs) throws Exception;
}
- 接口实现类一,bean
/**
* @description: IResultSetHandler的实现类之一, 返回一个javaBean
**/
public class BeanHandler<T> implements IResultSetHandler<T> {
private Class<T> clazz;
/**获取传进来的类对象的字节码信息*/
public BeanHandler(Class<T> clazz) {
this.clazz = clazz;
}
@Override
public T handle(ResultSet rs) throws Exception {
//如果查到了东西
if (rs.next()) {
//首先先根据字节码信息创建对象,等会返回
T obj = clazz.newInstance();
//再拿到类的信息
BeanInfo beanInfo = Introspector.getBeanInfo(clazz, Object.class);
//拿到类中的属性描述器
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
//遍历描述器,进行获取查询结果的对象信息进行封装
for (PropertyDescriptor pd : pds) {
//获取查询结果集的对应字段的信息
String name = pd.getName();
Object object = rs.getObject(pd.getName());
//通过调用setter写进信息
pd.getWriteMethod().invoke(obj,object);
}
return obj;
}
//查不到直接返回null
return null;
}
}
- 接口实现类二,beanList
/**
* @program: Dream01
* @description: IResultSetHandler的实现类之一, 返回一个javaBean集合
* @author: stop.yc
* @create: 2022-03-29 22:28
**/
public class BeanListHandle<T> implements IResultSetHandler<List<T>> {
private Class<T> clazz;
//获取当前对象的字节码信息
public BeanListHandle(Class<T> clazz) {
this.clazz = clazz;
}
@Override
public List<T> handle(ResultSet rs) throws Exception {
//通过字节码信息获取类的信息
BeanInfo beanInfo = Introspector.getBeanInfo(clazz, Object.class);
//再通过类获取属性描述器,比如getter,setter这些
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
//类的列表
List<T>list = new ArrayList<>();
//进行遍历
while(rs.next()) {
//通过对象信息创建对象
T obj = clazz.newInstance();
for (PropertyDescriptor pd : pds) {
//获取对应字段的信息
Object object = rs.getObject(pd.getName());
//获取setter
pd.getWriteMethod().invoke(obj,object);
}
list.add(obj);
}
return list;
}
}
- 主函数测试
public class Main {
public static void main(String[] args) {
String qSql = "select * from `t_user` where `userName`=?";
String userName = "张三";
//User为自定义的类.
User user = CRUDUtils.query(qSql,new BeanHandler<>(User.class),userName);
String sql = "select * from `t_user` where `gender`=0";
//List<User> list = CRUDUtils.query(sql,new BeanListHandle<>(User.class));
//update语句都行,这里只展示一种
String updateSql = "isnert into `t_user` (`userName`,`gender`) values ('李四','男')";
int ret = CRUDUtils.update(updateSql);
}
}
文章里的数据库工具类 详见 数据库工具类