1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        來了,MyBatisPlus的加入聯(lián)表查詢!

        共 15135字,需瀏覽 31分鐘

         ·

        2022-08-25 18:31

        點(diǎn)擊關(guān)注公眾號,Java干貨及時送達(dá)

        作者:陽宗德

        來源:https://juejin.cn/post/7110405284811522085


        眾所周知,mybatis plus 封裝的 mapper 不支持 join,如果需要支持就必須自己去實(shí)現(xiàn)。但是對于大部分的業(yè)務(wù)場景來說,都需要多表 join,要不然就沒必要采用關(guān)系型數(shù)據(jù)庫了。

        那么有沒有一種不通過硬 SQL 的形式,通過框架提供 join 能力呢?答案是,可以有。經(jīng)過一段時間的插眼排眼操作,成功的封裝了一個 jar 包。本文講講它的用法。

        使用方法

        安裝

        • Maven
        <dependency>
            <groupId>com.github.yulichang</groupId>
            <artifactId>mybatis-plus-join</artifactId>
            <version>1.2.4</version>
        </dependency>
        • Gradle
        implementation 'com.github.yulichang:mybatis-plus-join:1.2.4'

        或者 clone 代碼到本地執(zhí)行 mvn install,再引入以上依賴。

        注意:mybatis plus version >= 3.4.0。

        使用

        • mapper繼承MPJBaseMapper (必選)
        • service繼承MPJBaseService (可選)
        • serviceImpl繼承MPJBaseServiceImpl (可選)

        核心類 MPJLambdaWrapper和MPJQueryWrapper

        MPJLambdaWrapper用法

        簡單的三表查詢

        class test {
            @Resource
            private UserMapper userMapper;

            void testJoin() {
                List<UserDTO> list = userMapper.selectJoinList(UserDTO.class,
                        new MPJLambdaWrapper<UserDO>()
                                .selectAll(UserDO.class)
                                .select(UserAddressDO::getTel)
                                .selectAs(UserAddressDO::getAddressUserDTO::getUserAddress)
                                .select(AreaDO::getProvinceAreaDO::getCity)
                                .leftJoin(UserAddressDO.classUserAddressDO::getUserIdUserDO::getId)
                                .leftJoin(AreaDO.classAreaDO::getIdUserAddressDO::getAreaId)
                                .eq(UserDO::getId, 1)
                                .like(UserAddressDO::getTel, "1")
                                .gt(UserDO::getId, 5))
        ;
            }
        }

        對應(yīng)sql

        SELECT 
            t.id,
            t.name,
            t.sex,
            t.head_img,
            t1.tel,
            t1.address AS userAddress,
            t2.province,
            t2.city 
        FROM 
            user t 
            LEFT JOIN user_address t1 ON t1.user_id = t.id 
            LEFT JOIN area t2 ON t2.id = t1.area_id 
        WHERE (
            t.id = ? 
            AND t1.tel LIKE ? 
            AND t.id > ?)

        說明:

        • UserDTO.class 查詢結(jié)果返回類(resultType)
        • selectAll() 查詢指定實(shí)體類的全部字段
        • select() 查詢指定的字段,支持可變參數(shù),同一個select只能查詢相同表的字段               故將UserAddressDO和AreaDO分開為兩個select()
        • selectAs() 字段別名查詢,用于數(shù)據(jù)庫字段與業(yè)務(wù)實(shí)體類屬性名不一致時使用
        • leftJoin() 參數(shù)說明               
          第一個參數(shù): 參與連表的實(shí)體類class               
          第二個參數(shù): 連表的ON字段,這個屬性必須是第一個參數(shù)實(shí)體類的屬性               
          第三個參數(shù): 參與連表的ON的另一個實(shí)體類屬性
        • 默認(rèn)主表別名是t,其他的表別名以先后調(diào)用的順序使用t1,t2,t3....
        • 條件查詢,可以查詢主表以及參與連接的所有表的字段,全部調(diào)用mp原生的方法,正常使用沒有sql注入風(fēng)險

        MPJLambdaWrapper 還有很多其他的功能

        • 簡單的SQL函數(shù)使用:https://gitee.com/best_handsome/mybatis-plus-join/wikis/selectFunc()?sort_id=4082479
        • ON語句多條件支持:https://gitee.com/best_handsome/mybatis-plus-join/wikis/leftJoin?sort_id=3496671

        分頁查詢

        class test {
            @Resource
            private UserMapper userMapper;

            void testJoin() {
                IPage<UserDTO> iPage = userMapper.selectJoinPage(new Page<>(210), UserDTO.class,
                        new MPJLambdaWrapper<UserDO>()
                                .selectAll(UserDO.class)
                                .select(UserAddressDO::getTel)
                                .selectAs(UserAddressDO::getAddressUserDTO::getUserAddress)
                                .select(AreaDO::getProvinceAreaDO::getCity)
                                .leftJoin(UserAddressDO.classUserAddressDO::getUserIdUserDO::getId)
                                .leftJoin(AreaDO.classAreaDO::getIdUserAddressDO::getAreaId))
        ;
            }
        }

        對應(yīng)sql

        SELECT 
            t.id,
            t.name,
            t.sex,
            t.head_img,
            t1.tel,
            t1.address AS userAddress,
            t2.province,
            t2.city
        FROM 
            user t
            LEFT JOIN user_address t1 ON t1.user_id = t.id
            LEFT JOIN area t2 ON t2.id = t1.area_id
        LIMIT ?,?

        MPJQueryWrapper

        簡單的3表查詢

        class test {
            @Resource
            private UserMapper userMapper;

            void testJoin() {
                List<UserDTO> list = userMapper.selectJoinList(UserDTO.class,
                        new MPJQueryWrapper<UserDO>()
                                .selectAll(UserDO.class)
                                .select("addr.tel", "addr.address", "a.province")
                                .leftJoin("user_address addr on t.id 
        = addr.user_id")
                                .rightJoin("
        area a on addr.area_id = a.id")
                                .like("
        addr.tel", "1")
                                .le("
        a.province", "1"));
            }
        }

        對應(yīng) sql

        SELECT 
            t.id,
            t.name,
            t.sex,
            t.head_img,
            addr.tel,
            addr.address,
            a.province
        FROM 
            user t
            LEFT JOIN user_address addr on t.id = addr.user_id
            RIGHT JOIN area a on addr.area_id = a.id
        WHERE (
            addr.tel LIKE ?
            AND a.province <= ?)

        說明:

        • UserDTO.class 查詢結(jié)果類(resultType)
        • selectAll(UserDO.class) 查詢主表全部字段(主表實(shí)體類)默認(rèn)主表別名 "t"
        • select() mp的select策略是覆蓋,以最后一次為準(zhǔn),這里的策略是追加,可以一直select               主表字段可以用lambda,會自動添加表別名,主表別名默認(rèn)是 t ,非主表字段必須帶別名查詢
        • leftJoin() rightJoin() innerJoin() 傳sql片段 格式 (表 + 別名 + 關(guān)聯(lián)條件)
        • 條件查詢,可以查詢主表以及參與連接的所有表的字段,全部調(diào)用mp原生的方法,正常使用沒有sql注入風(fēng)險

        分頁查詢

        class test {
            @Resource
            private UserMapper userMapper;

            void testJoin() {
                IPage<UserDTO> page = userMapper.selectJoinPage(new Page<>(110), UserDTO.class,
                        new MPJQueryWrapper<UserDO>()
                                .selectAll(UserDO.class)
                                .select("addr.tel", "addr.address")
                                .select("a.province")
                                .leftJoin("user_address addr on t.id 
        = addr.user_id")
                                .rightJoin("
        area a on addr.area_id = a.id"));
            }
        }

        對應(yīng)sql

        SELECT 
            t.id,
            t.name,
            t.sex,
            t.head_img,
            addr.tel,
            addr.address,
            a.province
        FROM 
            user t
            LEFT JOIN user_address addr on t.id = addr.user_id
            RIGHT JOIN area a on addr.area_id = a.id 
        LIMIT ?,?

        還可以這么操作,但不建議

        class test {
            @Resource
            private UserMapper userMapper;

            void testJoin() {
                List<UserDTO> list = userMapper.selectJoinList(UserDTO.class,
                        new MPJQueryWrapper<UserDO>()
                                .selectAll(UserDO.class)
                                .select("addr.tel", "addr.address")
                                //行列轉(zhuǎn)換
                                .select("CASE t.sex WHEN '男' THEN '1' ELSE '0' END AS sex")
                                //求和函數(shù)
                                .select("sum(a.provinceAS province")
                                //自定義數(shù)據(jù)集
                                .leftJoin("(select * from user_addressaddr on t.id 
        = addr.user_id")
                                .rightJoin("
        area a on addr.area_id = a.id")
                                .like("
        addr.tel", "1")
                                .le("
        a.province", "1")
                                .orderByDesc("
        addr.id"));
            }
        }

        對應(yīng)sql

        SELECT 
            t.id,
            t.name,
            t.sex,
            t.head_img,
            addr.tel,
            addr.address,
            CASE t.sex WHEN '男' THEN '1' ELSE '0' END AS sex,
            sum(a.province) AS province
        FROM 
            user t
            LEFT JOIN (select * from user_address) addr on t.id = addr.user_id
            RIGHT JOIN area a on addr.area_id = a.id
        WHERE (
            addr.tel LIKE ?
            AND a.province <= ?)
        ORDER BY
            addr.id DESC
        針對以上 jar 感興趣的,可以下載對應(yīng)的源碼,進(jìn)一步的學(xué)習(xí)!

            

        1、社區(qū)糾紛不斷:程序員何苦為難程序員?

        2、該死的單元測試,寫起來到底有多痛?

        3、互聯(lián)網(wǎng)人為什么學(xué)不會擺爛

        4、為什么國外JetBrains做 IDE 就可以養(yǎng)活自己,國內(nèi)不行?區(qū)別在哪?

        5、相比高人氣的Rust、Go,為何 Java、C 在工具層面進(jìn)展緩慢?

        6、讓程序員早點(diǎn)下班的《技術(shù)寫作指南》

        點(diǎn)

        點(diǎn)

        點(diǎn)點(diǎn)

        點(diǎn)在看

        瀏覽 60
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        評論
        圖片
        表情
        推薦
        點(diǎn)贊
        評論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            在线成人性爱视频 | 我从后面摸着她的双乳 | 囯产精品一区二区三区线一牛影视1 | 毛片区| 久热99 | 欧美性老妇一区二区三区 | 国产精品美女www爽爽爽动态图 | 制服诱惑影院 | 再深点灬舒服灬免费A片日本 | 久久久久99精品成人片直播 |