最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

如何自定義MyBatis攔截器更改表名

 更新時(shí)間:2023年10月23日 14:08:05   作者:emanjusaka  
自定義MyBatis攔截器可以在方法執(zhí)行前后插入自己的邏輯,這非常有利于擴(kuò)展和定制 MyBatis 的功能,本篇文章實(shí)現(xiàn)自定義一個(gè)攔截器去改變要插入或者查詢的數(shù)據(jù)源?,需要的朋友可以參考下

自定義MyBatis攔截器可以在方法執(zhí)行前后插入自己的邏輯,這非常有利于擴(kuò)展和定制 MyBatis 的功能。本篇文章實(shí)現(xiàn)自定義一個(gè)攔截器去改變要插入或者查詢的數(shù)據(jù)源。

@Intercepts

@Intercepts是Mybatis的一個(gè)注解,它的主要作用是標(biāo)識(shí)一個(gè)類為攔截器。該注解通過一個(gè)@Signature注解(即攔截點(diǎn)),來指定攔截那個(gè)對(duì)象里面的某個(gè)方法。

具體來說,@Signature注解的屬性type用于指定攔截器類型,可能的值包括:

  • Executor(sql的內(nèi)部執(zhí)行器)
  • ParameterHandler(攔截參數(shù)的處理)
  • StatementHandler(攔截sql的構(gòu)建)
  • ResultSetHandler(攔截結(jié)果的處理)。

method屬性表示在指定的攔截器類型中要攔截的方法

args屬性表示攔截的方法對(duì)應(yīng)的參數(shù)

實(shí)現(xiàn)步驟

實(shí)現(xiàn)org.apache.ibatis.plugin.Interceptor接口,重寫一下的方法:

添加攔截器注解,@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})})

配置文件中添加攔截器

注意需要在 Spring Boot 的 application.yml 文件中配置 mybatis 配置文件的路徑。

mybatis攔截器目前不支持在application.yml配置文件中通過屬性配置,目前只支持通過xml配置或者代碼配置。

代碼實(shí)現(xiàn)

Mybatis攔截器:

package top.emanjusaka.springboottest.mybatis.plugin;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.reflection.DefaultReflectorFactory;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import top.emanjusaka.springboottest.mybatis.annotation.DBTableStrategy;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * @Author emanjusaka
 * @Date 2023/10/18 17:25
 * @Version 1.0
 */
@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})})
public class DynamicMybatisPlugin implements Interceptor {
    private Pattern pattern = Pattern.compile("(from|into|update)[\\s]{1,}(\\w{1,})", Pattern.CASE_INSENSITIVE);
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
        MetaObject metaObject = MetaObject.forObject(statementHandler, SystemMetaObject.DEFAULT_OBJECT_FACTORY, SystemMetaObject.DEFAULT_OBJECT_WRAPPER_FACTORY, new DefaultReflectorFactory());
        MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");
        // 獲取自定義注解判斷是否進(jìn)行分表操作
        String id = mappedStatement.getId();
        String className = id.substring(0, id.lastIndexOf("."));
        Class<?> clazz = Class.forName(className);
        DBTableStrategy dbTableStrategy = clazz.getAnnotation(DBTableStrategy.class);
        if (null == dbTableStrategy || !dbTableStrategy.changeTable() || null == dbTableStrategy.tbIdx()) {
            return invocation.proceed();
        }
        // 獲取SQL
        BoundSql boundSql = statementHandler.getBoundSql();
        String sql = boundSql.getSql();
        // 替換SQL表名
        Matcher matcher = pattern.matcher(sql);
        String tableName = null;
        if (matcher.find()) {
            tableName = matcher.group().trim();
        }
        assert null != tableName;
        String replaceSql = matcher.replaceAll(tableName + "_" + dbTableStrategy.tbIdx());
        // 通過反射修改SQL語句
        Field field = boundSql.getClass().getDeclaredField("sql");
        field.setAccessible(true);
        field.set(boundSql, replaceSql);
        field.setAccessible(false);
        return invocation.proceed();
    }
}

mapper的xml:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="top.emanjusaka.springboottest.score.repository.IScoreRepository">
    <select id="selectAll" resultType="top.emanjusaka.springboottest.score.model.vo.ScoreVO">
        select * from score
    </select>
</mapper>

切換表名的注解:

package top.emanjusaka.springboottest.score.repository;
import org.apache.ibatis.annotations.Mapper;
import top.emanjusaka.springboottest.mybatis.annotation.DBTableStrategy;
import top.emanjusaka.springboottest.score.model.vo.ScoreVO;
import java.util.List;
/**
 * @Author emanjusaka
 * @Date 2023/10/18 17:45
 * @Version 1.0
 */
@Mapper
@DBTableStrategy(changeTable = true,tbIdx = "2")
public interface IScoreRepository {
    List<ScoreVO> selectAll();
}

測試代碼:

package top.emanjusaka.springboottest;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import top.emanjusaka.springboottest.score.model.vo.ScoreVO;
import top.emanjusaka.springboottest.score.service.IScore;
import javax.annotation.Resource;
import java.util.List;
@SpringBootTest
class SpringBootTestApplicationTests {
    @Resource
    private IScore score;
    @Test
    void contextLoads() {
        List<ScoreVO> list = score.selectAll();
        list.forEach(System.out::println);
    }
}

運(yùn)行結(jié)果

通過上圖可以看出,現(xiàn)在表名已經(jīng)修改成了score_2了。通過這種機(jī)制,我們可以應(yīng)用到自動(dòng)分表中。本文的表名的索引是通過注解參數(shù)傳遞的,實(shí)際應(yīng)用中需要通過哈希散列計(jì)算。

到此這篇關(guān)于自定義MyBatis攔截器更改表名的文章就介紹到這了,更多相關(guān)MyBatis攔截器更改表名內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • String.join()方法示例詳解

    String.join()方法示例詳解

    String.join() 方法是連接指定數(shù)組的元素或集合的成員,在每個(gè)元素或成員之間使用指定的分隔符,這篇文章主要介紹了String.join()方法示例詳解,需要的朋友可以參考下
    2024-01-01
  • jsp中存取session值簡單介紹

    jsp中存取session值簡單介紹

    這篇文章主要介紹了jsp中存取session值簡單介紹,涉及request和session的域操作等相關(guān)內(nèi)容,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-11-11
  • 詳解java中String、StringBuilder、StringBuffer的區(qū)別

    詳解java中String、StringBuilder、StringBuffer的區(qū)別

    這篇文章主要介紹了java中String、StringBuilder、StringBuffer的區(qū)別,文中講解的很清晰,有對(duì)于這方面不太懂的同學(xué)可以研究下
    2021-02-02
  • Java詳解AVL樹的應(yīng)用

    Java詳解AVL樹的應(yīng)用

    AVL樹是高度平衡的二叉樹,它的特點(diǎn)是AVL樹中任何節(jié)點(diǎn)的兩個(gè)子樹的高度最大差別為1,本文主要給大家介紹了Java如何實(shí)現(xiàn)AVL樹,需要的朋友可以參考下
    2022-07-07
  • JavaWeb實(shí)現(xiàn)顯示mysql數(shù)據(jù)庫數(shù)據(jù)

    JavaWeb實(shí)現(xiàn)顯示mysql數(shù)據(jù)庫數(shù)據(jù)

    MySQL是最流行的關(guān)系型數(shù)據(jù)庫管理系統(tǒng),在WEB應(yīng)用方面MySQL是最好的。本文將利用JavaWeb實(shí)現(xiàn)顯示mysql數(shù)據(jù)庫數(shù)據(jù)功能,需要的可以參考一下
    2022-03-03
  • mybatis查詢oracle long類型的踩坑記錄

    mybatis查詢oracle long類型的踩坑記錄

    這篇文章主要介紹了mybatis查詢oracle long類型的踩坑記錄,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03
  • IntelliJ IDEA中如何構(gòu)建Spring Boot的項(xiàng)目

    IntelliJ IDEA中如何構(gòu)建Spring Boot的項(xiàng)目

    這篇文章主要介紹了IntelliJ IDEA中如何構(gòu)建Spring Boot的項(xiàng)目問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • SpringBoot小程序推送信息的項(xiàng)目實(shí)踐

    SpringBoot小程序推送信息的項(xiàng)目實(shí)踐

    本文主要介紹了SpringBoot小程序推送信息的項(xiàng)目實(shí)踐,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-04-04
  • Java?NIO實(shí)現(xiàn)多人聊天室

    Java?NIO實(shí)現(xiàn)多人聊天室

    這篇文章主要為大家詳細(xì)介紹了Java?NIO實(shí)現(xiàn)多人聊天室,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-11-11
  • Spring?Boot?+?MySQL讀寫分離實(shí)現(xiàn)方案全過程

    Spring?Boot?+?MySQL讀寫分離實(shí)現(xiàn)方案全過程

    讀寫分離是數(shù)據(jù)庫架構(gòu)中的一種優(yōu)化策略,它將讀操作和寫操作分開處理,通常通過將讀請(qǐng)求和寫請(qǐng)求分別發(fā)送到不同的數(shù)據(jù)庫服務(wù)器來實(shí)現(xiàn),這篇文章主要介紹了Spring?Boot?+?MySQL讀寫分離實(shí)現(xiàn)方案的相關(guān)資料,需要的朋友可以參考下
    2025-12-12

最新評(píng)論

南投市| 含山县| 南开区| 昌宁县| 会同县| 手游| 扎赉特旗| 白玉县| 武隆县| 大埔县| 花莲县| 普兰县| 日喀则市| 洛南县| 新乐市| 屏东市| 广汉市| 东源县| 鄄城县| 乐至县| 八宿县| 鄂州市| 龙川县| 太仓市| 科技| 县级市| 琼海市| 吕梁市| 泸州市| 准格尔旗| 天峻县| 威信县| 盱眙县| 长寿区| 定兴县| 崇阳县| 中方县| 睢宁县| 灵台县| 莱西市| 祁东县|