cn.woodwhales.common.util.datasource.DataSourceTool Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of woodwhales-common Show documentation
Show all versions of woodwhales-common Show documentation
https://github.com/woodwhales
package cn.woodwhales.common.util.datasource;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.reflect.FieldUtils;
import javax.persistence.Column;
import javax.persistence.Table;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.sql.*;
import java.time.ZoneId;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import static java.util.Objects.isNull;
import static java.util.Objects.nonNull;
/**
* @author woodwhales on 2021-01-28 21:22
* 数据库查询工具
*/
@Slf4j
public class DataSourceTool {
private String driverClass;
private String url;
private String username;
private String password;
private Connection connection;
private Map, TargetInfo> targetInfoCache = new HashMap<>(16);
private Map, Function extends Annotation, String>> annotationCache = new HashMap<>(16);
public static DataSourceTool newMysql(String url, String username, String password) {
return new DataSourceTool("com.mysql.jdbc.Driver", url, username, password);
}
public static DataSourceTool newMysql8(String url, String username, String password) {
return new DataSourceTool("com.mysql.cj.jdbc.Driver", url, username, password);
}
public static DataSourceTool newOracle(String url, String username, String password) {
return new DataSourceTool("oracle.jdbc.OracleDriver", url, username, password);
}
public DataSourceTool(String driverClass, String url, String username, String password) {
this.driverClass = driverClass;
this.url = url;
this.username = username;
this.password = password;
try {
Class.forName(this.driverClass);
Connection connection = DriverManager.getConnection(this.url, this.username, this.password);
this.connection = connection;
} catch (Exception e) {
Throwable cause = e.getCause();
if(cause instanceof SQLException){
SQLException sqlException = (SQLException) cause;
String sqlState = sqlException.getSQLState();
if("28000".equals(sqlState)) {
System.out.println("数据库账号或密码错误!!!");
}
} else {
e.printStackTrace();
}
System.exit(0);
}
}
public List queryList(String sql,
Class clazz,
Class annotationClass,
Function function) throws Exception {
return queryList(sql, this.getTarget(clazz, annotationClass, function));
}
private TargetInfo cacheTarget(Class clazz,
Class annotationClass,
Function function) {
if(!this.targetInfoCache.containsKey(clazz)) {
this.targetInfoCache.put(clazz, new TargetInfo<>(clazz, annotationClass, function));
}
return this.targetInfoCache.get(clazz);
}
public T queryOne(String sql,
Class clazz,
Class annotationClass,
Function function) throws Exception {
return queryOne(sql, this.getTarget(clazz, annotationClass, function));
}
private Function getTarget(Class clazz,
Class annotationClass,
Function function) {
this.cacheTarget(clazz, annotationClass, function);
return resultSet -> this.fillFieldValue(clazz, resultSet);
}
public List queryList(String sql, Class clazz) throws Exception {
return queryList(sql, clazz, null, null);
}
public T queryOne(String sql, Class clazz) throws Exception {
return queryOne(sql, clazz, null, null);
}
public T fillFieldValue(Class clazz, ResultSet resultSet) {
try {
T target = clazz.newInstance();
TargetInfo targetInfo = this.targetInfoCache.get(clazz);
for (TargetInfo.TargetFieldInfo targetFieldInfo : targetInfo.targetFieldInfoList) {
Object object = getObject(resultSet, targetFieldInfo);
if(nonNull(object)) {
boolean accessible = targetFieldInfo.field.isAccessible();
targetFieldInfo.field.setAccessible(true);
targetFieldInfo.field.set(target, object);
targetFieldInfo.field.setAccessible(accessible);
}
}
return target;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
private Object getObject(ResultSet resultSet, TargetInfo.TargetFieldInfo targetFieldInfo) throws SQLException {
String fieldTypeName = targetFieldInfo.fieldType.getName();
String columnLabel = targetFieldInfo.columnLabel;
if(isNull(columnLabel)) {
return null;
}
Object object;
switch (fieldTypeName) {
case "java.util.Date" :
object = resultSet.getTimestamp(targetFieldInfo.columnLabel);
break;
case "java.lang.Byte" :
object = resultSet.getByte(targetFieldInfo.columnLabel);
break;
case "java.time.LocalDateTime" :
object = Optional.ofNullable(resultSet.getTimestamp(columnLabel))
.map(timestamp -> timestamp.toInstant()
.atZone( ZoneId.systemDefault() )
.toLocalDateTime())
.orElse(null);
break;
default:
object = resultSet.getObject(columnLabel, targetFieldInfo.fieldType);
}
return object;
}
private static class TargetInfo {
Class clazz;
List targetFieldInfoList;
public TargetInfo(Class clazz, Class annotationClass, Function function) {
this.clazz = clazz;
this.targetFieldInfoList = new ArrayList<>();
Field[] declaredFields = FieldUtils.getAllFields(clazz);
for (Field declaredField : declaredFields) {
this.addTargetFieldInfo(declaredField, annotationClass, function);
}
}
public TargetInfo addTargetFieldInfo(Field field, Class clazz, Function function) {
TargetFieldInfo> fieldInfo;
if(isNull(clazz) || isNull(function)) {
fieldInfo = new TargetFieldInfo<>(field, Column.class, Column::name);
} else {
fieldInfo = new TargetFieldInfo<>(field, clazz, function);
}
fieldInfo.fillColumnLabel(field, DataColumn.class, DataColumn::value);
fieldInfo.fillColumnLabel(field, DataTable.class, DataTable::value);
fieldInfo.fillColumnLabel(field, Table.class, Table::name);
fieldInfo.fillColumnLabel(field, Column.class, Column::name);
fieldInfo.fillColumnLabel(field, TableId.class, TableId::value);
fieldInfo.fillColumnLabel(field, TableField.class, TableField::value);
fieldInfo.fillColumnLabel(field, DataColumn.class, DataColumn::value);
fieldInfo.fillColumnLabel(field, DataColumn.class, DataColumn::value);
this.targetFieldInfoList.add(fieldInfo);
return this;
}
private static class TargetFieldInfo {
private Field field;
private Class> fieldType;
private String columnLabel;
public TargetFieldInfo(Field field, Class annotationClass, Function function) {
this.field = field;
this.fieldType = field.getType();
this.fillColumnLabel(field, annotationClass, function);
}
private void fillColumnLabel(Field field,
Class annotationClass,
Function function) {
if(nonNull(this.columnLabel)
|| isNull(field.getAnnotations())
|| field.getAnnotations().length == 0) {
return;
} else {
Annotation[] annotations = field.getAnnotations();
Map extends Class extends Annotation>, Annotation> annotationMap = Arrays.stream(annotations)
.collect(Collectors.toMap(Annotation::annotationType, Function.identity()));
if (annotationMap.containsKey(annotationClass)) {
A annotation = (A) annotationMap.get(annotationClass);
this.columnLabel = function.apply(annotation);
}
}
}
}
}
public List queryList(String sql, Function function) throws Exception {
Statement statement = connection.createStatement();
ResultSet rs = statement.executeQuery(sql);
List dataList = new ArrayList<>();
while (rs.next()) {
T data = function.apply(rs);
dataList.add(data);
}
rs.close();
statement.close();
return dataList;
}
public T queryOne(String sql, Function function) throws Exception {
Statement statement = connection.createStatement();
ResultSet rs = statement.executeQuery(sql);
try {
rs.next();
return function.apply(rs);
} finally {
rs.close();
statement.close();
connection.close();
}
}
public void closeConnection() {
try {
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
private DataSourceTool() {
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy