mybatis-plus?實(shí)現(xiàn)查詢表名動(dòng)態(tài)修改的示例代碼
通過(guò) mybatis-plus 實(shí)現(xiàn)表名的動(dòng)態(tài)替換,即通過(guò)配置或入?yún)?dòng)態(tài)選擇不同的表。
下面通過(guò)一個(gè)例子來(lái)說(shuō)明該需求: 我們需要為學(xué)校開(kāi)發(fā)一個(gè)成績(jī)管理系統(tǒng),需要建立三張表: 學(xué)生表、科目表和成績(jī)表,表的 ER 圖如下所示。
對(duì)應(yīng)的建表語(yǔ)句如下:
-- 學(xué)科表 drop table if exists subject; create table subject(id int primary key , name varchar(64)); -- 學(xué)生表 drop table if exists student; create table student (id int primary key , name varchar(64)); -- 成績(jī)表(學(xué)生-學(xué)科 多對(duì)多) drop table if exists score; create table score(id int primary key , student_id int, subject_id int, result int);
根據(jù)三張表級(jí)聯(lián)查詢成績(jī)的查詢語(yǔ)句為:
select subject.name as subject_name, student.name as student_name, score.result as score from score, student, subject where score.student_id=student.id and score.subject_id=subject.id;
現(xiàn)在又來(lái)了一個(gè)新需求,我們的這套成績(jī)查詢系統(tǒng)需要部署在不同學(xué)校的服務(wù)器上,因?yàn)槊總€(gè)學(xué)校的學(xué)生表和成績(jī)表都要同步到教育局的服務(wù)器中,因此需要為這兩個(gè)表添加學(xué)校前綴,ER 圖如下所示。
不同學(xué)校的建表語(yǔ)句不同,對(duì)于 USTC 學(xué)校而言,建表語(yǔ)句為:
-- 學(xué)科表 drop table if exists subject; create table subject(id int primary key , name varchar(64)); -- 學(xué)生表 drop table if exists ustc_student; create table ustc_student (id int primary key , name varchar(64)); -- 成績(jī)表(學(xué)生-學(xué)科 多對(duì)多) drop table if exists ustc_score; create table ustc_score(id int primary key , student_id int, subject_id int, result int);
對(duì)于 ZJU 學(xué)校而言,建表語(yǔ)句為:
-- 學(xué)科表 drop table if exists subject; create table subject(id int primary key , name varchar(64)); -- 學(xué)生表 drop table if exists zju_student; create table zju_student (id int primary key , name varchar(64)); -- 成績(jī)表(學(xué)生-學(xué)科 多對(duì)多) drop table if exists zju_score; create table zju_score(id int primary key , student_id int, subject_id int, result int);
我們的成績(jī)查詢系統(tǒng)會(huì)安裝在不同的學(xué)校,并且校名是動(dòng)態(tài)可配的,因此該成績(jī)查詢系統(tǒng)需要根據(jù)配置文件動(dòng)態(tài)修改 sql 語(yǔ)句表名的功能。
實(shí)現(xiàn)
源碼地址: https://github.com/foolishflyfox/blog/tree/main/backend-code/mp-dynamic-tablename
數(shù)據(jù)庫(kù)初始化
創(chuàng)建程序需要的表:
create database if not exists mp_dynamic_tablename_test; use mp_dynamic_tablename_test; -- 學(xué)科表 drop table if exists subject; create table subject(id int primary key , name varchar(64)); insert into subject(id, name) values (1, 'Math'), (2, 'English'), (3, 'Chinese'); -- 學(xué)生表 drop table if exists student; create table student (id int primary key , name varchar(64)); insert into student(id, name) values(1, 'aaa'), (2, 'bbb'); -- 成績(jī)表(學(xué)生-學(xué)科 多對(duì)多) drop table if exists score; create table score(id int primary key , student_id int, subject_id int, result int); insert into score(id, student_id, subject_id, result) values (1, 1, 1, 74), (2, 1, 2, 83), (3, 1, 3, 69), (4, 2, 1, 91), (5, 2, 3, 87); -- 指定前綴 ustc 的表 -- 學(xué)生表 drop table if exists ustc_student; create table ustc_student (id int primary key , name varchar(64)); insert into ustc_student(id, name) values(1, 'u_aaa'), (2, 'u_bbb'); -- 成績(jī)表(學(xué)生-學(xué)科 多對(duì)多) drop table if exists ustc_score; create table ustc_score(id int primary key , student_id int, subject_id int, result int); insert into ustc_score(id, student_id, subject_id, result) values (1, 1, 1, 89), (2, 1, 2, 81), (3, 1, 3, 32), (4, 2, 1, 71), (5, 2, 2, 77); -- 指定前綴 zju 的表 -- 學(xué)生表 drop table if exists zju_student; create table zju_student (id int primary key , name varchar(64)); insert into zju_student(id, name) values(5, 'z_aaa'), (6, 'z_bbb'); -- 成績(jī)表(學(xué)生-學(xué)科 多對(duì)多) drop table if exists zju_score; create table zju_score(id int primary key , student_id int, subject_id int, result int); insert into zju_score(id, student_id, subject_id, result) values (1, 5, 1, 91), (2, 5, 2, 66), (3, 5, 3, 85), (4, 6, 1, 48), (5, 6, 2, 59);
依賴包
需要引入 spring-boot-starter-web、spring-boot-starter-test、spring-boot-configuration-processor、mybatis-plus-boot-starter、mysql-connector-java、lombok 庫(kù)。
配置讀取類
我們先定義一個(gè)配置讀取類,用于獲取動(dòng)態(tài)配置的學(xué)校以及需要?jiǎng)討B(tài)添加學(xué)校前綴的表名。
package cn.fff.config.properties; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; import java.util.HashSet; import java.util.Set; @Component @ConfigurationProperties("school") @Data public class SchoolProperties { /** 學(xué)校名,動(dòng)態(tài)表名會(huì)添加前綴: 學(xué)校名_ */ private String name; /** 需要?jiǎng)討B(tài)添加前綴的表 */ private Set<String> dynamicTables = new HashSet<>(); }
為 application.yml 添加如下配置:
school: name: ustc dynamic-tables: - student - score
表示需要為 student
和 score
動(dòng)態(tài)添加前綴 ustc
,即查詢 student
表時(shí)會(huì)動(dòng)態(tài)替換為 ustc_student
,查詢 score
表時(shí)會(huì)動(dòng)態(tài)替換為 ustc_score
。如果 school.name
修改為 zju
,則查詢 student
表時(shí)會(huì)動(dòng)態(tài)替換為 zju_student
,查詢 score
表時(shí)會(huì)動(dòng)態(tài)替換為 zju_score
。
設(shè)置 mybatis-plus 插件
實(shí)體類、mapper、服務(wù)類的創(chuàng)建比較基礎(chǔ),此處略過(guò),可直接查看源碼。動(dòng)態(tài)表面主要通過(guò)創(chuàng)建一個(gè) mybatis 插件實(shí)現(xiàn):
package cn.fff.config.mp; import cn.fff.config.properties.SchoolProperties; import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.DynamicTableNameInnerInterceptor; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.util.StringUtils; @Configuration public class DynamicTableNameConfig { @Autowired private SchoolProperties schoolProperties; @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(dynamicTableNameInnerInterceptor()); return interceptor; } private DynamicTableNameInnerInterceptor dynamicTableNameInnerInterceptor() { DynamicTableNameInnerInterceptor innerInterceptor = new DynamicTableNameInnerInterceptor(); innerInterceptor.setTableNameHandler((sql, tableName) -> { String newTableName = tableName; // 配置了學(xué)校名并且當(dāng)前查詢的表名在指定配置中,則添加表名前綴 if (StringUtils.hasLength(schoolProperties.getName()) && schoolProperties.getDynamicTables().contains(tableName)) { newTableName = schoolProperties.getName() + "_" + tableName; } return newTableName; }); return innerInterceptor; } }
測(cè)試
在 test 中創(chuàng)建一個(gè)測(cè)試類 ScoreServiceTest
:
package cn.fff; import cn.fff.entity.StudentScore; import cn.fff.service.ScoreService; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import java.util.List; @SpringBootTest public class ScoreServiceTest { @Autowired private ScoreService scoreService; @Test public void testDynameTableName() { List<StudentScore> studentScores = scoreService.queryStudentScore(); studentScores.forEach(e -> System.out.printf("%s %s %d\n", e.getStudentName(), e.getSubjectName(), e.getScore())); } }
當(dāng) school.name
為 ustc 時(shí),輸出為:
u_aaa Math 89 u_aaa English 81 u_aaa Chinese 32 u_bbb Math 71 u_bbb English 77
當(dāng) school.name
為 zju 時(shí),輸出為:
z_aaa Math 91 z_aaa English 66 z_aaa Chinese 85 z_bbb Math 48 z_bbb English 59
這樣我們就實(shí)現(xiàn)了根據(jù)配置動(dòng)態(tài)切換操作表名的功能。
到此這篇關(guān)于mybatis-plus 實(shí)現(xiàn)查詢表名動(dòng)態(tài)修改的示例代碼的文章就介紹到這了,更多相關(guān)mybatis-plus 查詢表名動(dòng)態(tài)修改內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- mybatis plus動(dòng)態(tài)數(shù)據(jù)源切換及查詢過(guò)程淺析
- MybatisPlus實(shí)現(xiàn)分頁(yè)查詢和動(dòng)態(tài)SQL查詢的示例代碼
- MyBatis-Plus多表聯(lián)查的實(shí)現(xiàn)方法(動(dòng)態(tài)查詢和靜態(tài)查詢)
- Mybatis-plus動(dòng)態(tài)條件查詢QueryWrapper的使用案例
- MyBatis-Plus多表聯(lián)查(動(dòng)態(tài)查詢)的項(xiàng)目實(shí)踐
- MybatisPlus使用Mybatis的XML的動(dòng)態(tài)SQL的功能實(shí)現(xiàn)多表查詢
- mybatis-plus @select動(dòng)態(tài)查詢方式
相關(guān)文章
SpringBoot實(shí)現(xiàn)發(fā)送郵件任務(wù)
這篇文章主要為大家詳細(xì)介紹了SpringBoot實(shí)現(xiàn)發(fā)送郵件任務(wù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-02-02Java刪除ArrayList中的重復(fù)元素的兩種方法
在Java編程中,ArrayList是一種常用的集合類,它允許我們存儲(chǔ)一組元素,在某些情況下,我們可能需要移除其中重復(fù)的元素,只保留唯一的元素,下面介紹兩種常見(jiàn)的刪除ArrayList中重復(fù)元素的方法,需要的朋友可以參考下2024-12-12微服務(wù)?Spring?Boot?整合?Redis?BitMap?實(shí)現(xiàn)?簽到與統(tǒng)計(jì)功能
這篇文章主要介紹了微服務(wù)?Spring?Boot?整合?Redis?BitMap?實(shí)現(xiàn)?簽到與統(tǒng)計(jì)功能,文章簡(jiǎn)單介紹了Redis BitMap 基本用法結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-01-01Springboot+Bootstrap實(shí)現(xiàn)增刪改查實(shí)戰(zhàn)
這篇文章主要介紹了Springboot+Bootstrap實(shí)現(xiàn)增刪改查實(shí)戰(zhàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12Java volatile關(guān)鍵字原理剖析與實(shí)例講解
volatile是Java提供的一種輕量級(jí)的同步機(jī)制,Java?語(yǔ)言包含兩種內(nèi)在的同步機(jī)制:同步塊(或方法)和?volatile?變量,本文將詳細(xì)為大家總結(jié)Java volatile關(guān)鍵字,通過(guò)詳細(xì)的代碼示例給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-07-07spring-boot-maven-plugin?配置有啥用
這篇文章主要介紹了spring-boot-maven-plugin?配置是干啥的,這個(gè)是SpringBoot的Maven插件,主要用來(lái)打包的,通常打包成jar或者war文件,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-08-08Mybatis-plus 批量插入太慢的問(wèn)題解決(提升插入性能)
公司使用的Mybatis-Plus操作SQL,用過(guò)Mybatis-Plus的小伙伴一定知道他有很多API提供給我們使用,但是批量插入大數(shù)據(jù)太慢應(yīng)該怎么解決,本文就詳細(xì)的介紹一下,感興趣的可以了解一下2021-11-11