0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

MyBatis-Plus為什么不支持聯(lián)表

汽車電子技術(shù) ? 來源:一行Java ? 作者:一航 ? 2023-02-28 15:19 ? 次閱讀

圖片

大家好,我是一航!

早前,寫過 MyBatis-Plus 的詳細(xì)使用],很多鐵子看了之后,也紛紛用起來了,得到的反饋基本都是:真香!但也時不時的有人會來問,這 MyBatis-Plus 不支持聯(lián)表 ,遇到復(fù)雜查詢依然還是麻煩,怎么辦?其實(shí)我在詳細(xì)的使用教程里面就已經(jīng)說到聯(lián)表解決方案,可能由于文章比較的長,方案又寫的比較的靠后,很多朋友沒留意到,這里就單獨(dú)擰出來說一下;

MyBatis-Plus 要想實(shí)現(xiàn)聯(lián)表查詢,只需要引入一個依賴mybatis-plus-join,就能完美解決;

準(zhǔn)備

本文,需要你對 MyBatis-Plus 有一定的了解,如果之前一直沒有使用過,可以先看一下這邊文章:MyBatis Plus + 兩款神器,徹底解放雙手

“示例源碼地址:https://github.com/vehang/ehang-spring-boot/tree/main/spring-boot-010-mysql-mybatis-plus (

聯(lián)表查詢所有測試用例全部在Test目錄下)

MyBatis Plus Join

MyBatis Plus Join一款專門解決MyBatis Plus 關(guān)聯(lián)查詢問題的擴(kuò)展框架,他并不一款全新的框架,而是基于MyBatis Plus功能的增強(qiáng),所以MyBatis Plus的所有功能MyBatis Plus Join同樣擁有;框架的使用方式和MyBatis Plus一樣簡單,幾行代碼就能實(shí)現(xiàn)聯(lián)表查詢的功能

“官方倉庫:https://gitee.com/best_handsome/mybatis-plus-join

依賴

  • mybatis
    <dependency>
        <groupId>com.baomidou<span class="hljs-name"groupId>
        <artifactId>mybatis-plus-boot-starter<span class="hljs-name"artifactId>
        <version>3.4.3.4<span class="hljs-name"version>
    <span class="hljs-name"dependency>
    
  • 數(shù)據(jù)庫連接依賴;
    大版本務(wù)必和自己的數(shù)據(jù)庫版本一致
    <dependency>
        <groupId>mysql<span class="hljs-name"groupId>
        <artifactId>mysql-connector-java<span class="hljs-name"artifactId>
        <version>5.1.46<span class="hljs-name"version>
    <span class="hljs-name"dependency>
    
  • 分頁
    <dependency>
        <groupId>com.baomidou<span class="hljs-name"groupId>
        <artifactId>mybatis-plus-extension<span class="hljs-name"artifactId>
        <version>3.4.1<span class="hljs-name"version>
    <span class="hljs-name"dependency>
    
  • 聯(lián)表查詢
    <dependency>
        <groupId>com.github.yulichang<span class="hljs-name"groupId>
        <artifactId>mybatis-plus-join<span class="hljs-name"artifactId>
        <version>1.3.11<span class="hljs-name"version>
    <span class="hljs-name"dependency>
    

數(shù)據(jù)庫表

為了方便做聯(lián)表測試,這里預(yù)先準(zhǔn)備三張表(學(xué)校表、班級表、學(xué)生表),用來做關(guān)聯(lián)查詢測試,sql如下:

DROP TABLE IF EXISTS `school_info`;
CREATE TABLE `school_info`  (
  `id` int(11) NOT NULL,
  `school_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '學(xué)校名稱',
  `school_addr` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '學(xué)校地址',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

INSERT INTO `school_info` VALUES (1, 'XXX小學(xué)', 'xx區(qū)xx街道80號');

-  ----------------------------------------------------------------

CREATE TABLE `class_info`  (
  `id` int(11) NOT NULL,
  `class_name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '名稱',
  `class_desc` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '描述',
  `school_id` int(11) NOT NULL COMMENT '隸屬的學(xué)校',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

INSERT INTO `class_info` VALUES (1, '一年級1班', NULL, 1);
INSERT INTO `class_info` VALUES (2, '一年級2班', NULL, 1);

-  ----------------------------------------------------------------

CREATE TABLE `student_info`  (
  `id` int(11) NOT NULL,
  `name` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `age` int(11) NULL DEFAULT NULL,
  `class_id` int(11) NULL DEFAULT NULL,
  `school_id` int(11) NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;

INSERT INTO `student_info` VALUES (1, '張三', 7, 1, 1);
INSERT INTO `student_info` VALUES (2, '李四', 7, 2, 1);
INSERT INTO `student_info` VALUES (3, '王五', 8, 1, 1);
INSERT INTO `student_info` VALUES (4, '趙六', 8, 1, 1);

基礎(chǔ) MyBatis Plus 代碼生成

以下的代碼通過 MyBatisX 工具自動生成;可參考 MyBatisX 的插件的使用說明,這里就不再重復(fù)了

圖片

MyBatis Plus Join 核心類說明

  • MPJBaseMapper
    擴(kuò)展了MyBatis Plus的 BaseMapper 接口
    public interface MPJBaseMapper<T> extends BaseMapper<T> {
        Integer selectJoinCount(@Param("ew") MPJBaseJoin var1);
    
        <DTO> DTO selectJoinOne(@Param("resultTypeClass_Eg1sG") Class<DTO> var1, @Param("ew") MPJBaseJoin var2);
    
        Map<String, Object> selectJoinMap(@Param("ew") MPJBaseJoin var1);
    
        <DTO> List<DTO> selectJoinList(@Param("resultTypeClass_Eg1sG") Class<DTO> var1, @Param("ew") MPJBaseJoin var2);
    
        List<Map<String, Object>> selectJoinMaps(@Param("ew") MPJBaseJoin var1);
    
        <DTO, P extends IPage?> IPage<DTO> selectJoinPage(P var1, @Param("resultTypeClass_Eg1sG") Class<DTO> var2, @Param("ew") MPJBaseJoin var3);
    
        <P extends IPage?> IPage<Map<String, Object>> selectJoinMapsPage(P var1, @Param("ew") MPJBaseJoin var2);
    }
    
  • MPJBaseService
    擴(kuò)展了MyBatis Plus的 IService 接口
    public interface MPJBaseService<T> extends IService<T> {
        Integer selectJoinCount(MPJBaseJoin var1);
    
        <DTO> DTO selectJoinOne(Class<DTO> var1, MPJBaseJoin var2);
    
        <DTO> List<DTO> selectJoinList(Class<DTO> var1, MPJBaseJoin var2);
    
        <DTO, P extends IPage?> IPage<DTO> selectJoinListPage(P var1, Class<DTO> var2, MPJBaseJoin var3);
    
        Map<String, Object> selectJoinMap(MPJBaseJoin var1);
    
        List<Map<String, Object>> selectJoinMaps(MPJBaseJoin var1);
    
        <P extends IPage<Map<String, Object>>> IPage<Map<String, Object>> selectJoinMapsPage(P var1, MPJBaseJoin var2);
    }
    
  • MPJBaseServiceImpl
    擴(kuò)展了MyBatis Plus的 ServiceImpl 接口實(shí)現(xiàn)
    public class MPJBaseServiceImpl<M extends MPJBaseMapper<T>, T> extends ServiceImpl<M, T> implements MPJBaseService<T> {
    ...
    }
    

整合 MyBatis Plus Join

簡單的三處調(diào)整,就能完成整合工作

  • 將mapper改為繼承MPJBaseMapper (必選)
    修改前

    public interface StudentInfoMapper extends BaseMapper<StudentInfo> {
    }
    

    修改后

    public interface StudentInfoMapper extends MPJBaseMapper<StudentInfo> {
    }
    
  • 將service改為繼承MPJBaseService (可選)
    修改前

    public interface StudentInfoService extends BaseService<StudentInfo> {
    }
    

    修改后

    public interface StudentInfoService extends MPJBaseService<StudentInfo> {
    }
    
  • 將serviceImpl改為繼承MPJBaseServiceImpl (可選)
    修改前

    @Service
    public class StudentInfoServiceImpl extends BaseServiceImpl<StudentInfoMapper, StudentInfo>
        implements StudentInfoService{
    }
    

    修改后

    @Service
    public class StudentInfoServiceImpl extends MPJBaseServiceImpl<StudentInfoMapper, StudentInfo>
        implements StudentInfoService{
    }
    

聯(lián)表測試

測試需求:查詢學(xué)生所處的班級及學(xué)校

DTO定義

用于聯(lián)表查詢后接收數(shù)據(jù)的實(shí)體類

@Data
public class StudentInfoDTO {
 // 學(xué)生id
    private Integer id;

    // 性名
    private String name;

    // 年齡
    private Integer age;

    // 班級名稱
    private String className;

    // 學(xué)校名稱
    private String schoolName;

    // 學(xué)校地址 用于測試別名
    private String scAddr;
}

單記錄聯(lián)表查詢

@Autowired
StudentInfoService sutdentInfoService;

/**
 * 聯(lián)表查詢單個
 */
@Test
public void selectJoinOne() {
    StudentInfoDTO studentInfoDTO = sutdentInfoService.selectJoinOne(StudentInfoDTO.class,
            new MPJLambdaWrapper

簡單說明

  • StudentInfoDTO.class
    表示resultType,用于接收聯(lián)表查詢之后的數(shù)據(jù)庫返回;

    “當(dāng)返回是多個表數(shù)據(jù)的整合,需要新定義一個對象用于接收;

    當(dāng)返回只需要用到一個表的數(shù)據(jù),直接用數(shù)據(jù)庫映射對象接收即可;

  • selectAll
    指明查詢實(shí)體對應(yīng)的所有字段
  • select
    指定查詢列,同一個select只能指明單個表的列,所以多表關(guān)聯(lián)時需要使用多個select去指明不同表的列
  • selectAs
    重命名,表現(xiàn)在sql層面是會給字段加上as(別名);主要用在數(shù)據(jù)庫字段名也實(shí)體對象的名稱不一致的情況;
  • leftJoin、rightJoin、innerJoin
    左鏈接、右連接、等值連接;不懂這三種連接方式的,可參考:SQL中 inner join、left join、right join、full join 到底怎么選?詳解來了
    • 參數(shù)一:參與聯(lián)表的對象
    • 參數(shù)二:on關(guān)聯(lián)的指定,此屬性必須是第一個對象中的值
    • 參數(shù)三:參與聯(lián)表on的另一個實(shí)體類屬性
  • 條件構(gòu)造器
    聯(lián)表后可能會存在各種篩選條件,可以根據(jù)上面對條件構(gòu)造器的介紹,指明所需要的篩選條件,比如上面.eq(StudentInfo::getId, 1)),就是用來指明ID為1的學(xué)生信息。
  • 表名
    默認(rèn)主表別名是t,其他的表別名以先后調(diào)用的順序使用 t1,t2,t3.... ;
    需要直接apply語句的時候,就得知道對應(yīng)的表名是什么,再進(jìn)行添加,所以不到萬不得已的時候,不建議直接追加語句。

等價SQL

SELECT 
 t.id,
 t.name,
 t.age,
 t.class_id,
 t.school_id,
 t1.school_name,
 t1.school_addr AS scAddr,
 t2.class_name
FROM 
 student_info t
 LEFT JOIN school_info t1 ON (t1.id = t.school_id)
 LEFT JOIN class_info t2 ON (t2.id = t.class_id)
WHERE (t.id = ?)

執(zhí)行結(jié)果

圖片

多記錄聯(lián)表查詢

@Autowired
StudentInfoService sutdentInfoService;

/**
 * 聯(lián)表查詢批量
 */
@Test
public void selectJoinList() {
    List

等價SQL

SELECT 
 t.id,
 t.name,
 t.age,
 t.class_id,
 t.school_id,
 t1.school_name,
 t1.school_addr AS scAddr,
 t2.class_name
FROM 
 student_info t
 LEFT JOIN school_info t1 ON (t1.id = t.school_id)
 LEFT JOIN class_info t2 ON (t2.id = t.class_id)

執(zhí)行結(jié)果

圖片

聯(lián)表分頁查詢

@Autowired
StudentInfoService sutdentInfoService;

/**
 * 分頁查詢
 */
@Test
public void selectJoinPage() {
    IPage

等價SQL

SELECT 
 t.id,
 t.name,
 t.age,
 t.class_id,
 t.school_id,
 t1.school_name,
 t1.school_addr AS scAddr,
 t2.class_name
FROM 
 student_info t
 LEFT JOIN school_info t1 ON (t1.id = t.school_id)
 LEFT JOIN class_info t2 ON (t2.id = t.class_id)
ORDER BY 
 t.id ASC 
LIMIT 2

執(zhí)行結(jié)果

圖片

總結(jié)

是不是簡單、方便、好用!

一個依賴,就讓 MyBatis-Plus 擁有聯(lián)表操作,再也不用寫那些繁瑣的xml;不過 MyBatis Plus Join 要求 MyBatis Plus 的版本必須大于等于3.4.0,我在初次整合的時候,確實(shí)就遇到了各種兼容問題,處理了好久,但解決之后,使用起來就變的非常舒服;所以當(dāng)你在決定使用他之前,可以先找一個不太重要的項(xiàng)目,將一些兼容問題先摸索一遍,驗(yàn)證一下方案可行性之后,再進(jìn)一步整合。作者的技術(shù)交流群也比較的活躍,只要有問題,都會給予解答,非常值得一試!

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • 框架
    +關(guān)注

    關(guān)注

    0

    文章

    398

    瀏覽量

    17404
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4722

    瀏覽量

    68230
  • mybatis
    +關(guān)注

    關(guān)注

    0

    文章

    58

    瀏覽量

    6695
收藏 人收藏

    評論

    相關(guān)推薦

    不支持的BIOS?

    PCIe NVMe(M鍵),它支持上面的UEFI啟動和英特爾RST15.5 ..但是當(dāng)我安裝optane時,它在intel optane app ver 16.x上說“不支持的BIOS或BIOS設(shè)置
    發(fā)表于 10-25 14:58

    不支持器件的問題

    我裝了Quartus11.0,裝了器件庫,然后破解了Quartus??墒蔷幾g工程,提示破解文件不支持器件。這應(yīng)該如何解決?謝謝!
    發(fā)表于 03-19 14:26

    MCUXpresso不支持Clocks工具嗎?

    Pins工具可以使用,但不支持Clocks工具(它被標(biāo)記為 v11.0)。 能否分享描述此功能何時可用的路線圖?
    發(fā)表于 05-31 08:54

    蘋果iPad不支持繁體中文

    蘋果iPad不支持繁體中文     北京時間1月29日消息,美國蘋果計(jì)算機(jī)推出的iPad不支持繁體中文,蘋果臺灣官方表示:要等
    發(fā)表于 01-30 09:50 ?1079次閱讀

    小米手表為什么到現(xiàn)在還不支持iOS系統(tǒng)

    小米手表雙11就開售了,不過50天都過去了,卻依然不支持iOS系統(tǒng),這究竟是什么原因呢?
    發(fā)表于 01-02 14:17 ?5399次閱讀

    一篇讓你熟練掌握 MyBatis-Plus!

    MyBatis-plus 是一款 Mybatis 增強(qiáng)工具,用于簡化開發(fā),提高效率。下文使用縮寫 mp來簡化表示 MyBatis-plus,本文主要介紹 mp 搭配 Spring Boot
    的頭像 發(fā)表于 06-01 09:30 ?2561次閱讀
    一篇讓你熟練掌握 <b class='flag-5'>MyBatis-Plus</b>!

    openharmony不支持安卓嗎

    前面議論紛紛的鴻蒙是安卓套殼時代話題結(jié)束了,現(xiàn)在,openharmony 支不支持安卓系統(tǒng)的話題又出現(xiàn)了?那么,openharmony 到底支不支持安卓系統(tǒng)呢?
    的頭像 發(fā)表于 06-23 09:43 ?2050次閱讀

    華為p50為什么不支持5g

    華為p50為什么不支持5g?這是近日廣大網(wǎng)友用戶吐槽的一個問題,華為已經(jīng)于近日正式發(fā)布了華為p50系列,并將全面支持鴻蒙2.0系統(tǒng),但是為什么卻不支持5G呢?
    的頭像 發(fā)表于 08-01 09:12 ?6.9w次閱讀

    Mybatis-Plus Mybatis增強(qiáng)工具包

    ./oschina_soft/gitee-mybatis-plus.zip
    發(fā)表于 06-13 11:34 ?1次下載
    <b class='flag-5'>Mybatis-Plus</b> <b class='flag-5'>Mybatis</b>增強(qiáng)工具包

    MyBatis-Plus的使用與測試

    本文主要介紹mybatis-plus這款插件,針對springboot用戶。包括引入,配置,使用,以及擴(kuò)展等常用的方面做一個匯總整理,盡量包含大家常用的場景內(nèi)容。
    的頭像 發(fā)表于 08-22 11:56 ?1270次閱讀

    Questa Sim不支持-novopt問題

    在仿真中為防止信號被優(yōu)化,會在modelsim仿真的do文件中使用vsim -novopt項(xiàng),但是Questa Sim已經(jīng)不支持,并會提示以下信息。所以要觀察信號第一步先要解決該問題。
    的頭像 發(fā)表于 12-23 10:34 ?5098次閱讀
    Questa Sim<b class='flag-5'>不支持</b>-novopt問題

    介紹一款基于Mybatis-Plus的代碼自助生成器

    在基于Mybatis的開發(fā)模式中,很多開發(fā)者還會選擇Mybatis-Plus來輔助功能開發(fā),以此提高開發(fā)的效率。
    的頭像 發(fā)表于 05-23 14:16 ?1117次閱讀
    介紹一款基于<b class='flag-5'>Mybatis-Plus</b>的代碼自助生成器

    如何調(diào)優(yōu)MyBatis 25倍性能

    最近在壓測一批接口,發(fā)現(xiàn)接口處理速度慢的有點(diǎn)超出預(yù)期,感覺很奇怪,后面定位發(fā)現(xiàn)是數(shù)據(jù)庫批量保存這塊很慢。 這個項(xiàng)目用的是 mybatis-plus,批量保存直接用的是 mybatis-plus 提供的 saveBatch。 我點(diǎn)進(jìn)去看了下源碼,感覺有點(diǎn)不太對勁
    的頭像 發(fā)表于 05-30 09:56 ?565次閱讀
    如何調(diào)優(yōu)<b class='flag-5'>MyBatis</b> 25倍性能

    你還在手寫join聯(lián)查詢?MyBatis-Plus這樣寫太香了!

    眾所周知,mybatis plus 封裝的 mapper 不支持 join,如果需要支持就必須自己去實(shí)現(xiàn)。但是對于大部分的業(yè)務(wù)場景來說,都需要多表 join,要不然就沒必要采用關(guān)系型數(shù)
    的頭像 發(fā)表于 07-07 10:19 ?2414次閱讀
    你還在手寫join<b class='flag-5'>聯(lián)</b><b class='flag-5'>表</b>查詢?<b class='flag-5'>MyBatis-Plus</b>這樣寫太香了!

    為什么RS485不支持任意拓?fù)?/a>

    RS485不支持任意拓?fù)?,因?yàn)槿我馔負(fù)湓诜种帟a(chǎn)生大量的駐波和反射。這是由于阻抗不連續(xù)所造成的。
    的頭像 發(fā)表于 10-27 11:47 ?869次閱讀
    為什么RS485<b class='flag-5'>不支持</b>任意拓?fù)? />    </a>
</div>                </div>            </div><!-- .main-wrap -->
        </article>

        <aside class=

    精選推薦

    更多
    • 文章
    • 資料
    • 帖子

    推薦專欄

    更多