package com.situ.chapter1;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetmetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public final class JdbcUtils {
// mysql8驱动
public static final String MYSQL8_DRIVER = "com.mysql.cj.jdbc.Driver";
public static final Connection getConnection(String driver, String url, String user, String password) {
try {
Class.forName(driver);
return DriverManager.getConnection(url, user, password);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
throw new RuntimeException("无法创建数据库连接");
}
public static final Connection getConnection(String url, String user, String password) {
return getConnection(MYSQL8_DRIVER, url, user, password);
}
public static final ResultSet query(Connection conn, String sql, Object[] args) {
try {
PreparedStatement ps = conn.prepareStatement(sql);
if (args != null) {
// 给PreparedStatement实例设置参数
for (int i = 0; i < args.length; i++) {
ps.setObject(i + 1, args[i]);
}
}
return ps.executeQuery();
} catch (SQLException e) {
e.printStackTrace();
}
throw new RuntimeException("查询出现异常");
}
public static final int update(Connection conn, String sql, Object[] args) {
try {
PreparedStatement ps = conn.prepareStatement(sql);
if (args != null) {
// 给PreparedStatement实例设置参数
for (int i = 0; i < args.length; i++) {
ps.setObject(i + 1, args[i]);
}
}
return ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
return -1;
}
public static final T query(Connection conn, ResultSetHandler handler, String sql, Object[] args) {
ResultSet rs = query(conn, sql, args);
return handler.handle(rs);
}
public static interface ResultSetHandler {
T handle(ResultSet rs);
}
public static class BeanListHandler implements ResultSetHandler> {
private final Class clazz;
public BeanListHandler(Class clazz) {
this.clazz = clazz;
}
@Override
public List handle(ResultSet rs) {
// 返回值
List list = new ArrayList<>();
// 存储所有列名(别名)
List columnNames = new ArrayList<>();
// 存储所有方法,键名是列名(别名),值即其对应的setter方法
Map methodMap = new HashMap<>();
// 获取所有列名
try {
// 结果集元数据
ResultSetmetaData rsmd = rs.getmetaData();
// 返回查询结果集的列数
int count = rsmd.getColumnCount();
// 返回此类型的所有方法
Method[] methods = clazz.getDeclaredMethods();
for (int i = 0; i < count; i++) {
// 获取列名,如果起别名,则获取别名
String columnName = rsmd.getColumnLabel(i + 1);
columnNames.add(columnName);// 返回查询结果集的列名
// 组装出对象的方法名
String methodName = columnName.substring(0, 1).toUpperCase() + columnName.substring(1);
methodName = "set" + methodName;
for (Method me : methods) {
if (me.getName().equals(methodName)) {
methodMap.put(columnName, me);// 设置到map中
break;
}
}
}
// 准备工作已完成,将结果集中的数据转换成T类型的实例
if (rs != null) {
// 获取无参的构造方法
Constructor con = clazz.getDeclaredConstructor();
while (rs.next()) {
T t = con.newInstance();// T类型的实例
for (int i = 0; i < count; i++) {
String columnName = columnNames.get(i);
// 从结果集中取出对应列的数据
Object value = rs.getObject(columnName);
// 取出方法
Method method = methodMap.get(columnName);
if (method != null) {
// 通过反射给T类型的实例赋值
method.invoke(t, value);
}
}
list.add(t);
}
}
return list;
} catch (SQLException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return null;
}
}
public static final void closeConnection(Connection conn) {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
存在一个小问题,如果类的birthday是localdate,而数据库中是date类型,则报错



