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也是类似的写法,这里便不再赘述。

    自我控制是最强者的本能-萧伯纳
  • 相关阅读:
    无限维
    黎曼流形
    why we need virtual key word
    TOJ 4119 Split Equally
    TOJ 4003 Next Permutation
    TOJ 4002 Palindrome Generator
    TOJ 2749 Absent Substrings
    TOJ 2641 Gene
    TOJ 2861 Octal Fractions
    TOJ 4394 Rebuild Road
  • 原文地址:https://www.cnblogs.com/CF1314/p/13924742.html
Copyright © 2011-2022 走看看