1. 分頁查詢
方案一:MyBatis XML
?MyBatis 內置的使用方式,步驟如下:
① 創建?AdminUserMapper.xml
?文件,編寫兩個 SQL 查詢語句:
<?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="cn.iocoder.yudao.module.system.dal.mysql.user.AdminUserMapper"><select id="selectPage01List"resultType="cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO" >SELECT * FROM system_users<where><if test="reqVO.username != null and reqVO.username !=''">AND username LIKE CONCAT('%',#{reqVO.username},'%')</if><if test="reqVO.createTime != null">AND create_time BETWEEN #{reqVO.createTime[0]}, #{reqVO.createTime[1]},</if><if test="reqVO.status != null">AND status = #{reqVO.status}</if></where>ORDER BY id DESCLIMIT #{reqVO.pageNo}, #{reqVO.pageSize}</select><select id="selectPage01Count" resultType="Long" >SELECT COUNT(1) FROM system_users<where><if test="reqVO.username != null and reqVO.username !=''">AND username LIKE CONCAT('%',#{reqVO.username},'%')</if><if test="reqVO.createTime != null">AND create_time BETWEEN #{reqVO.createTime[0]}, #{reqVO.createTime[1]},</if><if test="reqVO.status != null">AND status = #{reqVO.status}</if></where></select></mapper>
② 在 AdminUserMapper 創建這兩 SQL 對應的方法:
@Mapper
public interface AdminUserMapper extends BaseMapperX<AdminUserDO> {/*** 查詢分頁的列表*/List<AdminUserDO> selectPage01List(@Param("reqVO") UserPageReqVO reqVO);/*** 查詢分頁的條數*/Long selectPage01Count(@Param("reqVO") UserPageReqVO reqVO);}
其中?UserPageReqVO.java?(opens new window)是分頁查詢的請求 VO。
③ 在 AdminUserServiceImplService 層,調用這兩個方法,實現分頁查詢:
@Service
@Slf4j
public class AdminUserServiceImpl implements AdminUserService {@Overridepublic PageResult<AdminUserDO> getUserPage(UserPageReqVO reqVO) {return new PageResult<>(userMapper.selectPage01List(reqVO),userMapper.selectPage01Count(reqVO));}
}
④ 簡單調用下,可以在 IDEA 控制臺看到 2 條 SQL:
方案二:MyBatis Plus XML
MyBatis Plus 拓展的使用方式,可以簡化只需要寫一條 SQL,步驟如下:
① 創建?AdminUserMapper.xml
?文件,只編寫一個 SQL 查詢語句:
<?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="cn.iocoder.yudao.module.system.dal.mysql.user.AdminUserMapper"><select id="selectPage02"resultType="cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO" >SELECT * FROM system_users<where><if test="reqVO.username != null and reqVO.username !=''">AND username LIKE CONCAT('%',#{reqVO.username},'%')</if><if test="reqVO.createTime != null">AND create_time BETWEEN #{reqVO.createTime[0]}, #{reqVO.createTime[1]},</if><if test="reqVO.status != null">AND status = #{reqVO.status}</if></where>ORDER BY id DESC</select></mapper>
注意,不需要寫?LIMIT
?分頁語句噢。
② 在 AdminUserMapper 創建這一 SQL 對應的方法:
@Mapper
public interface AdminUserMapper extends BaseMapperX<AdminUserDO> {IPage<AdminUserDO> selectPage02(IPage<AdminUserDO> page, @Param("reqVO") UserPageReqVO reqVO);}
第一個參數、返回結果必須都是 IPage 類型,第二個參數可以放查詢條件。
③ 在 AdminUserServiceImplService 層,調用這一個方法,實現分頁查詢:
@Service
@Slf4j
public class AdminUserServiceImpl implements AdminUserService {@Overridepublic PageResult<AdminUserDO> getUserPage(UserPageReqVO reqVO) {// 必須使用 MyBatis Plus 的分頁對象IPage<AdminUserDO> page = new Page<>(reqVO.getPageNo(), reqVO.getPageSize());userMapper.selectPage02(page, reqVO);return new PageResult<>(page.getRecords(), page.getTotal());}
}
因為項目使用 PageParam 和 PageResult 作為分頁對象,所以需要和 IPage 做下轉換。
④ 簡單調用下,可以在 IDEA 控制臺看到 2 條 SQL:
本質上,MyBatis Plus 是基于我們在 XML 編寫的這條 SQL,計算出獲得分頁數量的 SQL。
一般情況下,建議采用方案二:MyBatis Plus XML,因為它開發效率更高,并且在分頁數量為 0 時,就不多余查詢分頁的列表,一定程度上可以提升性能。
2. 聯表查詢
對于需要鏈表查詢的場景,建議也是寫 MyBatis XML。
除了 XML 這種方式外,項目也集成了?MyBatis Plus Join?(opens new window)框架,通過 Java 代碼實現聯表查詢。
這里,以查詢?system_users
?和?system_dept
?聯表,查詢部門名為?芋道源碼
、用戶狀態為開啟的用戶列表。
案例一:字段平鋪
① 創建 AdminUserDetailDO 類,繼承 AdminUserDO 類,并添加?deptName
?平鋪。代碼如下:
@Data
public class AdminUserDetailDO extends AdminUserDO {private String deptName;}
② 在 AdminUserMapper 創建 selectListByStatusAndDeptName 方法,代碼如下:
@Mapper
public interface AdminUserMapper extends BaseMapperX<AdminUserDO> {default List<AdminUserDetailDO> selectList2ByStatusAndDeptName(Integer status, String deptName) {return selectJoinList(AdminUserDetailDO.class, new MPJLambdaWrapper<AdminUserDO>() // 查詢 List.selectAll(AdminUserDO.class) // 查詢 system_users 表的 all 所有字段.selectAs(DeptDO::getName, AdminUserDetailDO::getDeptName) // 查詢 system_dept 表的 name 字段,使用 deptName 字段“部分”返回.eq(AdminUserDO::getStatus, status) // WHERE system_users.status = ? 【部門名為 `芋道源碼`】.leftJoin(DeptDO.class, DeptDO::getId, AdminUserDO::getDeptId) // 聯表 WHERE system_users.dept_id = system_dept.id .eq(DeptDO::getName, deptName) // WHERE system_dept.name = ? 【用戶狀態為開啟】);}}
案例二:字段內嵌
① 創建 AdminUserDetailDO 類,繼承 AdminUserDO 類,并添加?dept
?部門。代碼如下:
@Data
public class AdminUserDetail2DO extends AdminUserDO {private DeptDO dept;}
② 在 AdminUserMapper 創建 selectListByStatusAndDeptName 方法,代碼如下:
@Mapper
public interface AdminUserMapper extends BaseMapperX<AdminUserDO> {default List<AdminUserDetail2DO> selectListByStatusAndDeptName(Integer status, String deptName) {return selectJoinList(AdminUserDetail2DO.class, new MPJLambdaWrapper<AdminUserDO>().selectAll(AdminUserDO.class).selectAssociation(DeptDO.class, AdminUserDetail2DO::getDept) // 重點差異點:查詢 system_dept 表的 name 字段,使用 dept 字段“整個”返回.eq(AdminUserDO::getStatus, status).leftJoin(DeptDO.class, DeptDO::getId, AdminUserDO::getDeptId).eq(DeptDO::getName, deptName));}}
2.3 總結
MyBatis Plus Join 相比 MyBatis XML 來說,一開始肯定是需要多看看它的文檔?(opens new window)。
但是熟悉后,我還是更喜歡使用 MyBatis Plus Join 哈~