MyBatisPlus多表自定义分页查询

问题:

我需要对一个文章信息+类型名称,它们分别属于不同的表,所以需要进行多表关联,再其次我需要查询的数据进行分页,所以我们还需要加入分页的相关条件。

两个实体类:

@Data
@EqualsAndHashCode(callSuper = false)
@ApiModel(value="ArticleInfo对象", description="文章信息")
public class ArticleInfo implements Serializable {

    private static final long serialVersionUID=1L;

    @ApiModelProperty(value = "主键ID")
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;

    @ApiModelProperty(value = "文章类型ID")
    private Integer categoryId;

    @ApiModelProperty(value = "文章标题")
    private String title;

    @ApiModelProperty(value = "文章简介,默认100个汉字以内")
    private String summary;

    @ApiModelProperty(value = "文章是否置顶,0为否,1为是")
    private Integer isTop;

    @ApiModelProperty(value = "图片地址")
    private String pictureUrl;

    @ApiModelProperty(value = "文章访问量")
    private Integer traffic;

    @ApiModelProperty(value = "创建时间")
    @JsonFormat(pattern = "yyyy-MM-dd",timezone = "Asia/Shanghai")
    private Date createdDate;

    @ApiModelProperty(value = "修改日期")
    @JsonFormat(pattern = "yyyy-MM-dd",timezone = "Asia/Shanghai")
    private Date updatedDate;

    @TableField(select = false)
    private Category category;

}
@Data
@EqualsAndHashCode(callSuper = false)
@ApiModel(value="Category对象", description="类型")
public class Category implements Serializable {

    private static final long serialVersionUID=1L;

    @ApiModelProperty(value = "主键id")
    @TableId(value = "id", type = IdType.AUTO)
    private Integer id;

    @ApiModelProperty(value = "分类名称")
    private String name;

    @ApiModelProperty(value = "该分类下的文章数量")
    private Integer num;

    @ApiModelProperty(value = "默认类型图片地址")
    private String prticleUrl;

    @ApiModelProperty(value = "分类排序")
    private Integer orderNum;

    @ApiModelProperty(value = "是否有效,默认为1为有效,0为无效")
    private Boolean isEffective;

    @ApiModelProperty(value = "分类创建时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
    private Date createdDate;

    @ApiModelProperty(value = "分类修改时间")
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
    private Date updatedDate;
    
}

xml的结果集定义:

<!-- 结果集 -->
    <resultMap id="BaseResultMap" type="com.jz.blog.entity.ArticleInfo">
        <id column="id" property="id" jdbcType="INTEGER"/>
        <result column="category_id" property="categoryId" jdbcType="INTEGER"/>
        <result column="title" property="title" jdbcType="VARCHAR"/>
        <result column="summary" property="summary" jdbcType="VARCHAR"/>
        <result column="is_top" property="isTop" jdbcType="INTEGER"/>
        <result column="picture_url" property="pictureUrl" jdbcType="VARCHAR"/>
        <result column="traffic" property="traffic" jdbcType="INTEGER"/>
        <result column="created_date" property="createdDate" jdbcType="TIMESTAMP"/>
        <result column="updated_date" property="updatedDate" jdbcType="TIMESTAMP"/>
    </resultMap>
    <!-- 关联结果集 -->
    <resultMap id="AllArticleInfoWithCategory" type="com.jz.blog.entity.ArticleInfo" extends="BaseResultMap">
        <association property="category" javaType="com.jz.blog.entity.Category">
            <id column="cid" property="id"/>
            <result column="cname" property="name" jdbcType="VARCHAR"/>
        </association>
    </resultMap>

思路一:

MyBatisPlus对于单表提供了很多方法,但是如果想要进行多表关联查询,那么我们就要去进行自定义的查询。

参考selectPage方法


image-20210128184743430.png

我们开始写一下我们自己的方法


image-20210128184949102.png

对应的xml信息
<select id="selectPage2" resultMap="AllArticleInfoWithCategory">
        SELECT a.*,
               c.id   AS cid,
               c.name AS cname
        FROM article_info a,
             category c
        WHERE a.category_id = c.id
        <if test="ew.sqlSegment != null and ew.sqlSegment != ''">
            AND ${ew.sqlSegment}
        </if>
    </select>

接下来开始进行测试

思路是,文章信息类作为实体参数,配个分页信息进行查询

 @Test
    public void myPageQueryTest2(){
        //参数信息
        ArticleInfo articleInfo = new ArticleInfo();
        articleInfo.setCategoryId(1);
        articleInfo.setSummary("摘要1");
        QueryWrapper<ArticleInfo> queryWrapper = new QueryWrapper<ArticleInfo>(articleInfo);
        //分页信息
        Page<ArticleInfo> page = new Page<ArticleInfo>(1,10);
        
        IPage<ArticleInfo> iPage = articleInfoMapper.selectPage2(page,queryWrapper);
        System.out.println(iPage.getRecords().size());
        List<ArticleInfo> lists = iPage.getRecords();
        lists.forEach(list ->{
            System.out.println(list.toString());
        });
    }

按照预想,实体内参数应该可以自动生成条件语句,${ew.sqlSegment}拼接在SQL中。

但是结果是,并没有如预想中拼接在后面:


image-20210128185947434.png

我开始以为我自己写错了,然后我替换成selectPage,MyBatisPlus自带的分页查询,开始实验。

结果是可行的,下面图片中就只有查询的方法改变了


image-20210128190145621.png

然后呢,是不是我自定义写错了,我不传入实体类,传入表达式。

结果是可行的


image-20210128190433352.png

那么问题来了?为什么传入实体类作为参数,自定义的方法中为何不能拼接成sql呢?

这个有待研究~

总结:思路一暂时行不通

思路二:

纯mybatis的形势,咱们不使用mybatis的分页插件,自将分页的参数、条件对象一一对应去写。
(这里的page 需要进行 page = (page-1)*size 转换)
接口:


image-20210128191855997.png

xml:

<select id="mySelectPage" resultMap="AllArticleInfoWithCategory">
        SELECT a.*,
        c.id AS cid,
        c.name AS cname
        FROM article_info a,
        category c
        Where a.category_id = c.id
        <if test="art.title != null and art.title != ''">
            and a.title like concat('%',#{art.title},'%')
        </if>
        <if test="art.summary != null and art.summary != ''">
            and a.summary like concat('%',#{art.summary},'%')
        </if>
        <if test="art.categoryId != null and art.categoryId != ''">
            and a.category_id = #{art.categoryId}
        </if>
        <if test="page !=null and size!=null">
            limit #{page},#{size}
        </if>
    </select>

测试代码:

@Test
    public void myPageQueryTest3(){
        ArticleInfo articleInfo = new ArticleInfo();
        articleInfo.setCategoryId(1);
        articleInfo.setSummary("摘要1");
        List<ArticleInfo> lists = articleInfoMapper.mySelectPage(1,10,articleInfo);
        System.out.println(lists.size());
        lists.forEach(list ->{
            System.out.println(list.toString());
        });
    }

测试结果是可行的

==>  Preparing: SELECT a.*, c.id AS cid, c.name AS cname FROM article_info a, category c Where a.category_id = c.id and a.summary like concat('%',?,'%') and a.category_id = ? limit ?,? 
==> Parameters: 摘要1(String), 1(Integer), 1(Integer), 10(Integer)

但是这个有一点欠缺的是,返回的是list合集,而且是本次查询的结果合集,我们分页查询肯定少不了总数,单纯用mybatis的话,咱们要再写一个查询总数的方法,进行查询。我们使用MyBatisp的分页插件的时候,已经直接进行了总数查询,所以我们就直接二者结合来用。

思路三:

MyBatisPlus的分页插件+实体传参的形式

接口:


image-20210128192431106.png

xml:

<select id="selectPageWithCategory" resultMap="AllArticleInfoWithCategory">
        SELECT a.*,
        c.id AS cid,
        c.name AS cname
        FROM article_info a,
        category c
        Where a.category_id = c.id
        <if test="art.title != null and art.title != ''">
            and a.title like concat('%',#{art.title},'%')
        </if>
        <if test="art.summary != null and art.summary != ''">
            and a.summary like concat('%',#{art.summary},'%')
        </if>
        <if test="art.categoryId != null and art.categoryId != ''">
            and a.category_id = #{art.categoryId}
        </if>
        order by a.id desc
    </select>

测试代码:

 @Test
    public void myPageQueryTest(){
        ArticleInfo articleInfo = new ArticleInfo();
        articleInfo.setCategoryId(1);
        articleInfo.setSummary("摘要1");
        Page<ArticleInfo> page = new Page<ArticleInfo>(1,10);
        IPage<ArticleInfo> iPage = articleInfoMapper.selectPageWithCategory(page,articleInfo);
        System.out.println(iPage.getRecords().size());
        List<ArticleInfo> lists = iPage.getRecords();
        lists.forEach(list ->{
            System.out.println(list.getCategory().getName());
        });
    }

测试结果可行,进行了两次查询,一次总数一次结果,且包含了我需要的分类表数据


image-20210128192658073.png

总结

思路一参考MyBatisPlus的selectPage方法,但是目前暂时不知道为啥实体参数带不出来,后面有时间研究一下。

思路二是纯mybatis,一一对应还是很容易明白的

思路三是偷懒的方法,省了一次查询总数的方法

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容