国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

香港云服务器
服務器之家 - 編程語言 - Java教程 - MyBatis自定義SQL攔截器示例詳解

MyBatis自定義SQL攔截器示例詳解

2022-02-27 15:07老鄭_ Java教程

Mybatis支持對Executor、StatementHandler、PameterHandler和ResultSetHandler 接口進行攔截,也就是說會對這4種對象進行代理,下面這篇文章主要給大家介紹了關于MyBatis自定義SQL攔截器的相關資料,需要的朋友可以參考下

前言

本文主要是講通過 MyBaits 的 Interceptor 的拓展點進行對 MyBatis 執行 SQL 之前做一個邏輯攔截實現自定義邏輯的插入執行。

適合場景:1. 比如限制數據庫查詢最大訪問條數;2. 限制登錄用戶只能訪問當前機構數據。

定義是否開啟注解

定義是否開啟注解, 主要做的一件事情就是是否添加 SQL 攔截器。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// 全局開啟
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(MyBatisSqlInterceptorConfiguration.class)
public @interface EnableSqlInterceptor {
 
}
 
// 自定義注解
@Target({ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface DataScope {
 
}

注冊SQL 攔截器

注冊一個 SQL 攔截器,會對符合條件的 SQL 查詢操作進行攔截。

?
1
2
3
4
5
6
7
8
public class MyBatisSqlInterceptorConfiguration implements ApplicationContextAware {
 
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        SqlSessionFactory sqlSessionFactory = applicationContext.getBean(SqlSessionFactory.class);
        sqlSessionFactory.getConfiguration().addInterceptor(new MyBatisInterceptor());
    }
}

處理邏輯

在處理邏輯中,我主要是做一個簡單的 limit 1 案例,如果是自己需要做其他的邏輯需要修改

?
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
@Slf4j
@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}),
        })
public class MyBatisInterceptor implements Interceptor {
 
    private static final Logger LOGGER = LoggerFactory.getLogger(MyBatisInterceptor.class);
 
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        // TODO Auto-generated method stub
        Object[] args = invocation.getArgs();
        MappedStatement ms = (MappedStatement) args[0];
        Object parameter = args[1];
        RowBounds rowBounds = (RowBounds) args[2];
        ResultHandler resultHandler = (ResultHandler) args[3];
        Executor executor = (Executor) invocation.getTarget();
        CacheKey cacheKey;
        BoundSql boundSql;
        //由于邏輯關系,只會進入一次
        if (args.length == 4) {
            //4 個參數時
            boundSql = ms.getBoundSql(parameter);
            cacheKey = executor.createCacheKey(ms, parameter, rowBounds, boundSql);
        } else {
            //6 個參數時
            cacheKey = (CacheKey) args[4];
            boundSql = (BoundSql) args[5];
        }
        DataScope dataScope = getDataScope(ms);
        if (Objects.nonNull(dataScope)) {
            String origSql = boundSql.getSql();
            log.info("origSql : {}", origSql);
            // 組裝新的 sql
            // todo you weaving business
            String newSql = origSql + " limit 1";
 
            // 重新new一個查詢語句對象
            BoundSql newBoundSql = new BoundSql(ms.getConfiguration(), newSql,
                    boundSql.getParameterMappings(), boundSql.getParameterObject());
 
            // 把新的查詢放到statement里
            MappedStatement newMs = newMappedStatement(ms, new BoundSqlSource(newBoundSql));
            for (ParameterMapping mapping : boundSql.getParameterMappings()) {
                String prop = mapping.getProperty();
                if (boundSql.hasAdditionalParameter(prop)) {
                    newBoundSql.setAdditionalParameter(prop, boundSql.getAdditionalParameter(prop));
                }
            }
 
            args[0] = newMs;
            if (args.length == 6) {
                args[5] = newMs.getBoundSql(parameter);
            }
        }
        LOGGER.info("mybatis intercept sql:{},Mapper方法是:{}", boundSql.getSql(), ms.getId());
 
 
        return invocation.proceed();
    }
 
    private MappedStatement newMappedStatement(MappedStatement ms, SqlSource newSqlSource) {
        MappedStatement.Builder builder = new
                MappedStatement.Builder(ms.getConfiguration(), ms.getId(), newSqlSource, ms.getSqlCommandType());
        builder.resource(ms.getResource());
        builder.fetchSize(ms.getFetchSize());
        builder.statementType(ms.getStatementType());
        builder.keyGenerator(ms.getKeyGenerator());
        if (ms.getKeyProperties() != null && ms.getKeyProperties().length > 0) {
            builder.keyProperty(ms.getKeyProperties()[0]);
        }
        builder.timeout(ms.getTimeout());
        builder.parameterMap(ms.getParameterMap());
        builder.resultMaps(ms.getResultMaps());
        builder.resultSetType(ms.getResultSetType());
        builder.cache(ms.getCache());
        builder.flushCacheRequired(ms.isFlushCacheRequired());
        builder.useCache(ms.isUseCache());
        return builder.build();
    }
 
 
    private DataScope getDataScope(MappedStatement mappedStatement) {
        String id = mappedStatement.getId();
        // 獲取 Class Method
        String clazzName = id.substring(0, id.lastIndexOf('.'));
        String mapperMethod = id.substring(id.lastIndexOf('.') + 1);
 
        Class<?> clazz;
        try {
            clazz = Class.forName(clazzName);
        } catch (ClassNotFoundException e) {
            return null;
        }
        Method[] methods = clazz.getMethods();
 
        DataScope dataScope = null;
        for (Method method : methods) {
            if (method.getName().equals(mapperMethod)) {
                dataScope = method.getAnnotation(DataScope.class);
                break;
            }
        }
        return dataScope;
    }
 
    @Override
    public Object plugin(Object target) {
        // TODO Auto-generated method stub
        LOGGER.info("MysqlInterCeptor plugin>>>>>>>{}", target);
        return Plugin.wrap(target, this);
    }
 
    @Override
    public void setProperties(Properties properties) {
        // TODO Auto-generated method stub
        String dialect = properties.getProperty("dialect");
        LOGGER.info("mybatis intercept dialect:>>>>>>>{}", dialect);
    }
 
    /**
     * 定義一個內部輔助類,作用是包裝 SQL
     */
    class BoundSqlSource implements SqlSource {
        private BoundSql boundSql;
 
        public BoundSqlSource(BoundSql boundSql) {
            this.boundSql = boundSql;
        }
 
        public BoundSql getBoundSql(Object parameterObject) {
            return boundSql;
        }
 
    }
 
}

如何使用

我們在 XXXMapper 中對應的數據操作方法只要加入 @DataScope 注解即可。

?
1
2
3
4
5
6
7
8
@Mapper
public interface OrderMapper {
 
   @Select("select 1 ")
   @DataScope
   Intger selectOne();
 
}

參考資料

mybatis.org/mybatis-3/z

總結

到此這篇關于MyBatis自定義SQL攔截器的文章就介紹到這了,更多相關MyBatis自定義SQL攔截器內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://juejin.cn/post/7021508758777888799

延伸 · 閱讀

精彩推薦
496
主站蜘蛛池模板: 天天综合久久 | 免费看的av| 先锋影音av中文字幕 | 四虎影视4hu4虎成人 | 日韩在线中文字幕 | 狠狠操网站 | 在线播放中文字幕 | 国产精品久久久久久久久免费 | 久久精品91 | 亚洲国产aⅴ精品一区二区 少妇一级片免费看 | 亚洲97| 亚洲欧洲视频在线 | 欧美日韩精品免费 | 成人在线观看免费视频 | 精品中文字幕一区 | 国产精品久久久久久久久久久久久久 | 国产美女精品 | 日韩不卡一区二区三区 | 亚洲不卡视频 | 深夜视频在线 | 亚洲日本韩国在线观看 | 国产综合亚洲精品一区二 | 欧洲成人 | 久久国产精品久久久久久 | 综合久 | 精品在线视频一区 | 天天综合天天做天天综合 | av天天干 | 黑森林av凹凸导航 | 国产高清免费 | 成人在线观看免费 | 久久综合亚洲 | 北条麻妃在线一区二区免费播放 | 国产精品久久久久久久久久久久冷 | 伊人伊成久久人综合网站 | 日韩在线电影 | 黄网免费看| 国产综合视频 | 99久久综合精品五月天 | 免费视频黄 | 最新免费av网站 |