MyBatisPlus自定义Sql多表联查
MyBatisPlus
MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
配置分页
开发当中肯定有很多人进行多表联查并分页处理,我们先配置MyaBatisPlus物理分页,它的分页不会占用内存
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
return paginationInterceptor;
}
@Bean
public MybatisPlusObjectHandler alarmMetaObjectHandler() {
MybatisPlusObjectHandler alarmMetaObjectHandler = new MybatisPlusObjectHandler();
return alarmMetaObjectHandler;
}
MyBatisPlus自定义Sql
重写内置接口
在开发中我们存在多表及各式各样的复杂查询,对于这种问题MyBatisPlus也有相对应的解决办法:
比如像MyBatisPLus中自带的BaseMapper里就有很多CRUD的接口,包括Mapper层及Service层,但这些都是单表的CRUD,那我们如何解决呢?
这是MyBatisPlus自带的方法
package com.baomidou.mybatisplus.core.mapper;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Constants;
import org.apache.ibatis.annotations.Param;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* Mapper 继承该接口后,无需编写 mapper.xml 文件,即可获得CRUD功能
* <p>这个 Mapper 支持 id 泛型</p>
*
* @author hubin
* @since 2016-01-23
*/
public interface BaseMapper<T> extends Mapper<T> {
/**
* 插入一条记录
*
* @param entity 实体对象
*/
int insert(T entity);
/**
* 根据 ID 删除
*
* @param id 主键ID
*/
int deleteById(Serializable id);
/**
* 根据 columnMap 条件,删除记录
*
* @param columnMap 表字段 map 对象
*/
int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
/**
* 根据 entity 条件,删除记录
*
* @param wrapper 实体对象封装操作类(可以为 null)
*/
int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper);
/**
* 删除(根据ID 批量删除)
*
* @param idList 主键ID列表(不能为 null 以及 empty)
*/
int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
/**
* 根据 ID 修改
*
* @param entity 实体对象
*/
int updateById(@Param(Constants.ENTITY) T entity);
/**
* 根据 whereEntity 条件,更新记录
*
* @param entity 实体对象 (set 条件值,可以为 null)
* @param updateWrapper 实体对象封装操作类(可以为 null,里面的 entity 用于生成 where 语句)
*/
int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper);
/**
* 根据 ID 查询
*
* @param id 主键ID
*/
T selectById(Serializable id);
/**
* 查询(根据ID 批量查询)
*
* @param idList 主键ID列表(不能为 null 以及 empty)
*/
List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
/**
* 查询(根据 columnMap 条件)
*
* @param columnMap 表字段 map 对象
*/
List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
/**
* 根据 entity 条件,查询一条记录
*
* @param queryWrapper 实体对象封装操作类(可以为 null)
*/
T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
/**
* 根据 Wrapper 条件,查询总记录数
*
* @param queryWrapper 实体对象封装操作类(可以为 null)
*/
Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
/**
* 根据 entity 条件,查询全部记录
*
* @param queryWrapper 实体对象封装操作类(可以为 null)
*/
List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
/**
* 根据 Wrapper 条件,查询全部记录
*
* @param queryWrapper 实体对象封装操作类(可以为 null)
*/
List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
/**
* 根据 Wrapper 条件,查询全部记录
* <p>注意: 只返回第一个字段的值</p>
*
* @param queryWrapper 实体对象封装操作类(可以为 null)
*/
List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
/**
* 根据 entity 条件,查询全部记录(并翻页)
*
* @param page 分页查询条件(可以为 RowBounds.DEFAULT)
* @param queryWrapper 实体对象封装操作类(可以为 null)
*/
<E extends IPage<T>> E selectPage(E page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
/**
* 根据 Wrapper 条件,查询全部记录(并翻页)
*
* @param page 分页查询条件
* @param queryWrapper 实体对象封装操作类
*/
<E extends IPage<Map<String, Object>>> E selectMapsPage(E page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
}
Dao层:
@Mapper
public interface QuotaDao extends BaseMapper<Quota>{
}
可以把相对应的方法名重写到Mapper.xml文件里
<select id="selectPage" resultType="com.qhotin.basic.model.comm.Quota">
SELECT t1.*,t2.TYPENAME FROM
T_OPS_QUOTA t1 LEFT JOIN
T_FES_SENSOR_TYPE t2
ON t1.TYPE_ID = t2.TYPEID
/*这句比较关键,因为调用重写的是selectPage方法里面有
queryWrapper条件构造,所以可以直接ew.customSqlSegment*/
<if test="ew.customSqlSegment != '' and ew.customSqlSegment != null">
${ew.customSqlSegment}
</if>
</select>
Service层代码:
/**
* @Author QHoTin
* @Date 2020/7/14 11:22
* @Version 1.0
*/
@Service("QuotaService")
public class QuotaServiceImpl extends ServiceImpl<QuotaDao, Quota> implements QuotaService {
@Override
public IPage<Quota> selectListPage(Integer current, Integer size, Quota quota) {
IPage<Quota> quotaPage = new Page<Quota>(current, size);
//注意xml文件里sql已经进行多表查询了,所以在这里的参数变成t1.DATE_ITEM_NAME
QueryWrapper<Quota> queryWrapper = new QueryWrapper<Quota>()
.like(!StringUtils.isEmpty(quota.getDateItemName()),"t1.DATE_ITEM_NAME",quota.getDateItemName())
.orderByDesc("t1.RANK");
return this.baseMapper.selectPage(quotaPage,queryWrapper);
}
}
自定义接口实现
在Dao层里自定义自己的接口:
@Mapper
public interface UserDao extends BaseMapper<User>{
//这个很关键@Param(Constants.WRAPPER) Wrapper<T> queryWrapper
//因为要调用后面的条件构造器
IPage<User> selectPageUser(IPage<User> page, @Param(Constants.WRAPPER) Wrapper<User> queryWrapper);
}
Mapper.xml文件:
<select id="selectPageUser" parameterType="com.nari.sys.model.ext.UserPageQuery" resultMap="BaseResultMap">
SELECT
su.*,
str.name as struName
FROM ENE_SYS_USER su
LEFT JOIN (select STRU_ID,STRU_CODE,NAME from ENE_SYS_STRU) str ON su.STRU_ID=str.STRU_ID
<if test="ew.customSqlSegment != '' and ew.customSqlSegment != null">
${ew.customSqlSegment}
</if>
</select>
Service文件:
/**
*@Description 用户管理模块接口实现类
*@Author QHoTin
*@Date 2020/5/13 15:47
*/
@Service("userService")
public class UserServiceImpl extends ServiceImpl<UserDao, User> implements UserService{
@Override
public IPage<User> selectPageUser(Integer current, Integer size,User user) {
// 当前页,总条数 构造 page 对象
IPage<User> page = new Page<User>(current, size);
QueryWrapper<User> queryWrapper = new QueryWrapper<User>()
.eq(StringUtils.isNotEmpty(user.getStatusCode()),"su.STATUS_CODE",user.getStatusCode())
.eq(StringUtils.isNotEmpty(user.getSex()),"su.SEX",user.getSex())
.like(StringUtils.isNotEmpty(user.getName()),"su.NAME",user.getName())
.eq(user.getStruId()!=null,"su.STRU_ID",user.getStruId())
.like(StringUtils.isNotEmpty(user.getUsername()),"su.USERNAME",user.getUsername())
.eq(StringUtils.isNotEmpty(user.getUserType()),"su.USER_TYPE",DictConstants.USER_TYPE_01)
.orderByDesc("su.UPDATE_TIME","su.CREATE_TIME");
return this.baseMapper.selectPageUser(page, queryWrapper);
}
}
以上是两种实现分页查询及条件查询的方法,简而言之MyBatisPlus很灵活,包括UpdateWapper,lambdaQuery都是很强大的构造器,希望大家以后有什么问题可以评论一起讨论,简化开发,使得开发效率提高。
版权声明:本文为weixin_45120856原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。