package com.csy.dao;
import com.csy.config.ConfigMng;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.sql.*;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @Description: 管理数据库的连接与释放
* @Author: windStop
* @Date: 2024/5/20 16:38
*/
public class BaseDao {
public Connection connection = null;
public PreparedStatement pStatement = null;
public ResultSet resultSet = null;
//使用配置文件的方式进行解耦合,可以在无需重新编译的基础上进行修改内容
public boolean getConnection() {
try {
ConfigMng configMng = ConfigMng.getInstance();
Class.forName(configMng.getString("jdbc.driver"));
String url = configMng.getString("jdbc.url");
connection = DriverManager.getConnection(url, configMng.getString("jdbc.username"), configMng.getString("jdbc.password"));
}
catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
public boolean closeResource() {
try {
if (resultSet != null)
resultSet.close();
if (pStatement != null)
pStatement.close();
if (connection != null)
connection.close();
} catch (SQLException e) {
e.printStackTrace();//把异常信息打印在控制台中
return false;
}
return true;
}
/**
* 封装增删改操作
* @param sql sql语句
* @param params 参数占位符 ?的填充的内容
* @return 影响了多少条数据
*/
public int executeUpdate(String sql, Object[] params) {
if (getConnection()) {
//1.执行sql语句
try {
pStatement = connection.prepareStatement(sql);
//2.填充占位符
for (int i = 0; i < params.length; i++) {
pStatement.setObject(i + 1,params[i]);
}
return pStatement.executeUpdate();
} catch (SQLException e) {
throw new RuntimeException(e);
}finally {
closeResource();
}
}
return 0;
}
/**
* 通过拆解出where条件后面跟的条件,然后遍历javabean的属性找到相应的进行插入。最后将结果ResultSet映射到javabean中返回
* @param sql sql语句
* @param obj 调用者传来的javabean
* @return 查询到的javabean集合
* @param javabean的泛型
*/
public List executeQuery(String sql, T obj) throws IllegalAccessException, SQLException {
List resultList = new ArrayList<>();
if (getConnection()) {
pStatement = connection.prepareStatement(sql);
// 使用反射获取对象的属性值
Class> clazz = obj.getClass();
//获取该对象中的所有属性(包括私有)所有字段
Field[] fields = clazz.getDeclaredFields();
List conditionFields = extractConditionFields(sql);
for (int i = 0; i < conditionFields.size(); i++) {
// 填充占位符内容
for (Field field : fields) {
//私有暴力反射 设置可访问私有字段
field.setAccessible(true);
if (field.getName().equals(conditionFields.get(i))){//找到相等的了
//接受一个对象实例作为参数,返回该对象实例中对应字段的值。
Object value = field.get(obj);
pStatement.setObject(i + 1,value);
break;
}
}
}
resultSet = pStatement.executeQuery();
while (resultSet.next()) {
// 根据泛型类型创建对象并填充数据
T resultObj = (T)createObjectFromResultSet(resultSet, clazz);
resultList.add(resultObj);
}
}
return resultList;
}
//将resultSet的返回值封装到泛型对象中,并且返回(这里我没有处理表名映射下划线和驼峰)
private T createObjectFromResultSet(ResultSet resultSet, Class clazz) throws SQLException {
T obj;
try {
obj = clazz.getDeclaredConstructor().newInstance();
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
String fieldName = field.getName();
Class> fieldType = field.getType();
// 根据字段类型从结果集中获取相应的值
if (fieldType == String.class) {
String value = resultSet.getString(fieldName);
field.set(obj, value);
} else if (fieldType == Integer.class || fieldType == int.class) {
int value = resultSet.getInt(fieldName);
field.set(obj, value);
} else if (fieldType == Date.class) {
Date value = resultSet.getDate(fieldName);
field.set(obj, value);
} else if (fieldType == LocalDateTime.class) {
Timestamp timestamp = resultSet.getTimestamp(fieldName);
LocalDateTime value = timestamp.toLocalDateTime();
field.set(obj, value);
} else {
// 其他类型的处理... 想到在写
}
}
} catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
throw new SQLException("Error creating object from ResultSet", e);
}
return obj;
}
//截取出where条件中的所有字段条件的名称
public List extractConditionFields(String sql) {
List conditionFields = new ArrayList<>();
// 使用正则表达式匹配 WHERE 子句
Pattern wherePattern = Pattern.compile("where(.*)", Pattern.CASE_INSENSITIVE);
Matcher whereMatcher = wherePattern.matcher(sql);
if (whereMatcher.find()) {
String whereClause = whereMatcher.group(1).trim();
// 使用正则表达式匹配条件字段
Pattern conditionPattern = Pattern.compile("(\\w+)\\s?=\\s?");
Matcher conditionMatcher = Pattern.compile("and", Pattern.CASE_INSENSITIVE).matcher(whereClause);
int lastIndex = 0;
while (conditionMatcher.find()) {
String condition = whereClause.substring(lastIndex, conditionMatcher.start()).trim();
Matcher fieldMatcher = conditionPattern.matcher(condition);
if (fieldMatcher.find()) {
conditionFields.add(fieldMatcher.group(1));
}
lastIndex = conditionMatcher.end();
}
// 处理最后一个条件
String lastCondition = whereClause.substring(lastIndex).trim();
Matcher lastFieldMatcher = conditionPattern.matcher(lastCondition);
if (lastFieldMatcher.find()) {
conditionFields.add(lastFieldMatcher.group(1));
}
}
return conditionFields;
}
}