
com.gitee.qdbp.jdbc.plugins.DbPluginInitTools Maven / Gradle / Ivy
package com.gitee.qdbp.jdbc.plugins;
import java.math.BigDecimal;
import java.sql.Date;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.converter.ConverterRegistry;
import org.springframework.core.convert.support.DefaultConversionService;
import com.gitee.qdbp.jdbc.model.MainDbType;
import com.gitee.qdbp.jdbc.model.OmitStrategy;
import com.gitee.qdbp.jdbc.plugins.impl.BatchInsertByMultiRowsExecutor;
import com.gitee.qdbp.jdbc.plugins.impl.BatchOperateByForEachExecutor;
import com.gitee.qdbp.jdbc.plugins.impl.BatchOperateByMultiSqlExecutor;
import com.gitee.qdbp.jdbc.plugins.impl.BatchUpdateByCaseWhenExecutor;
import com.gitee.qdbp.jdbc.plugins.impl.BatchUpdateByJoinUsingExecutor;
import com.gitee.qdbp.jdbc.plugins.impl.ConfigableJdbcDataTypeResolver;
import com.gitee.qdbp.jdbc.plugins.impl.DataSourceDbVersionFinder;
import com.gitee.qdbp.jdbc.plugins.impl.FastJsonBeanToMapConverter;
import com.gitee.qdbp.jdbc.plugins.impl.FastJsonDbConditionConverter;
import com.gitee.qdbp.jdbc.plugins.impl.NoneEntityDataStateFillStrategy;
import com.gitee.qdbp.jdbc.plugins.impl.OrderByFunctionSqlBuilder;
import com.gitee.qdbp.jdbc.plugins.impl.PersistenceAnnotationTableScans;
import com.gitee.qdbp.jdbc.plugins.impl.SimpleColumnValueValidator;
import com.gitee.qdbp.jdbc.plugins.impl.SimpleDbOperatorContainer;
import com.gitee.qdbp.jdbc.plugins.impl.SimpleEntityFieldFillStrategy;
import com.gitee.qdbp.jdbc.plugins.impl.SimpleJdbcNamingConverter;
import com.gitee.qdbp.jdbc.plugins.impl.SimpleRawValueConverter;
import com.gitee.qdbp.jdbc.plugins.impl.SimpleSqlDialect;
import com.gitee.qdbp.jdbc.plugins.impl.SimpleSqlFormatter;
import com.gitee.qdbp.jdbc.plugins.impl.SimpleSqlFragmentOptions;
import com.gitee.qdbp.jdbc.plugins.impl.SimpleSqlReplacer;
import com.gitee.qdbp.jdbc.plugins.impl.SimpleTablesFieldColumnParser;
import com.gitee.qdbp.jdbc.plugins.impl.SimpleVarToDbValueConverter;
import com.gitee.qdbp.jdbc.plugins.impl.SpringMapToBeanConverter;
import com.gitee.qdbp.jdbc.plugins.impl.SpringSqlFileScanner;
import com.gitee.qdbp.jdbc.plugins.impl.SpringTypeConverter;
import com.gitee.qdbp.jdbc.result.CamelNamingRowToMapMapper;
import com.gitee.qdbp.jdbc.result.TableRowToBeanMapper;
import com.gitee.qdbp.jdbc.result.TablesRowToProperyMapper;
import com.gitee.qdbp.jdbc.support.convert.NumberToBooleanConverter;
import com.gitee.qdbp.jdbc.support.convert.StringToDateConverter;
import com.gitee.qdbp.jdbc.support.enums.AllEnumConverterRegister;
import com.gitee.qdbp.tools.utils.Config;
import com.gitee.qdbp.tools.utils.ReflectTools;
/**
* 插件初始化工具类
*
* @author zhaohuihua
* @version 20210704
*/
public class DbPluginInitTools {
private static final Logger log = LoggerFactory.getLogger(DbPluginInitTools.class);
public static void initDefaultConverter(ConversionService conversionService) {
if (conversionService instanceof ConverterRegistry) {
ConverterRegistry registry = (ConverterRegistry) conversionService;
if (!conversionService.canConvert(String.class, Date.class)) {
registry.addConverter(new StringToDateConverter());
}
// oracle, 如果数字字段定义的类型是SMALLINT, 将会返回BigDecimal
if (!conversionService.canConvert(BigDecimal.class, Boolean.class)) {
registry.addConverter(new NumberToBooleanConverter());
}
// 注册其他枚举值转换处理类: oracle的BigDecimal转Enum等
AllEnumConverterRegister.registerEnumConverterFactory(registry);
try {
// 判断是否为jdk8
Class.forName("java.time.LocalDate");
// 注册日期转换处理类
// DateConverter里面都是jdk8的转换处理类, qdbc默认支持jdk7, 因此使用反射调用jdk8代码
Class> dateConverter = Class.forName("com.gitee.qdbp.jdbc.support.convert.DateConverter");
ReflectTools.invokeMethod(dateConverter, "registerConverters", conversionService);
} catch (ClassNotFoundException ignore) {
} catch (Exception e) {
log.warn("Failed to invoke method of DateConverter.registerConverters()", e);
}
}
}
/**
* 检查并设置默认属性
*
* 灵活就意味着可配置的细节多, 也就难以上手
* 提供一个默认版本, 用于满足基本需求, 基于约定,常用,无定制
*
* 未提供的特性包括:
* TableInfoScans.commonFieldResolver: 不会将公共字段放在查询列表的最后
* EntityFieldFillStrategy.entityFillBizResolver: 不会自动填充创建人/创建时间等业务参数
* EntityDataStateFillStrategy: 不会自动填充数据状态, 不支持逻辑删除
* 等等...
*
* @param plugins 插件容器
*/
public static void checkAndSetDefaultProperty(DbPluginContainer plugins) {
if (plugins.getSqlConfig() == null) {
Config config = new Config();
config.put("recursive.keyword", "WITH RECURSIVE");
config.put("recursive.keyword.db2", "WITH");
config.put("recursive.keyword.sqlserver", "WITH");
plugins.setSqlConfig(config);
}
if (plugins.getConversionService() == null) {
plugins.setConversionService(DefaultConversionService.getSharedInstance());
}
if (plugins.getNamingConverter() == null) {
plugins.setNamingConverter(new SimpleJdbcNamingConverter());
}
if (plugins.getAvailableDbTypes() == null) {
plugins.addAvailableDbTypeClass(MainDbType.class);
}
if (plugins.getSqlTaglibCreator() == null) {
plugins.setSqlTaglibPath("classpath:settings/qdbc/qdbc.taglib.txt");
}
if (plugins.getJdbcDataTypeResolver() == null) {
String path = "classpath:settings/qdbc/qdbc.datatype.txt";
plugins.setJdbcDataTypeResolver(new ConfigableJdbcDataTypeResolver(path));
}
if (plugins.getTableInfoScans() == null) {
plugins.setTableInfoScans(new PersistenceAnnotationTableScans());
}
if (plugins.getTablesFieldColumnParser() == null) {
plugins.setTablesFieldColumnParser(new SimpleTablesFieldColumnParser());
}
if (plugins.getEntityFieldFillStrategy() == null) {
plugins.setEntityFieldFillStrategy(new SimpleEntityFieldFillStrategy());
}
if (plugins.getEntityDataStateFillStrategy() == null) {
plugins.setEntityDataStateFillStrategy(new NoneEntityDataStateFillStrategy());
}
if (plugins.getOmitStrategyOfBatchSql() == null) {
plugins.setOmitStrategyOfBatchSql(new OmitStrategy(50, 5));
}
if (plugins.getOmitStrategyOfInSql() == null) {
plugins.setOmitStrategyOfInSql(new OmitStrategy(8, 3));
}
if (plugins.getRawValueConverter() == null) {
plugins.setRawValueConverter(new SimpleRawValueConverter());
}
if (plugins.getToDbValueConverter() == null) {
plugins.setToDbValueConverter(new SimpleVarToDbValueConverter());
}
if (plugins.getObjectTypeConverter() == null) {
plugins.setObjectTypeConverter(new SpringTypeConverter());
}
if (plugins.getRowToMapConverter() == null) {
CamelNamingRowToMapMapper mapper = new CamelNamingRowToMapMapper();
mapper.setPlugins(plugins.helper());
plugins.setRowToMapConverter(mapper);
}
if (plugins.getTableRowToBeanFactory() == null) {
plugins.setTableRowToBeanFactory(new TableRowToBeanMapper.Factory());
}
if (plugins.getTablesRowToBeanFactory() == null) {
plugins.setTablesRowToBeanFactory(new TablesRowToProperyMapper.Factory());
}
if (plugins.getMapToBeanConverter() == null) {
// 由于fastjson的TypeUtils.castToEnum()逻辑存在硬伤, 无法做到数字枚举值的自定义转换
// container.setMapToBeanConverter(new FastJsonMapToBeanConverter());
// 改为SpringMapToBeanConverter
plugins.setMapToBeanConverter(new SpringMapToBeanConverter());
}
if (plugins.getBeanToMapConverter() == null) {
plugins.setBeanToMapConverter(new FastJsonBeanToMapConverter());
}
if (plugins.getDbConditionConverter() == null) {
plugins.setDbConditionConverter(new FastJsonDbConditionConverter());
}
if (plugins.getOperatorContainer() == null) {
plugins.setOperatorContainer(new SimpleDbOperatorContainer());
}
if (plugins.getSqlFormatter() == null) {
plugins.setSqlFormatter(new SimpleSqlFormatter());
}
if (plugins.getSqlReplacer() == null) {
plugins.setSqlReplacer(new SimpleSqlReplacer());
}
if (plugins.getDbVersionFinder() == null) {
plugins.setDbVersionFinder(new DataSourceDbVersionFinder());
}
if (plugins.getSqlDialectCreator() == null) {
plugins.setSqlDialectCreator(new SimpleSqlDialect.Creator());
}
if (plugins.getSqlFileScanner() == null) {
plugins.setSqlFileScanner(new SpringSqlFileScanner());
}
if (plugins.getSqlFragmentOptions() == null) {
plugins.setSqlFragmentOptions(new SimpleSqlFragmentOptions());
}
if (plugins.getColumnValueValidator() == null) {
plugins.setColumnValueValidator(new SimpleColumnValueValidator());
}
if (plugins.getOrderBySqlBuilders().isEmpty()) {
plugins.addOrderBySqlBuilder(new OrderByFunctionSqlBuilder());
}
if (plugins.getDefaultBatchInsertExecutor() == null) {
plugins.setDefaultBatchInsertExecutor(new BatchOperateByForEachExecutor());
}
if (plugins.getDefaultBatchUpdateExecutor() == null) {
plugins.setDefaultBatchUpdateExecutor(new BatchOperateByForEachExecutor());
}
// 初始化公共的批量操作处理器(通用的放前面,专用的放后面)
if (plugins.getBatchInsertExecutors().isEmpty()) {
plugins.addBatchInsertExecutor(new BatchOperateByMultiSqlExecutor()); // mysql,oracle
plugins.addBatchInsertExecutor(new BatchInsertByMultiRowsExecutor()); // mysql,db2
// BatchInsertByUnionAllFromDualExecutor有问题
// Oracle的CLOB字段批量新增时, 如果CLOB字段值既有小于4000的也有大于4000的
// 就会报错ORA-01790: 表达式必须具有与对应表达式相同的数据类型
// 原因是JdbcTemplate对CLOB的处理, 小于4000的用ps.setString(), 超过4000的用ps.setClob()
// 详见StatementCreatorUtils.setValue()
// plugins.addBatchInsertExecutor(new BatchInsertByUnionAllFromDualExecutor());
}
if (plugins.getBatchUpdateExecutors().isEmpty()) {
plugins.addBatchInsertExecutor(new BatchOperateByMultiSqlExecutor()); // mysql,oracle
plugins.addBatchUpdateExecutor(new BatchUpdateByCaseWhenExecutor()); // mysql,db2
plugins.addBatchUpdateExecutor(new BatchUpdateByJoinUsingExecutor()); // mysql
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy