使用 MyBatis-plus 可以很简单的使用 Wrapper 进行单表操作。但是要是能在联表查询和自定义 SQL 中使用 Wrapper 就更好了。
翻了翻 MyBatis-Plus 的官网的文档,还真有这一节。
官网文档直通车
根据官网的文档只要像下面给到的栗子这么做就可以使用 Wrapper 自定义 SQL
## Service.java
mysqlMapper.getAll(Wrappers.<MysqlData>lambdaQuery().eq(MysqlData::getGroup, 1));
## Mapper.java
List<MysqlData> getAll(@Param(Constants.WRAPPER) Wrapper wrapper);
## mapper.xml
<select id="getAll" resultType="MysqlData">
SELECT * FROM mysql_data ${ew.customSqlSegment}
</select>
官网的举例中还是单表环境下,所以我尝试做了多表联合查询
根据文档在 mapper.xml 中加入 ${ew.customSqlSegment}
<select id="selectByRoleId" resultType="com.captain.crewer.mybatis.plus.dto.RolePermsDTO">
SELECT tp.id,
tp.perm_name,
tp.url,
tr.role_id as roleId,
tr.role_name as roleName
FROM tb_role tr
LEFT JOIN tb_perm_role tpr ON tr.role_id = tpr.role_id
LEFT JOIN tb_perm tp ON tpr.perm_id = tp.id ${ew.customSqlSegment}
</select>
在 Mapper.java 的参数列表中加入
@Param(Constants.WRAPPER) Wrapper wrapper
/**
* 根据角色名查询权限信息
*
* @param wrapper mybatis-plus wrapper
* @return 权限集合
*/
List<RolePermsDTO> selectByRoleId(@Param(Constants.WRAPPER) Wrapper<RolePermsDTO> wrapper);
然后我就在测试类中这么一调用
@Test
public void test(){
tbPermService.selectByRoleId(Wrappers.<RolePermsDTO>lambdaQuery()
.eq(RolePermsDTO::getRoleId, 1));
}
然后就报错了!
MybatisPlusException: can not find lambda cache for this property [roleId] of entity [xxx.xxx.xxx.RolePermsDTO]
试了很多方法,最后发现像这种联合查询不能直接用 Wrappers 直接构建,要用 QueryWrapper 来曲线救国:
@Test
public void test2(){
QueryWrapper<RolePermsDTO> wrapper = new QueryWrapper<>();
wrapper.eq("tr.role_id", 1);
tbPermService.selectByRoleId(wrapper);
}
还要注意,如果传入的字段名称在多个表中都存在需要 在条件中显式的使用 [table].[column]
的方式表达,防止报
column in where clause is amiguous
错误