Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.gitee.qdbp.jdbc.plugins.DbPluginHelper Maven / Gradle / Ivy
package com.gitee.qdbp.jdbc.plugins;
import java.lang.reflect.Array;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.sql.DataSource;
import com.gitee.qdbp.able.convert.BeanToMapConverter;
import com.gitee.qdbp.able.convert.MapToBeanConverter;
import com.gitee.qdbp.able.convert.ObjectTypeConverter;
import com.gitee.qdbp.able.jdbc.base.OrderByCondition;
import com.gitee.qdbp.able.jdbc.base.UpdateCondition;
import com.gitee.qdbp.able.jdbc.base.WhereCondition;
import com.gitee.qdbp.able.jdbc.condition.TableJoin;
import com.gitee.qdbp.jdbc.model.AllFieldColumn;
import com.gitee.qdbp.jdbc.model.DbType;
import com.gitee.qdbp.jdbc.model.DbVersion;
import com.gitee.qdbp.jdbc.model.MainDbType;
import com.gitee.qdbp.jdbc.model.OmitStrategy;
import com.gitee.qdbp.jdbc.model.SimpleFieldColumn;
import com.gitee.qdbp.jdbc.model.TablesFieldColumn;
import com.gitee.qdbp.jdbc.model.TypedDbVariable;
import com.gitee.qdbp.jdbc.operator.DbBaseOperator;
import com.gitee.qdbp.jdbc.result.RowToBeanMapper;
import com.gitee.qdbp.jdbc.result.RowToBeanMapper.FactoryOfTable;
import com.gitee.qdbp.jdbc.result.RowToBeanMapper.FactoryOfTables;
import com.gitee.qdbp.jdbc.result.RowToMapMapper;
import com.gitee.qdbp.jdbc.utils.DbTypes;
import com.gitee.qdbp.jdbc.utils.ParseTools;
import com.gitee.qdbp.staticize.tags.base.Taglib;
import com.gitee.qdbp.tools.property.PropertyContainer;
import com.gitee.qdbp.tools.utils.ConvertTools;
import com.gitee.qdbp.tools.utils.VerifyTools;
import org.springframework.jdbc.core.SqlParameterValue;
/**
* 插件帮助类
*
* @author zhaohuihua
* @version 20210626
*/
public class DbPluginHelper {
public interface Aware {
void setPlugins(DbPluginHelper plugins);
}
private final DbPluginContainer plugins;
private final ParseTools parseTools;
DbPluginHelper(DbPluginContainer plugins) {
this.plugins = plugins;
this.parseTools = new ParseTools(this);
}
/** 解析工具类 **/
public ParseTools parseTools() {
return parseTools;
}
/** 获取配置项 **/
public PropertyContainer getSqlConfig() {
return this.plugins.getSqlConfig();
}
/** 通过配置项检查是否支持某选项 **/
public boolean configSupports(String configKey, DbVersion version) {
return configSupports(configKey, null, version);
}
/** 通过配置项检查是否支持某选项 **/
public boolean configSupports(String configKey, String defaultValue, DbVersion version) {
String value = plugins.getSqlConfig().getStringUseDefValue(configKey, defaultValue);
return version.matchesWith(value);
}
protected int getRealJdbcType(int jdbcType, DbVersion dbVersion) {
// 如果支持CLOB/NCLOB字段, 将需要调用PreparedStatement.setClob方法
// postgresql不支持CLOB, org.postgresql.jdbc.PgPreparedStatement.setClob, 报NOT_IMPLEMENTED错误
if (jdbcType == Types.CLOB || jdbcType == Types.NCLOB) {
if (!this.configSupports("supports.clob", dbVersion)) {
return Types.VARCHAR;
}
}
return jdbcType;
}
/**
* 将变量转换为数据库字段值
* 基本对象不做转换, 直接返回, 其他对象转换为基本对象后返回
* 基本对象是指Boolean/Character/Date/Number/String
*
* @param variable 变量
* @param dialect 数据库方言
* @return 转换后的字段值对象
*/
public Object variableToDbValue(Object variable, SqlDialect dialect) {
if (variable instanceof Collection) {
Collection> list = (Collection>) variable;
List result = new ArrayList<>();
for (Object item : list) {
result.add(variableToDbValue(item, dialect));
}
return result;
} else if (variable != null && variable.getClass().isArray()) {
Object[] array = (Object[]) variable;
Object[] result = (Object[]) Array.newInstance(variable.getClass().getComponentType(), array.length);
for (int i = 0; i < array.length; i++) {
result[i] = variableToDbValue(array[i], dialect);
}
return result;
} else {
if (variable instanceof SqlParameterValue) {
return variable;
}
VariableToDbValueConverter converter = plugins.getToDbValueConverter();
Object result = converter.convert(variable);
if (result instanceof TypedDbVariable) { // 转换结果指定了类型
TypedDbVariable temp = (TypedDbVariable) result;
int jdbcType = getRealJdbcType(temp.getJdbcType(), dialect.dbVersion());
return new SqlParameterValue(jdbcType, temp.getValue());
} else if (variable instanceof TypedDbVariable) { // 入参指定了类型
TypedDbVariable typed = (TypedDbVariable) variable;
int jdbcType = getRealJdbcType(typed.getJdbcType(), dialect.dbVersion());
return new SqlParameterValue(jdbcType, result);
} else if (result instanceof Character) { // Character类型不能自动识别
// @see org.springframework.jdbc.core.StatementCreatorUtils.setValue
// 调用的是PreparedStatement.setObject(int index, Object x)
// 而不是PreparedStatement.setObject(int index, Object x, int Types.xxx)
return new SqlParameterValue(Types.VARCHAR, variable);
} else {
return result;
}
}
}
/**
* 将变量转换为字符串, 用于拼接SQL
* 如字符串会返回单引号括起来的'stringValue', Boolean会返回1或0
* 日期: MYSQL: '2019-06-01 12:34:56.789'
* ORACLE: TO_TIMESTAMP('2019-06-01 12:34:56.789', 'YYYY-MM-DD HH24:MI:SS.FF')
*
* @param variable 变量
* @param dialect 数据库方言
* @return 转换后的字符串
*/
public String variableToString(Object variable, SqlDialect dialect) {
if (variable instanceof Collection) {
Collection> list = (Collection>) variable;
List result = new ArrayList<>();
for (Object item : list) {
result.add(variableToString(item, dialect));
}
return ConvertTools.joinToString(result, ',', false);
} else if (variable != null && variable.getClass().isArray()) {
Object[] array = (Object[]) variable;
String[] result = new String[array.length];
for (int i = 0; i < array.length; i++) {
result[i] = variableToString(array[i], dialect);
}
return ConvertTools.joinToString(result, ',', false);
} else {
VariableToDbValueConverter converter = plugins.getToDbValueConverter();
Object result = converter.convert(variable);
if (result instanceof TypedDbVariable) {
TypedDbVariable temp = (TypedDbVariable) result;
result = temp.getValue();
} else if (result instanceof SqlParameterValue) {
SqlParameterValue temp = (SqlParameterValue) result;
result = temp.getValue();
}
if (result == null) {
return "NULL";
} else if (result instanceof Number) {
return result.toString();
} else if (result instanceof CharSequence) {
return dialect.variableToString(result.toString());
} else if (result instanceof Boolean) {
return dialect.variableToString((Boolean) result);
} else if (result instanceof Date) {
return dialect.variableToString((Date) result);
} else if (result instanceof Character) {
return dialect.variableToString(result.toString());
} else {
return dialect.variableToString(result.toString());
}
}
}
/**
* 将代码中写的数据类型转换为java.sql.Types中的数据类型
*
* @param dataType 代码中的数据类型
* 1.来自SQL模板中, 如#{createTime,jdbcType=TIMESTAMP}
* 2.来自实体类上的注解, 如@Column(columnDefinition="TIMESTAMP NOT NULL")
* @return java.sql.Types中的数据类型
* @see java.sql.Types
* @see JdbcDataTypeResolver
*/
public Integer parseJdbcDataType(String dataType) {
JdbcDataTypeResolver resolver = plugins.getJdbcDataTypeResolver();
return resolver.parseDataType(dataType);
}
/**
* 获取Jdbc数据类型转换类
*
* @return JdbcDataTypeResolver
*/
public JdbcDataTypeResolver getJdbcDataTypeResolver() {
return plugins.getJdbcDataTypeResolver();
}
/**
* 可用的数据库类型
* 除MainDbType以外, 可通过plugins.addDbType()注册其他数据库类型
*
* @return 数据库类型列表
*/
public List getAvailableDbTypes() {
return plugins.getAvailableDbTypes();
}
/**
* 判断数据库类型是否有效
*
* @param dbType 数据库类型字符串
* @return 是否有效
*/
public boolean isAvailableDbType(String dbType) {
if (dbType == null || dbType.length() == 0) {
return false;
}
List dbTypes = getAvailableDbTypes();
for (DbType item : dbTypes) {
if (DbTypes.equals(item, MainDbType.Unknown)) {
continue;
}
if (item.name().equalsIgnoreCase(dbType)) {
return true;
}
}
return false;
}
/**
* 解析数据库类型
*
* @param dbType 数据库类型字符串
* @return 数据库类型对象
*/
public DbType parseDbType(String dbType) {
if (dbType == null || dbType.length() == 0) {
return null;
}
List dbTypes = getAvailableDbTypes();
for (DbType item : dbTypes) {
if (DbTypes.equals(item, MainDbType.Unknown)) {
continue;
}
if (item.name().equalsIgnoreCase(dbType)) {
return item;
}
}
return MainDbType.Unknown;
}
/**
* 新建一个SQL标签库
* 默认的标签库为classpath:settings/qdbc/qdbc.taglib.txt
* 可通过plugins.setSqlTaglibPath()修改
*
* @return SQL标签库
*/
public Taglib newSqlTaglib() {
return plugins.getSqlTaglibCreator().create();
}
/**
* 转换原始关键字, 如sysdate/CURRENT_TIMESTAMP之前的互转
*
* @param rawValue 原生值, 如sysdate
* @param dialect 数据库方言
* @return 转换后的值, 如mysql的CURRENT_TIMESTAMP, SqlServer的GETDATE()
* @see RawValueConverter
*/
public String resolveRawValue(String rawValue, SqlDialect dialect) {
RawValueConverter converter = plugins.getRawValueConverter();
return converter.convert(rawValue, dialect);
}
/** 获取对象类型转换处理类 **/
public ObjectTypeConverter getObjectTypeConverter() {
return plugins.getObjectTypeConverter();
}
/** 获取Row到Map的转换处理类 **/
public RowToMapMapper getRowToMapConverter() {
return plugins.getRowToMapConverter();
}
/** 获取Row到Bean的转换处理类 (单表) **/
public RowToBeanMapper getRowToBeanMapper(Class clazz) {
FactoryOfTable factory = plugins.getTableRowToBeanFactory();
return factory.getRowToBeanMapper(clazz);
}
/** 获取Row到Bean的转换处理类 (多表关联) **/
public RowToBeanMapper getRowToBeanMapper(TableJoin tables, Class clazz) {
FactoryOfTables factory = plugins.getTablesRowToBeanFactory();
return factory.getRowToBeanMapper(tables, clazz);
}
/** 获取Map到JavaBean的转换处理类 **/
public MapToBeanConverter getMapToBeanConverter() {
return plugins.getMapToBeanConverter();
}
/** JavaBean到Map的转换处理类 **/
public BeanToMapConverter getBeanToMapConverter() {
return plugins.getBeanToMapConverter();
}
/** 获取JavaBean到数据库条件的转换处理类 **/
public DbConditionConverter getDbConditionConverter() {
return plugins.getDbConditionConverter();
}
/** 实体类逻辑删除数据状态填充策略 **/
public EntityFieldFillStrategy getEntityFieldFillStrategy() {
return plugins.getEntityFieldFillStrategy();
}
/** 实体类逻辑删除数据状态填充策略 **/
public EntityDataStateFillStrategy> getEntityDataStateFillStrategy() {
return plugins.getEntityDataStateFillStrategy();
}
/** 根据DbType生成SqlDialect **/
public SqlDialect buildSqlDialect(DbType dbType) {
return buildSqlDialect(new DbVersion(dbType));
}
/** 根据DbVersion生成SqlDialect **/
public SqlDialect buildSqlDialect(DbVersion version) {
SqlDialect.Creator creator = plugins.getSqlDialectCreator();
return creator.create(version);
}
/** 获取自定义WhereSqlBuilder **/
public > B getWhereSqlBuilder(Class type) {
return plugins.getWhereSqlBuilder(type);
}
/** 获取自定义WhereSqlBuilder **/
public > B getWhereSqlBuilder(T condition) {
@SuppressWarnings("unchecked")
Class type = (Class) condition.getClass();
return plugins.getWhereSqlBuilder(type);
}
/** 获取自定义UpdateSqlBuilder **/
public > B getUpdateSqlBuilder(Class type) {
return plugins.getUpdateSqlBuilder(type);
}
/** 获取自定义UpdateSqlBuilder **/
public > B getUpdateSqlBuilder(T condition) {
@SuppressWarnings("unchecked")
Class type = (Class) condition.getClass();
return plugins.getUpdateSqlBuilder(type);
}
/** 获取自定义UpdateSqlBuilder **/
public > B getOrderBySqlBuilder(Class type) {
return plugins.getOrderBySqlBuilder(type);
}
/** 获取自定义UpdateSqlBuilder **/
public > B getOrderBySqlBuilder(T condition) {
@SuppressWarnings("unchecked")
Class type = (Class) condition.getClass();
return plugins.getOrderBySqlBuilder(type);
}
/**
* 根据运算符获取WhereOperator处理类
*
* @param operatorType 运算符
* @return WhereOperator处理类
*/
public DbBaseOperator getWhereOperator(String operatorType) {
DbOperatorContainer container = plugins.getOperatorContainer();
return container == null ? null : container.getWhereOperator(operatorType);
}
/**
* 根据运算符获取UpdateOperator处理类
*
* @param operatorType 运算符
* @return UpdateOperator处理类
*/
public DbBaseOperator getUpdateOperator(String operatorType) {
DbOperatorContainer container = plugins.getOperatorContainer();
return container == null ? null : container.getUpdateOperator(operatorType);
}
/**
* 格式化SQL语句
*
* @param sql 待格式化的SQL语句
* @param indent 缩进层数
* @param version 数据库版本
* @return 已格式化的SQL语句
*/
public String formatSql(String sql, int indent, DbVersion version) {
SqlFormatter formatter = plugins.getSqlFormatter();
return formatter.format(sql, indent, version);
}
/**
* 替换SQL语句
*
* @param sql 源SQL语句
* @param version 数据库版本
* @return 替换后的SQL语句
*/
public String replaceSql(String sql, DbVersion version) {
SqlReplacer replacer = plugins.getSqlReplacer();
return replacer.replace(sql, version);
}
/**
* 查找数据库版本信息
*
* @param datasource 数据源
* @return 数据库版本信息
*/
public DbVersion findDbVersion(DataSource datasource) {
DbVersionFinder finder = plugins.getDbVersionFinder();
return finder.findDbVersion(datasource);
}
/** 获取SQL模板扫描处理类 **/
public SqlFileScanner getSqlFileScanner() {
return plugins.getSqlFileScanner();
}
/** 获取SQL片断的选项配置类 **/
public SqlFragmentOptions getSqlFragmentOptions() {
return plugins.getSqlFragmentOptions();
}
/** 获取字段值校验处理类 **/
public ColumnValueValidator getColumnValueValidator() {
return plugins.getColumnValueValidator();
}
/** 获取命名转换接口 **/
public JdbcNamingConverter getNamingConverter() {
return plugins.getNamingConverter();
}
/** 获取批量操作的省略策略配置 **/
public OmitStrategy getOmitStrategyOfBatchExecutor() {
return plugins.getOmitStrategyOfBatchSql();
}
/** 获取IN语句的省略策略配置 **/
public OmitStrategy getOmitStrategyOfInSql() {
return plugins.getOmitStrategyOfInSql();
}
/** 多表关联列信息的解析器 **/
public TablesFieldColumnParser getTablesFieldColumnParser() {
return plugins.getTablesFieldColumnParser();
}
/** 根据数据库类型获取批量新增处理类 **/
public BatchInsertExecutor getBatchInsertExecutor(DbVersion version) {
return plugins.getBatchInsertExecutor(version);
}
/** 根据数据库类型获取批量更新处理类 **/
public BatchUpdateExecutor getBatchUpdateExecutor(DbVersion version) {
return plugins.getBatchUpdateExecutor(version);
}
/** Entity的表名缓存 **/
private final Map, String> entityTableNameCache = new HashMap<>();
/**
* 扫描表名信息(有缓存)
*
* @param clazz 类名
* @return 表名
*/
public String parseTableName(Class> clazz) {
VerifyTools.requireNonNull(clazz, "class");
if (entityTableNameCache.containsKey(clazz)) {
return entityTableNameCache.get(clazz);
}
TableInfoScans scans = plugins.getTableInfoScans();
String tableName = scans.scanTableName(clazz);
entityTableNameCache.put(clazz, tableName);
return tableName;
}
/** Entity的主键缓存 **/
private final Map, SimpleFieldColumn> entityPrimaryKeyCache = new HashMap<>();
/**
* 扫描获取主键(有缓存)
*
* @param clazz 类名
* @return 主键
*/
public SimpleFieldColumn parsePrimaryKey(Class> clazz) {
VerifyTools.requireNonNull(clazz, "class");
if (entityPrimaryKeyCache.containsKey(clazz)) {
return entityPrimaryKeyCache.get(clazz);
}
AllFieldColumn all = parseAllFieldColumns(clazz);
SimpleFieldColumn pk = all.findPrimaryKey();
entityPrimaryKeyCache.put(clazz, pk);
return pk;
}
/** TableJoin的列名缓存 **/
private final Map> joinColumnsCache = new HashMap<>();
/**
* 扫描获取字段名和数据库列名的映射表(有缓存)
*
* @param tables 表关联对象
* @return AllFieldColumn: fieldName - columnName
*/
public AllFieldColumn parseAllFieldColumns(TableJoin tables) {
VerifyTools.requireNonNull(tables, "tables");
String cacheKey = tables.getTableFeatures(true);
if (joinColumnsCache.containsKey(cacheKey)) {
return joinColumnsCache.get(cacheKey);
}
TablesFieldColumnParser parser = plugins.getTablesFieldColumnParser();
List all = parser.parseFieldColumns(tables);
AllFieldColumn fieldColumns = new AllFieldColumn<>(all);
joinColumnsCache.put(cacheKey, fieldColumns);
return fieldColumns;
}
/** Entity的列名缓存 **/
private final Map, AllFieldColumn> entityColumnsCache = new HashMap<>();
/**
* 扫描获取字段名和数据库列名的映射表(有缓存)
*
* @param clazz 类型
* @return AllFieldColumn: fieldName - columnName
*/
public AllFieldColumn parseAllFieldColumns(Class> clazz) {
VerifyTools.requireNonNull(clazz, "class");
if (entityColumnsCache.containsKey(clazz)) {
return entityColumnsCache.get(clazz);
} else {
TableInfoScans scans = plugins.getTableInfoScans();
List fields = scans.scanColumnList(clazz);
if (fields.isEmpty()) {
String m = "Fields not found, please check config of TableInfoScans, class=" + clazz.getName();
throw new IllegalArgumentException(m);
}
AllFieldColumn all = new AllFieldColumn<>(fields);
entityColumnsCache.put(clazz, all);
return all;
}
}
}