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版权协议,转载请附上原文出处链接和本声明。