1 package com.atsyc.api.utils;
2
3 /*
4 * 封装dao数据库重复代码
5 * TODO:
6 * 封装两个方法 一个简化非DQL,一个简化DQL
7 */
8
9 import java.lang.reflect.Field;
10 import java.sql.*;
11 import java.util.ArrayList;
12 import java.util.HashMap;
13 import java.util.List;
14 import java.util.Map;
15
16 public abstract class BaseDao {
17
18 /*
19 * 封装简化非DQL语句
20 * sql 带占位符的SQL语句
21 * params 占位符的值
22 * return返回执行影响的行数(为int类型)
23 */
24 public int executeUpdate(String sql,Object... params) throws SQLException {
25
26 //获取连接
27 Connection connection = JdbcUtilsV2.getConnection();
28
29 PreparedStatement preparableStatement = connection.prepareStatement(sql);
30 //占位符赋值,可变参数可以当作数组使用
31 for(int i = 1 ; i <= params.length ; i++){
32 preparableStatement.setObject(i,params[i-1]);
33 }
34 //发送SQL语句
35 //DML类型
36 int rows = preparableStatement.executeUpdate();
37
38 preparableStatement.close();
39 //是否回收连接,需要考虑是不是事务,开启事务了就不用管,在业务层处理
40 if(connection.getAutoCommit()){
41 //没有开启事务,正常回收连接
42 JdbcUtilsV2.freeConnection();
43 }
44
45 return rows;
46 }
47
48 /*
49 * DQL语句封装方法返回值:
50 * 数据库数据 -> java的实体类
51 * 表中一行 -> java类的一个对象 表中多行 -> List<Java实体类> list
52 *
53 * clazz 要接值的实体类集合的模板对象
54 * sql List<T> list 查询语句,要求列名或者别名等于实体类的属性名
55 * params 占位符的值 要和?位置对象传递
56 * <T> 声明的结果的泛型
57 * return返回某一个类的实体类集合
58 *
59 */
60
61 // <T>声明一个泛型,不确定类型
62 // 1.确定泛型User.class T = User
63 // 2.要使用反射技术属性赋值
64 public <T> List<T> executeQuery(Class<T> clazz,String sql,Object... params) throws SQLException, InstantiationException, IllegalAccessException, NoSuchFieldException {
65 Connection connection = JdbcUtilsV2.getConnection();
66
67 PreparedStatement preparedStatement = connection.prepareStatement(sql);
68
69 if(params == null && params.length != 0){
70 for(int i = 1 ; i <= params.length ; i++){
71 preparedStatement.setObject(i,params[i-1]);
72 }
73 }
74
75 ResultSet resultSet = preparedStatement.executeQuery();
76
77 //结果集解析
78 List<T> list = new ArrayList<>();
79
80 ResultSetMetaData metaData = resultSet.getMetaData();
81
82 //写了下面这句可以获取列数,水平遍历列
83 int columnCount = metaData.getColumnCount();
84
85 while (resultSet.next()){
86 T t = clazz.newInstance(); //调用类的无参构造函数实例化对象
87
88 //TODO:自动遍历列要从 1 开始,并且小于等于总列数
89 for(int i = 1 ; i <= columnCount ; i++){
90 //获取指定列下角标的值 获取值相关用resultSet对象
91 Object value = resultSet.getObject(i);
92
93 //获取指定列下角标的名称 获取名相关用metaData对象
94 String propertyName = metaData.getColumnLabel(i);
95
96 //反射,给对象的属性值赋值
97 Field field = clazz.getDeclaredField(propertyName); //getDeclaredField() 仅能获取类本身的属性成员(包括私有、共有、保护)
98 field.setAccessible(true); //属性可以设置,打破private私有属性的修饰限制
99
100 //参数1:要赋值的对象(如果属性是静态,第一个参数可以为null)
101 //参数2:具体的属性值
102 field.set(t,value);
103 }
104 //把对象加到集合中
105 list.add(t);
106 }
107 resultSet.close();
108 preparedStatement.close();
109
110 if(connection.getAutoCommit()){
111 //没有事务,可以关闭
112 JdbcUtilsV2.freeConnection();
113 }
114
115 return list;
116
117 }
118 }