JDBC总结:
手动获取数据库连接的多种方式、使用数据库连接池获取连接、Statement与PreparedStatement的对比使用、sql注入问题讲解、Blob字段的操作、高效的批量插入、DAO设计模式、使用dbutils提供的相关工具类等。
此外还对数据库事务进行详解,利用反射及JDBC元数据编写通用的查询方法等。
/**
* 使用反射动态的实现对不同表的通用多个查询
* @author bh
* @create 2022-03-04 17:43
*/
public class CommonMultiQuery {
@Test
public void test() {
String sql = "select id stuId, name stuName from student where id > ?;";
List<Student> multiQueryInstance = getMultiQueryInstance(Student.class, sql, 1002);
System.out.println(multiQueryInstance);
String sql1 = "select teamID, teamName, location, arena from teams where teamID > ?;";
List<Teams> multiQueryInstance1 = getMultiQueryInstance(Teams.class, sql1, 1);
multiQueryInstance1.forEach(System.out::println);
}
public <T> List<T> getMultiQueryInstance(Class<T> clazz, String sql, Object...args) {
Connection connection = null;
PreparedStatement ps = null;
ResultSet resultSet = null;
try {
connection = JDBCUtils.getConnection();
ps = connection.prepareStatement(sql);
for(int i = 0; i < args.length; i++) {
//对sql语句设置占位符
ps.setObject(i + 1, args[i]);
}
//获取结果集
resultSet = ps.executeQuery();
//获取结果集的元数据(数据的描述)
ResultSetMetaData rsmd = resultSet.getMetaData();
//获取结果集列数
int columnCount = rsmd.getColumnCount();
ArrayList<T> list = new ArrayList<>();
while(resultSet.next()) {
T t = clazz.newInstance();//使用反射动态获取类(表)的对象
for(int i = 0; i < columnCount; i++) {
//获取每个列的值
Object objectValue = resultSet.getObject(i + 1);
//获取结果集每个列的别名 ---> 对应Java类属性名
//String columnLabel = rsmd.getColumnName(i + 1); //不靠谱,不推荐使用!!!
String columnLabel = rsmd.getColumnLabel(i + 1); //推荐使用!!!
//利用反射获取列名columnName对应的属性
Field field = clazz.getDeclaredField(columnLabel);
field.setAccessible(true);
//将t对象对应的属性赋值为objectValue
field.set(t, objectValue);
}
list.add(t);
}
return list;
} catch (Exception e) {
e.printStackTrace();
}finally {
JDBCUtils.closeResource(connection, ps, resultSet);
}
return null;
}
}
查询结果: