zoukankan      html  css  js  c++  java
  • MyBatis 多对多查询

    MyBatis 多对多查询

    最近的项目重新用到了 Mybatis, 之前的知识点稍微有点忘记了,在此记录一下。

    MyBatis 的多对多查询本质上就是两个一对多的查询,使用 collection 集合可以解决一对多 查询,使用中间表转成一对多的查询。

    下面以一个例子讲解下,一篇文章有多个分类,一个分类下有多篇文章,因此需要中间表来保存关系。

    entity

    Posts(文章)

    @Data
    @EqualsAndHashCode(callSuper = false)
    @Accessors(chain = true)
    public class Posts implements Serializable {
    
        private static final long serialVersionUID = 1L;
    
        @TableId(value = "id", type = IdType.AUTO)
        private Integer id;
    
        /**
         * 标题
         */
        private String name;
    
        /**
         * 摘要
         */
        private String summary;
    
        /**
         * 内容
         */
        private String content;
    
        /**
         * 封面
         */
        private String cover;
    
        /**
         * 不允许评论
         */
        @TableField("disallowComment")
        private Boolean disallowComment;
    
        /**
         * 置顶文章
         */
        @TableField("topPriority")
        private Boolean topPriority;
    
        /**
         * 排序ID
         */
        @TableField("serID")
        private Integer serID;
    
        /**
         * 文章状态,1正常,0不正常
         */
        private Integer state;
    
        /**
         * 创建时间
         */
        @TableField("addTime")
        private LocalDateTime addTime;
    
        /**
         * 发布时间
         */
        @TableField("releaseTime")
        private LocalDateTime releaseTime;
    
        /**
         * 最后更新时间
         */
        @TableField("updateTime")
        private LocalDateTime updateTime;
    
        /**
         * 文章分类
         */
        @TableField(exist = false)
        private List<PostCategories> categories;
    

    PostsCategories(文章分类)

    @Data
    @EqualsAndHashCode(callSuper = false)
    @Accessors(chain = true)
    public class PostCategories implements Serializable {
    
        private static final long serialVersionUID = 1L;
    
        @TableId(value = "id", type = IdType.AUTO)
        private Integer id;
    
        /**
         * 分类名称
         */
        @NotBlank(message = "分类名称不能为空")
        private String name;
    
        /**
         * 描述
         */
        private String des;
    
        /**
         * 状态
         */
        private Boolean state;
    
        /**
         * 排序
         */
        @TableField("serID")
        private Integer serID;
    
        @TableField("addTime")
        private LocalDateTime addTime;
    
        @TableField("updateTime")
        private LocalDateTime updateTime;
    
        private List<Posts> posts;
    }
    

    PostsCategoriesRelation(中间表)

    @Data
    @EqualsAndHashCode(callSuper = false)
    @Accessors(chain = true)
    public class PostCategoriesRelation implements Serializable {
    
        private static final long serialVersionUID = 1L;
    
        @TableId(value = "id", type = IdType.AUTO)
        private Integer id;
    
        /**
         * 文章ID
         */
        @TableField("postID")
        private Integer postID;
    
        /**
         * 文章分类ID
         */
        @TableField("categoryID")
        private Integer categoryID;
    }
    

    mapper(查询文章列表)

    @Mapper
    @Repository
    public interface PostsMapper extends BaseMapper<Posts> {
    
        List<Posts> getPostsMap(Map<String, Object> map);
    
    }
    

    mapper.xml(查询文章以及文章下的分类)

    在这里查询的是文章下的分类,对于文章自身而言分类是一对多的关系,因此使用 List categories 保存文章分类到 Posts 中。

    collection的几个重要的属性

    • property: 在实体类中的关联的字段名称,这里即是 categories。
    • ofType: 关联的字段的类型,这里即是 PostCategories。
    • column: column="{prop1=col1,prop2=col2}", 指定多个参数给嵌套的select语句
    • select: 嵌套的select语句。
    <!-- 查询语句,由于查询时需要传入 PostCategories 的条件,即从表的条件,所以需要进行左连接,反之则可以去掉 -->
    <select id="getPostsMap" resultMap="postsMap">
        SELECT DISTINCT
        p.id,
        p. NAME,
        p.summary,
        p.content,
        p.cover,
        p.disallowComment,
        p.topPriority,
        p.serID,
        p.state,
        p.addTime,
        p.releaseTime,
        p.updateTime
        FROM
        posts p
        LEFT JOIN post_categories_relation pcr ON p.id = pcr.postID
        LEFT JOIN post_categories pc ON pcr.categoryID = pc.id
        <where>
            <if test="name != null">
                AND p.name LIKE CONCAT('%',#{name},'%')
            </if>
            <if test="disallowComment != null">
                AND p.disallowComment = #{disallowComment}
            </if>
            <if test="topPriority != null">
                AND p.topPriority = #{topPriority}
            </if>
            <if test="state != null">
                AND p.state = #{state}
            </if>
            <!-- PostCategories的查询条件 -->
            <if test="categoryID != null">
                AND pc.id = #{categoryID}
            </if>
        </where>
        order by p.serID asc, p.releaseTime desc
        <if test="current != null">
            LIMIT #{current}, #{pages}
        </if>
    </select>
    
    <!--resultmap,用于结果映射 -->
    <resultMap id="postsMap" type="com.xy.erp.saas.userserver.entity.Posts">
        <result property="id" column="id"></result>
        <result property="name" column="name"></result>
        <result property="summary" column="summary"></result>
        <result property="content" column="content"></result>
        <result property="cover" column="cover"></result>
        <result property="disallowComment" column="disallowComment"></result>
        <result property="topPriority" column="topPriority"></result>
        <result property="serID" column="serID"></result>
        <result property="state" column="state"></result>
        <result property="addTime" column="addTime"></result>
        <result property="releaseTime" column="releaseTime"></result>
        <result property="updateTime" column="updateTime"></result>
        <!-- collection集合,嵌套的查询语句为getPostsCategories -->
        <collection property="categories" ofType="com.xy.erp.saas.userserver.entity.PostCategories" select="getPostsCategories" column="{postID=id}">
        </collection>
    </resultMap>
    
    <!-- 嵌套的select语句,参数由 collection 的 column 传递进来 -->
    <select id="getPostsCategories" resultType="com.xy.erp.saas.userserver.entity.PostCategories">
        SELECT pc.id, pc.name
        FROM
        posts p
        LEFT JOIN post_categories_relation pcr ON p.id = pcr.postID
        LEFT JOIN post_categories pc ON pcr.categoryID = pc.id
        where p.id = #{postID}
    </select>
    
    

    返回结果

    此时,调用 getPostsMap(Map<String, Object> map) 方法,返回结果如下所示, Posts 中包含 categories的 list。

    {
        "id": 8,
        "name": "三体",
        "summary": "跨时代的科幻巨著",
        "content": "围绕三体文明的科幻对决",
        "cover": null,
        "disallowComment": false,
        "topPriority": false,
        "serID": 0,
        "state": 1,
        "addTime": "2020-11-02T15:58:33",
        "releaseTime": null,
        "updateTime": "2020-11-04T10:47:02",
        "categories": [
            {
                "id": 1,
                "name": "古典小说",
                "des": null,
                "state": null,
                "serID": null,
                "addTime": null,
                "updateTime": null
            },
            {
                "id": 3,
                "name": "写实",
                "des": null,
                "state": null,
                "serID": null,
                "addTime": null,
                "updateTime": null
            }
        ],
    }
    

    反之, 根据文章分类查询文章的list也是类似的写法,这里便不再赘述。

    自我控制是最强者的本能-萧伯纳
  • 相关阅读:
    VMware给虚拟机绑定物理网卡
    Chrome插件开发教程收集
    Linux文本过滤常用命令(转)
    Linux文本过滤命令grep、awk、sed
    Chromium和Chrome的区别
    MyBatis参数为Integer型并赋值为0时判断失误的问题解决
    Java中使用HttpRequest调用RESTfull的DELETE方法接口提示:How to fix HTTP method DELETE doesn't support output
    Ubuntu 16.04服务器版查看IP、网关、DNS(非DHCP)
    CentOS 6.9设置IP、网关、DNS
    Ubuntu 16.04服务器版查看DHCP自动分配的IP、网关、DNS
  • 原文地址:https://www.cnblogs.com/CF1314/p/13924742.html
Copyright © 2011-2022 走看看