You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

121 lines
4.7 KiB

package com.example.sbcamel;
import java.io.IOException;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import javax.sql.DataSource;
import org.apache.camel.component.mybatis.MyBatisComponent;
import org.apache.camel.spring.spi.SpringTransactionPolicy;
import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy;
import org.springframework.transaction.PlatformTransactionManager;
import com.google.common.reflect.ClassPath;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
@Configuration
public class DatabaseConfig {
private static final Logger logger = LoggerFactory.getLogger(DatabaseConfig.class);
public static final String CFG_APP_DATABASE_URL = "${app.database.url}";
public static final String CFG_APP_DATABASE_USERNAME = "${app.database.username:}";
public static final String CFG_APP_DATABASE_PASSWORD = "${app.database.password:}";
public static final String CFG_APP_DATABASE_MAPPER_PACKAGE = "${app.database.mapper-package}";
public static final String CFG_APP_DATABASE_SPRINGBOOT_CLASS_PREFIX = "${app.database.springboot-class-prefix:BOOT-INF.classes.}";
@Value(CFG_APP_DATABASE_URL)
private String dbUrl;
@Value(CFG_APP_DATABASE_USERNAME)
private String dbUsername;
@Value(CFG_APP_DATABASE_PASSWORD)
private String dbPassword;
@Value(CFG_APP_DATABASE_MAPPER_PACKAGE)
private String mapperPackage;
@Value(CFG_APP_DATABASE_SPRINGBOOT_CLASS_PREFIX)
private String springBootClassPrefix;
@Bean
HikariConfig hikariConfig() {
HikariConfig config = new HikariConfig();
config.setJdbcUrl(dbUrl);
config.setUsername(dbUsername);
config.setPassword(dbPassword);
config.addDataSourceProperty("cachePrepStmts", "true");
config.addDataSourceProperty("prepStmtCacheSize", "250");
config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
return config;
}
@Bean
DataSource dataSource(HikariConfig hikariConfig) {
return new TransactionAwareDataSourceProxy(new HikariDataSource(hikariConfig));
}
@Bean
PlatformTransactionManager txManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean
SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
Environment environment = new Environment("development", new JdbcTransactionFactory(), dataSource);
org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration(
environment);
Set<Class<?>> mapperClasses = findAllClassesUsingGuava(mapperPackage);
mapperClasses.forEach(configuration::addMapper);
return new SqlSessionFactoryBuilder().build(configuration);
}
@Bean
MyBatisComponent mybatis(SqlSessionFactory sqlSessionFactory) {
MyBatisComponent mybatis = new MyBatisComponent();
mybatis.setSqlSessionFactory(sqlSessionFactory);
return mybatis;
}
@Bean
SpringTransactionPolicy propagationRequired(PlatformTransactionManager txManager) {
SpringTransactionPolicy propagationRequired = new SpringTransactionPolicy();
propagationRequired.setTransactionManager(txManager);
propagationRequired.setPropagationBehaviorName("PROPAGATION_REQUIRED");
return propagationRequired;
}
private Set<Class<?>> findAllClassesUsingGuava(String packageName) throws IOException {
logger.trace("Orm mappers packageName: {}", packageName);
return ClassPath.from(ClassLoader.getSystemClassLoader()).getAllClasses().stream()
.peek(clazz -> logger.trace("candidate class: {}, package name: {}", clazz, clazz.getPackageName()))
.filter(clazz -> clazz.getPackageName().endsWith(packageName))
.peek(clazz -> logger.info("accepted class: {}, package name: {}", clazz, clazz.getPackageName()))
.map(clazz -> {
try {
if (clazz.getName().startsWith(springBootClassPrefix)) {
return Class.forName(clazz.getName().replace(springBootClassPrefix, ""));
}
return Class.forName(clazz.getName());
} catch (ClassNotFoundException e) {
logger.error("cannot convert this class name to class: {}", clazz.getName());
}
return null;
}).filter(Objects::nonNull).collect(Collectors.toSet());
}
}