package com.walker.jdbc.config;
|
|
import com.walker.db.DatabaseType;
|
import com.walker.infrastructure.ApplicationRuntimeException;
|
import com.walker.jdbc.DataSourceMeta;
|
import com.walker.jdbc.JdbcInspector;
|
import com.walker.jdbc.dao.PaginationHelper;
|
import com.walker.jdbc.dao.SqlDaoSupport;
|
import org.aspectj.lang.annotation.Aspect;
|
import org.slf4j.Logger;
|
import org.slf4j.LoggerFactory;
|
import org.springframework.aop.Advisor;
|
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
|
import org.springframework.aop.support.DefaultPointcutAdvisor;
|
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Lazy;
|
import org.springframework.jdbc.core.JdbcTemplate;
|
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
|
import org.springframework.transaction.TransactionDefinition;
|
import org.springframework.transaction.TransactionManager;
|
import org.springframework.transaction.interceptor.DefaultTransactionAttribute;
|
import org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource;
|
import org.springframework.transaction.interceptor.TransactionInterceptor;
|
|
import javax.sql.DataSource;
|
|
@Configuration
|
@Aspect
|
public class DatabaseConfig {
|
|
// private static final String AOP_POINTCUT_EXPRESSION = "execution (* com.walkersoft..*ServiceImpl.*(..))";
|
private static final String AOP_POINTCUT_EXPRESSION = "execution (* com..*ServiceImpl.*(..))";
|
|
private final transient Logger logger = LoggerFactory.getLogger(this.getClass());
|
|
// @Autowired
|
// @Resource
|
private DataSource dataSource;
|
|
// @Resource
|
private TransactionManager transactionManager;
|
|
private DatabaseType databaseType = null;
|
|
/**
|
* 这里让延迟加载,看是否能避免报错:is not eligible for getting processed by all BeanPostProcessors
|
* @param dataSource
|
* @param transactionManager
|
* @date 2023-01-05
|
*/
|
@Autowired
|
public DatabaseConfig(DataSource dataSource, TransactionManager transactionManager){
|
this.dataSource = dataSource;
|
this.transactionManager = transactionManager;
|
}
|
|
@Bean
|
public DatabaseProperties databaseProperties(){
|
return new DatabaseProperties();
|
}
|
|
/**
|
* 创建数据源元数据对象,可以通过该对象获取数据库类型、url、数据库名称等内容。
|
// * @param dataSource
|
* @return
|
* @date 2022-09-13
|
*/
|
@Bean
|
public JdbcInspector jdbcInspector(DatabaseProperties databaseProperties){
|
DataSourceMeta defaultDataSource = (DataSourceMeta)this.dataSource;
|
// DatabaseType databaseType = ((DefaultDataSource)this.dataSource).getDatabaseType();
|
DatabaseType databaseType = defaultDataSource.getDatabaseType();
|
defaultDataSource.setUsername(databaseProperties.getUsername());
|
defaultDataSource.setPassword(databaseProperties.getPassword());
|
|
JdbcInspector.getInstance().setPrimaryDatabaseType(databaseType);
|
JdbcInspector.getInstance().setPrimaryDataSourceMeta(defaultDataSource);
|
logger.info("创建: JdbcInspector, username=" + databaseProperties.getUsername());
|
return JdbcInspector.getInstance();
|
}
|
|
@Bean
|
public TransactionInterceptor txAdvice() {
|
if(dataSource == null){
|
throw new ApplicationRuntimeException("未找到数据源:DataSource");
|
}
|
if(!(this.dataSource instanceof DataSourceMeta)){
|
throw new ApplicationRuntimeException("配置的数据源必须实现接口:DataSourceMeta!");
|
}
|
// if(!(dataSource instanceof DataSourceMeta)){
|
// throw new ApplicationRuntimeException("请配置数据源类型为:com.walker.jdbc.ds.DefaultDataSource");
|
// }
|
databaseType = ((DataSourceMeta)this.dataSource).getDatabaseType();
|
logger.info("dataType = " + databaseType);
|
|
// 2022-11-01 发现上面定义的bean没有初始化。
|
this.jdbcInspector(databaseProperties());
|
|
// 这里设置主数据库信息,2022-08-17
|
// JdbcInspector.getInstance().setPrimaryDatabaseType(databaseType);
|
// JdbcInspector.getInstance().setPrimaryDataSourceMeta((DefaultDataSource)this.dataSource);
|
|
DefaultTransactionAttribute txAttr_REQUIRED = new DefaultTransactionAttribute();
|
txAttr_REQUIRED.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
|
DefaultTransactionAttribute txAttr_REQUIRED_READONLY = new DefaultTransactionAttribute();
|
txAttr_REQUIRED_READONLY.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
|
txAttr_REQUIRED_READONLY.setReadOnly(true);
|
if(databaseType.getTypeIndex() != DatabaseType.SQLITE.getTypeIndex()){
|
txAttr_REQUIRED.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
|
txAttr_REQUIRED_READONLY.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
|
}
|
NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource();
|
source.addTransactionalMethod("add*", txAttr_REQUIRED);
|
source.addTransactionalMethod("insert*", txAttr_REQUIRED);
|
source.addTransactionalMethod("save*", txAttr_REQUIRED);
|
source.addTransactionalMethod("start*", txAttr_REQUIRED);
|
source.addTransactionalMethod("delete*", txAttr_REQUIRED);
|
source.addTransactionalMethod("update*", txAttr_REQUIRED);
|
source.addTransactionalMethod("create*", txAttr_REQUIRED);
|
source.addTransactionalMethod("exec*", txAttr_REQUIRED);
|
source.addTransactionalMethod("set*", txAttr_REQUIRED);
|
source.addTransactionalMethod("clear*", txAttr_REQUIRED);
|
source.addTransactionalMethod("clean*", txAttr_REQUIRED);
|
source.addTransactionalMethod("sync*", txAttr_REQUIRED);
|
source.addTransactionalMethod("send*", txAttr_REQUIRED);
|
source.addTransactionalMethod("submit*", txAttr_REQUIRED);
|
source.addTransactionalMethod("init*", txAttr_REQUIRED);
|
|
source.addTransactionalMethod("retract*", txAttr_REQUIRED);
|
source.addTransactionalMethod("back*", txAttr_REQUIRED);
|
source.addTransactionalMethod("leave*", txAttr_REQUIRED);
|
source.addTransactionalMethod("enter*", txAttr_REQUIRED);
|
source.addTransactionalMethod("next*", txAttr_REQUIRED);
|
source.addTransactionalMethod("sign*", txAttr_REQUIRED);
|
source.addTransactionalMethod("upload*", txAttr_REQUIRED);
|
source.addTransactionalMethod("copy*", txAttr_REQUIRED);
|
source.addTransactionalMethod("batch*", txAttr_REQUIRED);
|
|
source.addTransactionalMethod("get*", txAttr_REQUIRED_READONLY);
|
source.addTransactionalMethod("query*", txAttr_REQUIRED_READONLY);
|
source.addTransactionalMethod("find*", txAttr_REQUIRED_READONLY);
|
source.addTransactionalMethod("list*", txAttr_REQUIRED_READONLY);
|
source.addTransactionalMethod("count*", txAttr_REQUIRED_READONLY);
|
source.addTransactionalMethod("is*", txAttr_REQUIRED_READONLY);
|
source.addTransactionalMethod("sql*", txAttr_REQUIRED_READONLY);
|
source.addTransactionalMethod("*", txAttr_REQUIRED_READONLY);
|
return new TransactionInterceptor(transactionManager, source);
|
}
|
|
@Bean
|
@Lazy
|
public Advisor txAdviceAdvisor() {
|
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
|
pointcut.setExpression(AOP_POINTCUT_EXPRESSION);
|
return new DefaultPointcutAdvisor(pointcut, txAdvice());
|
}
|
|
@Bean("jdbcTemplate")
|
public JdbcTemplate jdbcTemplate() {
|
JdbcTemplate jdbcTemplate = new JdbcTemplate();
|
try {
|
jdbcTemplate.setDataSource(this.dataSource);
|
jdbcTemplate.setLazyInit(false);
|
} catch (Exception e) {
|
logger.error(e.getMessage(), e);
|
}
|
return jdbcTemplate;
|
}
|
|
@Bean("namedParameterJdbcTemplate")
|
public NamedParameterJdbcTemplate namedParameterJdbcTemplate() {
|
NamedParameterJdbcTemplate namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(this.dataSource);
|
return namedParameterJdbcTemplate;
|
}
|
|
@Bean("paginationHelper")
|
public PaginationHelper paginationHelper() {
|
PaginationHelper paginationHelper = new PaginationHelper();
|
// paginationHelper.setType(JdbcUtils.getDbType(dataSourceProperties.getUrl()));
|
paginationHelper.setType(this.databaseType.toString());
|
return paginationHelper;
|
}
|
|
@Bean("dao")
|
public SqlDaoSupport jdbcDaoImpl(DatabaseProperties databaseProperties) {
|
SqlDaoSupport jdbcDao = new SqlDaoSupport();
|
jdbcDao.setJdbcTemplate(this.jdbcTemplate());
|
jdbcDao.setNamedParameterJdbcTemplate(this.namedParameterJdbcTemplate());
|
jdbcDao.setPaginationHelper(this.paginationHelper());
|
jdbcDao.setShowSql(databaseProperties.isShowSql());
|
return jdbcDao;
|
}
|
}
|