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; } }