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

Mybatis-Plus動態(tài)表名的實(shí)現(xiàn)示例

 更新時間:2024年07月10日 11:34:24   作者:Aiir  
面對復(fù)雜多變的業(yè)務(wù)需求,動態(tài)表名的處理變得愈發(fā)重要,本文主要介紹了Mybatis-Plus動態(tài)表名的實(shí)現(xiàn)示例,具有一定的參考價值,感興趣的可以了解一下

前言

在某些情況下,需要將大量數(shù)據(jù)分散到多個數(shù)據(jù)表中,這樣可以提高數(shù)據(jù)庫的查詢效率和數(shù)據(jù)處理能力。按天分表就是一種常見的數(shù)據(jù)分表策略,它將每天的數(shù)據(jù)放到一個獨(dú)立的數(shù)據(jù)表中,可以方便地進(jìn)行數(shù)據(jù)查詢和備份。但是,為了實(shí)現(xiàn)按天分表需要動態(tài)表名的支持,即在創(chuàng)建表時根據(jù)當(dāng)前日期自動生成表名。這樣可以確保每天數(shù)據(jù)都存放在不同的表中,避免數(shù)據(jù)重復(fù)或覆蓋的情況。同時,動態(tài)表名還可以幫助開發(fā)人員更方便地管理數(shù)據(jù),例如刪除過期數(shù)據(jù)表等。因此,使用動態(tài)表名是按天分表的必要條件之一。

例如:t_user_20230901、t_user_20230902、t_user_20230903…

一、方案一(動態(tài)傳參)

使用方法(Mapper自定義SQL)

坐標(biāo)依賴

<dependency>
	<groupId>com.baomidou</groupId>
	<artifactId>mybatis-plus-boot-starter</artifactId>
	<version>3.5.1</version>
</dependency>
<dependency>
	<groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
	<version>8.0.28</version>
</dependency>

數(shù)據(jù)源配置

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/db1?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai&useSSL=false
    username: root
    password: 123456
    driver-class-name: com.mysql.cj.jdbc.Driver

實(shí)體類

@Data
@TableName("t_user")
public class User {
    @TableId(type = IdType.AUTO)
    private Integer id;
    @TableField("name")
    private String name;
}

這里的@TableName("t_user")映射表名不需要帶上日期后綴

Mapper

@Mapper
public interface UserMapper extends BaseMapper<User> {
	// 方法1
	@Select("Select * from ${tableName}")
	List<User> getUserInfo(@Param("tableName") String tableName);
	// 方法2
	List<User> getUserInfoMP(String tableName);
}

MapperXML

<?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="com.xx.xx.mapper.UserMapper">
 <select id="getUserInfoMP" resultType="com.xx.xx.entity.User" >
        select * from ${tableName} order by phone_number ASC
 </select>
</mapper>

具體使用

@Service
public class UserServiceImpl implements UserService {

	@Autowired
    private UserMapper userMapper;
	
	void query(){
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        String rDay = LocalDateTime.now().format(formatter);
		String tableName = "t_user_" + rDay;
		
		List<User> list1 = userMapper.getUserInfo(tableName);
		List<User> list2 = userMapper.getUserInfoMP(tableName);
	}

}

二、方案二(DynamicTableNameInnerInterceptor插件)

使用方法(插件配置+ThreadLocal+輔助類)

配置類

@Configuration
@MapperScan(basePackages = {"com.xx.**.mapper"})
public class MybatisPlusConfig {

    public MybatisPlusInterceptor mybatisPlusInterceptor(){
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        //動態(tài)表名
        DynamicTableNameInnerInterceptor dynamicTableNameInnerInterceptor = new DynamicTableNameInnerInterceptor();
        //可以傳多個表名參數(shù),指定哪些表使用DayTableNameHandler處理表名稱
        dynamicTableNameInnerInterceptor.setTableNameHandler(new DayTableNameHandler("t_user"));
		//以攔截器的方式處理表名稱
		//可以傳遞多個攔截器,即:可以傳遞多個表名處理器TableNameHandler
        mybatisPlusInterceptor.addInnerInterceptor(dynamicTableNameInnerInterceptor);
        return mybatisPlusInterceptor;
    }
}

輔助類

/**
 * 按天參數(shù),組成動態(tài)表名
 */
public class DayTableNameHandler implements TableNameHandler {
    //用于記錄哪些表可以使用該動態(tài)表名處理器(即哪些表需要分表)
    private List<String> tableNames;
    //構(gòu)造函數(shù),構(gòu)造動態(tài)表名處理器的時候,傳遞tableNames參數(shù)
    public DayTableNameHandler(String ...tableNames) {
        this.tableNames = Arrays.asList(tableNames);
    }
    //每個請求線程維護(hù)一個day數(shù)據(jù),避免多線程數(shù)據(jù)沖突。所以使用ThreadLocal
    private static final ThreadLocal<String> DAY_DATA = new ThreadLocal<>();
    //設(shè)置請求線程的day數(shù)據(jù)
    public static void setData(String day) {
        DAY_DATA.set(day);
    }
    //刪除當(dāng)前請求線程的day數(shù)據(jù)
    public static void removeData() {
        DAY_DATA.remove();
    }
    //動態(tài)表名接口實(shí)現(xiàn)方法
    @Override
    public String dynamicTableName(String sql, String tableName) {
        if (this.tableNames.contains(tableName)){
            return tableName + "_" + DAY_DATA.get();  //表名增加后綴
        }else{
            return tableName;   //表名原樣返回
        }
    }
}

具體使用

@Service
public class UserServiceImpl implements UserService {

	@Autowired
    private UserService userService;
	
	void query(){
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        String rDay = LocalDateTime.now().format(formatter);
        DayTableNameHandler.setData(rDay);
        List<User> list = userService.list();
        // 用完即銷毀
        DayTableNameHandler.removeData();
	}
}

這里可以自行打印SQL語句驗(yàn)證 Select * from t_user_20230909

三、方案三(DynamicTableNameInnerInterceptor插件、省略輔助類)

這里可以直接配置DynamicTableNameInnerInterceptor插件做簡單的使用,但是用法相對固定,不能根據(jù)實(shí)際情況控制實(shí)體類所映射的表名,原因是被統(tǒng)一攔截

使用方法(插件配置+ThreadLocal)

配置類

@Configuration
@MapperScan(basePackages = {"com.xx.**.mapper"})
public class MybatisPlusConfig {

	public static ThreadLocal<String> myTableName = new ThreadLocal<>();

    public MybatisPlusInterceptor mybatisPlusInterceptor(){
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        //動態(tài)表名
        DynamicTableNameInnerInterceptor dynamicTableNameInnerInterceptor = new DynamicTableNameInnerInterceptor();
        HashMap<String, TableNameHandler> map = new HashMap<String, TableNameHandler>(2) {{
            put("t_user", (sql, tableName) -> {
                return myTableName.get();
            });
        }};
        dynamicTableNameInnerInterceptor.setTableNameHandlerMap(map);
        mybatisPlusInterceptor.addInnerInterceptor(dynamicTableNameInnerInterceptor);
		myTableName.remove();

        return mybatisPlusInterceptor;
    }
}

具體使用

@Service
public class UserServiceImpl implements UserService {

	@Autowired
    private UserService userService;
	
	void query(){
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        String rDay = LocalDateTime.now().format(formatter);
        DayTableNameHandler.setData(rDay);
        String tableName = "t_user" + rDay;
        MybatisPlusConfig.myTableName.set(tableName);
        List<User> list = userService.list();        
	}
}

總結(jié)

三種方法可以結(jié)合實(shí)際需要選擇,使用Mapper自定義SQL要注意SQL注入,使用線程池的方式要記得清理。

注意

Threadlocal 中的數(shù)據(jù)在AOP中最好自己釋放掉 ,spring是用的線程池,如果不清理掉會影響線程下次使用的程序。

到此這篇關(guān)于Mybatis-Plus動態(tài)表名的實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)Mybatis-Plus 動態(tài)表名內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring Boot 使用 Swagger 構(gòu)建 RestAPI 接口文檔

    Spring Boot 使用 Swagger 構(gòu)建 RestAPI 接口文檔

    這篇文章主要介紹了Spring Boot 使用 Swagger 構(gòu)建 RestAPI 接口文檔,幫助大家更好的理解和使用Spring Boot框架,感興趣的朋友可以了解下
    2020-10-10
  • JDK15正式發(fā)布(新增功能預(yù)覽)

    JDK15正式發(fā)布(新增功能預(yù)覽)

    這篇文章主要介紹了JDK15正式發(fā)布,新增功能預(yù)覽,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2020-09-09
  • 命令行中 javac、java、javap 的使用小結(jié)

    命令行中 javac、java、javap 的使用小結(jié)

    使用 java 命令運(yùn)行一個.class文件,需要使用該類的全限定類名,同時需要在當(dāng)前路徑下有該類的包層次文件夾,這篇文章主要介紹了命令行中 javac、java、javap 的使用小結(jié),需要的朋友可以參考下
    2023-07-07
  • Java 高精度的大數(shù)字運(yùn)算方式

    Java 高精度的大數(shù)字運(yùn)算方式

    這篇文章主要介紹了Java 高精度的大數(shù)字運(yùn)算方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Java設(shè)計(jì)模式之橋模式(Bridge模式)介紹

    Java設(shè)計(jì)模式之橋模式(Bridge模式)介紹

    這篇文章主要介紹了Java設(shè)計(jì)模式之橋模式(Bridge模式)介紹,本文講解了為什么使用橋模式、如何實(shí)現(xiàn)橋模式、Bridge模式在EJB中的應(yīng)用等內(nèi)容,需要的朋友可以參考下
    2015-03-03
  • 公共POI導(dǎo)出Excel方法詳解

    公共POI導(dǎo)出Excel方法詳解

    這篇文章主要介紹了公共POI導(dǎo)出Excel方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • SpringBoot從2.7.x 升級到3.3注意事項(xiàng)

    SpringBoot從2.7.x 升級到3.3注意事項(xiàng)

    從SpringBoot 2.7.x升級到3.3涉及多個重要變更,特別是因?yàn)?nbsp;Spring Boot 3.x 系列基于 Jakarta EE 9,而不再使用 Java EE,本文就來詳細(xì)的介紹一下,感興趣的可以了解一下
    2024-09-09
  • SWT(JFace) Menu、Bar...體驗(yàn)代碼

    SWT(JFace) Menu、Bar...體驗(yàn)代碼

    SWT(JFace)體驗(yàn)之Menu、Bar實(shí)現(xiàn)代碼。
    2009-06-06
  • 詳解spring與shiro集成

    詳解spring與shiro集成

    這篇文章主要介紹了詳解spring與shiro集成,需要的朋友可以參考下
    2017-09-09
  • 處理java異步事件的阻塞和非阻塞方法分析

    處理java異步事件的阻塞和非阻塞方法分析

    這篇文章主要介紹了處理java異步事件的阻塞和非阻塞方法分析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,阻塞與非阻塞關(guān)注的是交互雙方是否可以彈性工作。,需要的朋友可以參考下
    2019-06-06

最新評論