欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

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

@Intercepts

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

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

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

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

args屬性表示攔截的方法對應(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)用到自動分表中。本文的表名的索引是通過注解參數(shù)傳遞的,實(shí)際應(yīng)用中需要通過哈希散列計(jì)算。

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

相關(guān)文章

  • 基于jenkins構(gòu)建結(jié)果企業(yè)微信提醒

    基于jenkins構(gòu)建結(jié)果企業(yè)微信提醒

    這篇文章主要介紹了基于jenkins構(gòu)建結(jié)果企業(yè)微信提醒,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-08-08
  • Spring中的FactoryBean實(shí)現(xiàn)原理詳解

    Spring中的FactoryBean實(shí)現(xiàn)原理詳解

    這篇文章主要介紹了Spring中的FactoryBean實(shí)現(xiàn)原理詳解,spring中有兩種類型的Bean,一種是普通的JavaBean,另一種就是工廠Bean(FactoryBean),這兩種Bean都受Spring的IoC容器管理,但它們之間卻有一些區(qū)別,需要的朋友可以參考下
    2024-02-02
  • vue+springboot讀取git的markdown文件并展示功能

    vue+springboot讀取git的markdown文件并展示功能

    Markdown-it 是一個用于解析和渲染 Markdown 標(biāo)記語言的 JavaScript 庫,使用 Markdown-it,你可以將 Markdown 文本解析為 HTML 輸出,并且可以根據(jù)需要添加功能、擴(kuò)展語法或修改解析行為,本文介紹vue+springboot讀取git的markdown文件并展示,感興趣的朋友一起看看吧
    2024-01-01
  • Java多線程中Lock的使用小結(jié)

    Java多線程中Lock的使用小結(jié)

    jdk1.5 以后,提供了各種鎖,本文主要介紹了Java多線程中Lock的使用小結(jié),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • Java替換int數(shù)組中重復(fù)數(shù)據(jù)的方法示例

    Java替換int數(shù)組中重復(fù)數(shù)據(jù)的方法示例

    這篇文章主要介紹了Java替換int數(shù)組中重復(fù)數(shù)據(jù)的方法,涉及java針對數(shù)組的遍歷、轉(zhuǎn)換、判斷等相關(guān)操作技巧,需要的朋友可以參考下
    2017-06-06
  • 基于EasyExcel實(shí)現(xiàn)百萬級數(shù)據(jù)導(dǎo)入導(dǎo)出詳解

    基于EasyExcel實(shí)現(xiàn)百萬級數(shù)據(jù)導(dǎo)入導(dǎo)出詳解

    大數(shù)據(jù)的導(dǎo)入和導(dǎo)出,相信大家在日常的開發(fā)、面試中都會遇到。本文將為大家詳細(xì)介紹一下如何利用EasyExcel實(shí)現(xiàn)百萬級數(shù)據(jù)導(dǎo)入導(dǎo)出,需要的可以參考一下
    2023-01-01
  • Spring中的retry重試組件詳解

    Spring中的retry重試組件詳解

    這篇文章主要介紹了Spring中的retry重試組件詳解,Retry重試組件是一個處理重試邏輯的工具,可以在出現(xiàn)異?;蚴∏闆r下自動進(jìn)行重試操作,從而提高程序的穩(wěn)定性和可靠性,需要的朋友可以參考下
    2023-10-10
  • JAVA使用hutool工具實(shí)現(xiàn)查詢樹結(jié)構(gòu)數(shù)據(jù)(省市區(qū))

    JAVA使用hutool工具實(shí)現(xiàn)查詢樹結(jié)構(gòu)數(shù)據(jù)(省市區(qū))

    今天通過本文給大家分享JAVA使用hutool工具實(shí)現(xiàn)查詢樹結(jié)構(gòu)數(shù)據(jù)(省市區(qū)),代碼分為表結(jié)構(gòu)和數(shù)據(jù)結(jié)構(gòu),代碼簡單易懂,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友參考下吧
    2021-08-08
  • java中的Struts2攔截器詳解

    java中的Struts2攔截器詳解

    本篇文章主要介紹了java中的Struts2攔截器淺解,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-03-03
  • Java利用SpEL表達(dá)式實(shí)現(xiàn)權(quán)限校驗(yàn)

    Java利用SpEL表達(dá)式實(shí)現(xiàn)權(quán)限校驗(yàn)

    這篇文章主要為大家詳細(xì)介紹了Java如何利用SpEL表達(dá)式實(shí)現(xiàn)權(quán)限校驗(yàn)功能,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-01-01

最新評論