shikeying
2024-01-11 3b67e947e36133e2a40eb2737b15ea375e157ea0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
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;
    }
}