All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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