张晓波
2023-09-19 164694c47c35d6654df69b533e8dbf8b5423efc5
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
package com.thhy.general.config.mysql;
 
import com.thhy.general.common.enums.DataSources;
import com.thhy.general.config.mysql.tos.MoreReflection;
import org.apache.ibatis.cache.CacheKey;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.annotation.Transactional;
 
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Properties;
 
@Intercepts({
        @Signature(
                type = Executor.class,
                method = "query",
                args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}
        ),
        @Signature(
                type = Executor.class,
                method = "query",
                args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class}
        ),
        @Signature(
                type = Executor.class,
                method = "update",
                args = {MappedStatement.class, Object.class}
        )
})
public class SwtichInterceptor implements Interceptor {
 
    private Logger logger = LoggerFactory.getLogger(SwtichInterceptor.class);
 
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
 
        //System.out.println(invocation.getMethod().getName());
        MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
        //Connection connection = ((SqlSessionFactory) SpringContextUtils.getBean(SqlSessionFactory.class)).openSession().getConnection();
        String idclass = mappedStatement.getId();
        String className = idclass.substring(0,idclass.lastIndexOf("."));
 
        String serviceClass = MoreReflection.getCallerPlace(Class.forName(className)).getClassName();
        String serviceMethod = MoreReflection.getCallerPlace(Class.forName(className)).getMethodName();
        //System.out.println("========"+serviceClass+","+serviceMethod);
        Class clazz = Class.forName(serviceClass);
        Method[] methods = clazz.getMethods();
        for(Method m : methods){
            if(m.getName().equals(serviceMethod)){
                Annotation[] annotations = m.getDeclaredAnnotations();
                for(Annotation annotation : annotations){
                    if(annotation.annotationType().equals(Transactional.class)){
                        //System.out.println(mappedStatement.getBoundSql());
                        return invocation.proceed();
                    }
                }
            }
        }
        Object parameter = null;
        if (invocation.getArgs().length > 1) {
            parameter = invocation.getArgs()[1];
        }
        if (!SqlCommandType.SELECT.equals(mappedStatement.getSqlCommandType())) {
            //
            try {
                DynamicDataSource.setDataSource(DataSources.MASTER.name());
                System.out.println(mappedStatement.getSqlSource().toString());
                return invocation.proceed();
            } finally {
                DynamicDataSource.clearDataSource();
            }
        }else{
            //查询
            try {
                DynamicDataSource.setDataSource(DataSources.SLAVE.name());
 
                //printSql(serviceClass,serviceMethod,idclass,mappedStatement,parameter);
                return invocation.proceed();
            } finally {
                DynamicDataSource.clearDataSource();
            }
        }
 
    }
 
 
 
    @Override
    public Object plugin(Object target) {
        if (target instanceof Executor) {
            return Plugin.wrap(target, this);
        } else {
            return target;
        }
    }
 
    @Override
    public void setProperties(Properties properties) {
        Interceptor.super.setProperties(properties);
    }
 
    public void printSql(String service,String serviceMethod,String mapperMethod,MappedStatement mappedStatement,Object parameter){
 
        logger.info("调用的Service:["+service+"]中的:["+serviceMethod+"]方法");
        logger.info("调用Mapper:["+mapperMethod+"]");
        String sql = mappedStatement.getBoundSql(parameter).getSql();
        logger.info("调用的sql:\n["+sql+"]");
    }
}