文章目录
前言
mybatis-plus的多条件+分页+多表查询的编写方法一、创建条件查询的VO
我们首先创建一个AlbumPicQuery类,作为查询参数类, 里面封装了我们要查询的参数
public class AlbumPicQuery implements Serializable {
/**
* 专辑ID
*
* */
@ApiModelProperty(value = "专辑的ID",example = "1334767173783027714")
private String albumId;
/**
* 模特名字
* */
@ApiModelProperty(value = "名字",example = "张三")
private String name;
/**
* 是否上线
*/
@ApiModelProperty(value = "是否上线",example = "1")
private String online;
/**
* 更新时间开始
*/
@ApiModelProperty(value = "专辑图片更新起始时间",example = "2020-12-04 00:00:00")
private String startTime;
/**
* 更新结束时间
* */
@ApiModelProperty(value = "专辑图片更新结束时间",example = "2020-12-04 00:00:00")
private String endTime;
//省略getter setter toString
有了查询参数类之后,我们将此类作为Controller组件查询方法的参数,方便前端传入查询条件后直接封装成AlbumPicQuery对象
@ApiOperation(value = "多条件分页查询",httpMethod="POST")
@PostMapping("/{current}/{limit}/pic")
public UnifyResult getAlbumPic(@ApiParam(name = "current",value = "当前页码",required = true) @PathVariable long current,
@ApiParam(name = "limit",value = "每页查询条数",required = true) @PathVariable long limit,
@RequestBody(required = false) AlbumPicQuery albumPicQuery){
}
二、创建两个实体类
1.Album类
代码如下(示例):
public class Album {
/**
* id
* */
private String id;
/**
* 专辑名称
* */
private String albumName;
/**
* 专辑封面
* */
private String cover;
/**
* 创建时间
* */
@TableField(fill = FieldFill.INSERT)
private Date gmtCreate;
/**
* 修改时间
* */
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date gmtModified;
/**
* 是否上线
* */
private Integer online;
/**
* 逻辑删除标志
*/
@TableLogic
private Integer deleted;
//省略getter setter toString
2.AlbumPic类
public class AlbumPic {
/**
* id
* */
private String id;
/**
* 所属的专辑ID
* */
private String albumId;
/**
* 名字
* */
private String name;
/**
* 图片URL
* */
private String picUrl;
/**
* 是否上线
* */
private Integer online;
/**
* 图片热度
* */
private String hot;
/**
* 创建时间
* */
@TableField(fill = FieldFill.INSERT)
private Date gmtCreate;
/**
* 修改时间
* */
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date gmtModified;
/**
* 逻辑删除
* */
@TableLogic
private Integer deleted;
//省略setter getter toString
两个类分别对应数据库里的两个表,因为我们要做多表查询,所以以两张表为例。
三、创建AlbumPicResVO类
代码如下(示例):public class AlbumPicResVO extends AlbumPic {
private Album albumInfo;
public Album getAlbum() {
return albumInfo;
}
public void setAlbum(Album album) {
this.albumInfo = album;
}
@Override
public String toString() {
return "AlbumPicResVO{" +
"album=" + albumInfo +
'}';
}
该类封装两个表连表查询后的结果,用于返回给前端。
此类其实就是继承AlbumPic 类里的所有属性然后再将Album 类封装进来
四、构建mapper接口
代码如下(示例):@Repository
public interface AlbumPicMapper extends BaseMapper<AlbumPic> {
/**
* TODO 多表分页带条件查询
*
* @param page 分页
* @param albumPicQuery 查询条件
* @return Page
*/
Page<AlbumPicResVO> findAndPage (Page<AlbumPicResVO> page, AlbumPicQuery albumPicQuery);
}
五、构建mapper.xml文件
代码如下(示例):<mapper namespace="com.babyqiao.wallpaper.manager.dao.AlbumPicMapper">
<resultMap id="albumRes" type="com.babyqiao.entity.vo.AlbumPicResVO">
<id property="id" column="id"/>
<result property="albumId" column="album_id"/>
<result property="name" column="name"/>
<result property="picUrl" column="pic_url"/>
<result property="online" column="online"/>
<result property="hot" column="hot"/>
<result property="gmtCreate" column="gmt_create" jdbcType="TIMESTAMP"/>
<result property="gmtModified" column="gmt_modified" jdbcType="TIMESTAMP"/>
<!--albumInfo对象中的属性-->
<result property="albumInfo.id" column="album_album_id"/>
<result property="albumInfo.albumName" column="album_name"/>
<result property="albumInfo.cover" column="album_cover"/>
<result property="albumInfo.gmtCreate" column="album_gmt_create" jdbcType="TIMESTAMP"/>
<result property="albumInfo.gmtModified" column="album_gmt_modified" jdbcType="TIMESTAMP"/>
<result property="albumInfo.online" column="album_online"/>
</resultMap>
<select id="findAndPage" resultMap="albumRes">
SELECT alp.id,alp.album_id,alp.name,alp.pic_url,alp.online,alp.hot,alp.gmt_create,alp.gmt_modified,
al.id album_album_id,al.album_name,al.cover album_cover,al.gmt_create album_gmt_create,al.gmt_modified album_gmt_modified,al.online album_online
FROM album_pic alp,album al WHERE alp.deleted =0 and alp.album_id=al.id
<if test="albumPicQuery.albumId !=null and albumPicQuery.albumId !=''">
and alp.album_id=#{albumPicQuery.albumId}
</if>
<if test="albumPicQuery.name !=null and albumPicQuery.name!=''">
and alp.name like concat('%',#{albumPicQuery.name},'%')
</if>
<if test="albumPicQuery.online !=null and albumPicQuery.online!=''">
and alp.online=#{albumPicQuery.online}
</if>
<if test="albumPicQuery.startTime !=null and albumPicQuery.startTime!=''">
and alp.gmt_modified >= #{albumPicQuery.startTime}
</if>
<if test="albumPicQuery.endTime !=null and albumPicQuery.endTime!=''">
and alp.gmt_modified <= #{albumPicQuery.endTime}
</if>
</select>
</mapper>
这里着重说一下resultMap 的构建,这个resultMap 主要就是对应我们之前构建的AlbumPicResVO类,我们从type就能看出来
这样查询出来的结果才能准确的映射给AlbumPicResVO对象
而AlbumPicResVO是个复合类,所以在映射的时候应该用[复合类对象.方法名] 如:
为了防止两个表在查询的时候,又重复的字段,我将所有复合类的类名都加上了album_ 进行区别
注意 !这时的这个column的值要与查询sql中命名的别名相一致
然后是构建查询条件
这里注意上面的红框里的内容不能直接写成 <= (这样写会报错)
替代方法又很多不止我写的这一种。
六、构建service接口
代码如下(示例):这没什么好说的就是service接口,参数page为分页,AlbumPicQuery 为查询条件
public Page<AlbumPicResVO> multipleTablesAndCondition(Page<AlbumPicResVO> page,AlbumPicQuery albumPicQuery);
七、构建service实现类
代码如下(示例):@Override
public Page<AlbumPicResVO> multipleTablesAndCondition(Page<AlbumPicResVO> page, AlbumPicQuery albumPicQuery) {
Page<AlbumPicResVO> andPage = albumPicMapper.findAndPage(page, albumPicQuery);
return andPage;
}
同样没什么好说的,就是调用mapper接口的方法,然后会自动调用mapper.xml对应id里面的SQL语句,这些都是mybatis的设计,就是这么用的。
八、Controller类里的查询方法中调用
代码如下(示例):啥也不说直接调就完了。
@ApiOperation(value = "多条件分页查询",httpMethod="POST")
@PostMapping("/{current}/{limit}/pic")
public UnifyResult getAlbumPic(@ApiParam(name = "current",value = "当前页码",required = true) @PathVariable long current,
@ApiParam(name = "limit",value = "每页查询条数",required = true) @PathVariable long limit,
@RequestBody(required = false) AlbumPicQuery albumPicQuery){
//构建查询参数
//QueryWrapper<AlbumPic> albumPicQueryWrapper = albumPicService.addSelectCondition(albumPicQuery);
//构建分页
Page<AlbumPicResVO> page=new Page<>(current,limit);
//albumPicService.page(page,albumPicQueryWrapper);
Page<AlbumPicResVO> albumPicResVOPage = albumPicService.multipleTablesAndCondition(page, albumPicQuery);
//获得总数
long total = albumPicResVOPage.getTotal();
//获得数据
List<AlbumPicResVO> records = albumPicResVOPage.getRecords();
return UnifyResult.success().data("result",records);
}
所有参数都是前端给你,你返回一个复合类的JSON给前端。
PS:这里面构建分页的Page对象是Mybatis-plus自带的组件,将你的页码和每页显示多少条的数据,传入到构造方法里就能构建出来,传入之后直接能实现分页效果。
结尾
看看效果没问题!大功告成!