Loading

mybatis全局变量

描述:生产和测试的一些枚举值不一样,然后mapper.xml中会用到这些枚举,所以想了个方案通过在工程初始化时通过连接数据库查询对应枚举值作为参数。

方案一:

自定义数据源配置,在数据源中设置全局变量

@Data
@Slf4j
@Configuration
@EnableTransactionManagement
// com.test.mapper.test 包下的mapper都使用这个数据源
@MapperScan(basePackages = "com.test.mapper.test",
        sqlSessionFactoryRef = "testSqlSessionFactory")
@ConfigurationProperties(prefix = "test.datasource")
public class MybatisTestConfiguration {

    private static final String MAPPER_LOCATION = "classpath:mapper/test/**/*.xml";

    private String driverClassName;
    private String url;
    private String userName;
    private String password;
    
    /**
     * 全局自定义参数
     */
    @Resource
    private DmcpConfigurationVarProperties dmcpConfigurationVarProperties;

    /**
     * 动态属性配置
     */
    private final Properties dynamicProperties = new Properties();
    
    @Bean(name = "testDataSource")
    public DataSource testDataSource() {
        DruidDataSource ds = new DruidDataSource();
        ds.setUrl(url);
        ds.setUsername(userName);
        ds.setPassword(password);
        ds.setDriverClassName(getOrDefault(driverClassName, "oracle.jdbc.OracleDriver"));

        return ds;
    }

    @Bean(name = "testSqlSessionFactory")
    public SqlSessionFactory testSqlSessionFactory(@Qualifier("testDataSource") DataSource dataSource) {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        // MyBatis config
        org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
        configuration.setMapUnderscoreToCamelCase(true);
        // 设置jdbcTypeForNull,解决Oracle null值问题
        configuration.setJdbcTypeForNull(JdbcType.NULL);
        // TODO 自定义全局变量
        configuration.setVariables(getMybatisProperties(dataSource));
        bean.setConfiguration(configuration);
        try {
            ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
            bean.setMapperLocations(resolver.getResources(MAPPER_LOCATION));
            return bean.getObject();
        } catch (Exception e) {
            throw new RuntimeException("Failed to build SqlSessionFactory", e);
        }
    }
    
    @Bean(name = "testTransactionManager")
    public DataSourceTransactionManager testTransactionManager(@Qualifier("testDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean(name = "testSqlSessionTemplate")
    @Primary
    public SqlSessionTemplate primarySqlSessionTemplate(@Qualifier("testSqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
    
    private Properties getMybatisProperties(DataSource dataSource) {
        Properties properties = new Properties();
        // 设置表名配置
        log.info("设置mybatis全局参数开始...");
        // 添加数据库枚举参数
        addDatabaseEnumParameters(dataSource, properties);
        log.info("设置mybatis全局参数完成...");
        return properties;
    }
    
    /**
     * 添加数据库枚举参数
     */
    private void addDatabaseEnumParameters(DataSource dataSource, Properties properties) {
        String enumSql = "SQL";
        try (Connection connection = dataSource.getConnection();
             PreparedStatement ps = connection.prepareStatement(enumSql)) {
            log.info("》》》加载数据库枚举...");
            try (ResultSet rs = ps.executeQuery()) {
                if (rs.next()) {
                    String id = rs.getString("ID");
                    properties.setProperty("param", id);
                }
            }
        } catch (Exception e) {
            log.warn("查询数据库枚举失败:", e);
        }
    }
    
    /**
     * 获取字符串配置值,如果为空则使用默认值
     */
    private String getOrDefault(String value, String defaultValue) {
        return (value != null && !value.isEmpty()) ? value : defaultValue;
    }
}

方案二

使用mybatis-plus多数据源时,创建配置bean设置

@Slf4j
@Configuration
public class MybatisVariableConfig {

    @Value("${spring.datasource.dynamic.datasource.test.driver-class-name}")
    private String driverClassName;
    @Value("${spring.datasource.dynamic.datasource.test.url}")
    private String url;
    @Value("${spring.datasource.dynamic.datasource.test.username}")
    private String userName;
    @Value("${spring.datasource.dynamic.datasource.test.password}")
    private String password;
    @Value("${spring.datasource.dynamic.datasource.test.druid.validation-query}")
    private String validationQuery;


    @Bean
    public ConfigurationCustomizer configurationCustomizer() {
        try(DruidDataSource dataSource = this.buildDataSource()){
            return (org.apache.ibatis.session.Configuration configuration) -> {
                Properties vars = configuration.getVariables();
                if (vars == null) {
                    vars = new Properties();
                }
                // 加载数据库枚举参数
                addDatabaseEnumParameters(dataSource, vars);

                configuration.setVariables(vars);
            };
        }catch (Exception e){
            throw new RuntimeException("初始化test枚举失败:", e);
        }
    }


    /**
     * 构建数据源
     */
    private DruidDataSource buildDataSource() {
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl(url);
        dataSource.setUsername(userName);
        dataSource.setPassword(password);
        dataSource.setDriverClassName(driverClassName);
        dataSource.setValidationQuery(validationQuery);
        return dataSource;
    }
}
posted @ 2025-09-05 17:05  IamHzc  阅读(6)  评论(0)    收藏  举报