來了,MyBatisPlus的join聯表查詢

眾所周知,mybatis plus 封裝的 mapper 不支援 join,如果需要支援就必須自己去實現。但是對於大部分的業務場景來說,都需要多表達 join,要不然就沒必要採用關係型資料庫了。

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

使用方法

安裝

Maven

com。github。yulichang mybatis-plus-join 1。2。4

Gradle

implementation ‘com。github。yulichang:mybatis-plus-join:1。2。4’

或者 clone 程式碼到本地執行 mvn install,再引入以上依賴。

注意:mybatis plus version >= 3。4。0。

使用

mapper繼承MPJBaseMapper (必選)

service繼承MPJBaseService (可選)

serviceImpl繼承MPJBaseServiceImpl (可選)

基於 Spring Boot + MyBatis Plus + Vue & Element 實現的後臺管理系統 + 使用者小程式,支援 RBAC 動態許可權、多租戶、資料許可權、工作流、三方登入、支付、簡訊、商城等功能。

專案地址:https://github。com/YunaiV/ruoyi-vue-pro

核心類 MPJLambdaWrapper和MPJQueryWrapper

MPJLambdaWrapper用法

簡單的三表查詢

class test { @Resource private UserMapper userMapper; void testJoin() { List list = userMapper。selectJoinList(UserDTO。class, new MPJLambdaWrapper() 。selectAll(UserDO。class) 。select(UserAddressDO::getTel) 。selectAs(UserAddressDO::getAddress, UserDTO::getUserAddress) 。select(AreaDO::getProvince, AreaDO::getCity) 。leftJoin(UserAddressDO。class, UserAddressDO::getUserId, UserDO::getId) 。leftJoin(AreaDO。class, AreaDO::getId, UserAddressDO::getAreaId) 。eq(UserDO::getId, 1) 。like(UserAddressDO::getTel, “1”) 。gt(UserDO::getId, 5)); }}

對應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 查詢結果返回類(resultType)

selectAll() 查詢指定實體類的全部欄位

select() 查詢指定的欄位,支援可變引數,同一個select只能查詢相同表的欄位 故將UserAddressDO和AreaDO分開為兩個select()

selectAs() 欄位別名查詢,用於資料庫欄位與業務實體類屬性名不一致時使用

leftJoin() 引數說明 第一個引數: 參與連表的實體類class 第二個引數: 連表的ON欄位,這個屬性必須是第一個引數實體類的屬性 第三個引數: 參與連表的ON的另一個實體類屬性

預設主表別名是t,其他的表別名以先後呼叫的順序使用t1,t2,t3。。。。

條件查詢,可以查詢主表以及參與連線的所有表的欄位,全部呼叫mp原生的方法,正常使用沒有sql注入風險

MPJLambdaWrapper 還有很多其他的功能

簡單的SQL函式使用:

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 iPage = userMapper。selectJoinPage(new Page<>(2, 10), UserDTO。class, new MPJLambdaWrapper() 。selectAll(UserDO。class) 。select(UserAddressDO::getTel) 。selectAs(UserAddressDO::getAddress, UserDTO::getUserAddress) 。select(AreaDO::getProvince, AreaDO::getCity) 。leftJoin(UserAddressDO。class, UserAddressDO::getUserId, UserDO::getId) 。leftJoin(AreaDO。class, AreaDO::getId, UserAddressDO::getAreaId)); }}

對應sql

SELECT t。id, t。name, t。sex, t。head_img, t1。tel, t1。address AS userAddress, t2。province, t2。cityFROM user t LEFT JOIN user_address t1 ON t1。user_id = t。id LEFT JOIN area t2 ON t2。id = t1。area_idLIMIT ?,?

MPJQueryWrapper

簡單的3表查詢

class test { @Resource private UserMapper userMapper; void testJoin() { List list = userMapper。selectJoinList(UserDTO。class, new MPJQueryWrapper() 。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”)); }}

對應 sql

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

說明:

UserDTO。class 查詢結果類(resultType)

selectAll(UserDO。class) 查詢主表全部欄位(主表實體類)預設主表別名 “t”

select() mp的select策略是覆蓋,以最後一次為準,這裡的策略是追加,可以一直select 主表字段可以用lambda,會自動新增表別名,主表別名預設是 t ,非主表字段必須帶別名查詢

leftJoin() rightJoin() innerJoin() 傳sql片段 格式 (表 + 別名 + 關聯條件)

條件查詢,可以查詢主表以及參與連線的所有表的欄位,全部呼叫mp原生的方法,正常使用沒有sql注入風險

分頁查詢

class test { @Resource private UserMapper userMapper; void testJoin() { IPage page = userMapper。selectJoinPage(new Page<>(1, 10), UserDTO。class, new MPJQueryWrapper() 。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”)); }}

對應sql

SELECT t。id, t。name, t。sex, t。head_img, addr。tel, addr。address, a。provinceFROM 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 list = userMapper。selectJoinList(UserDTO。class, new MPJQueryWrapper() 。selectAll(UserDO。class) 。select(“addr。tel”, “addr。address”) //行列轉換 。select(“CASE t。sex WHEN ‘男’ THEN ‘1’ ELSE ‘0’ END AS sex”) //求和函式 。select(“sum(a。province) AS province”) //自定義資料集 。leftJoin(“(select * from 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”) 。orderByDesc(“addr。id”)); }}

對應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 provinceFROM user t LEFT JOIN (select * from user_address) addr on t。id = addr。user_id RIGHT JOIN area a on addr。area_id = a。idWHERE ( addr。tel LIKE ? AND a。province <= ?)ORDER BY addr。id DESC

針對以上 jar 感興趣的,可以下載對應的原始碼,進一步地學習!

原文連結:https://mp。weixin。qq。com/s/JX1v_8X8LwjKuTCksoeN2w