MyBatis之多对多联合查询

摘要:
本文详细记录了SpringBoot整合MyBatis之多对多联合查询,从实体类、接口类、配置文件以及接口测试。

相关环境:
SpringBoot + MyBatis


1. 什么是多对多关系?

多对多关系:多对多关系是关系数据库中两个表之间的一种关系, 该关系中第一个表中的一个行可以与第二个表中的一个或多个行相关。第二个表中的一个行也可以与第一个表中的一个或多个行相关。

举例:博客与博客标签的多对多关系

2. 具体配置

2.1 pom.xml
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.1</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-api</artifactId>
            <version>5.3.1</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

2.2 application.yml
mybatis:
  configuration:
    map-underscore-to-camel-case: true
  mapper-locations: classpath*:mapper/**/*.xml
  type-aliases-package: com.mzr.blog.dao

3. 表设计

blog表
博客表:t_blog
Tag表
标签表:t_tag
blog_tags表:
博客标签关系表:t_blogs_tags

4. 实体类(pojo):

4.1 博客类:
//Blog类

@Getter
@Setter
@ToString
public class Blog {
    private Long id;    //博客编号
    private Integer views;  //浏览次数
    private String description; //博客描述
    private String firstPicture;    //博客首图
    private String flag;    //博客标记
    private String title;   //博客标题
    private Boolean appreciation;   //博客赞赏是否开启
    private Boolean commendable;   //博客评论是否开启
    private Boolean published;  //是否发布
    private Boolean recommend;  //是否推荐
    private Boolean shareStatement; //转载声明是否开启
    private Date createTime;    //创建时间
    private Date updateTime;    //更新时间
    private Long typeId;    //博客类别编号
    private Long userId;    //用户编号
    private String content; //博客内容
    private Type type;  //博客类别
    private User user;  //用户
    private List<Comment> comments = new ArrayList<>();	//博客评论
    private List<Tag> tags = new ArrayList<>(); //博客标签,多对多关系
}
4.2 标签类:
//Tag类

@Getter
@Setter
@ToString
public class Tag {
    private Long id;    //标签编号
    private String name;    //标签名
}
dao层(mapper):
@Mapper
@Component
public interface BlogMapper {
    //根据标签id查询博客
    List<Blog> listBlogByTagId(@Param("tagId") Long tagId);
}

Service层:

public interface BlogService {
	List<Blog> findBlogsByTagId(Long tagId);
}

接口实例(BlogServiceImpl ):

@Service
public class BlogServiceImpl implements BlogService {

    @Autowired
    private BlogMapper blogMapper;
    
    @Override
    public List<Blog> findBlogsByTagId(Long tagId) {
        return blogMapper.listBlogByTagId(tagId);
    }
}

BlogMapper.xml(博客实体映射文件):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mzr.blog.dao.BlogMapper">
  <!--自定义结果映射-->
  <resultMap id="TagWithBlogResult" type="com.mzr.blog.pojo.Blog">
    <id property="id" column="id" />
    <result column="appreciation" property="appreciation" />
    <result column="commendable" property="commendable" />
    <result column="create_time" property="createTime" />
    <result column="description" property="description" />
    <result column="first_picture" property="firstPicture" />
    <result column="content" property="content" />
    <result column="flag" property="flag" />
    <result column="published" property="published" />
    <result column="recommend" property="recommend" />
    <result column="share_statement" property="shareStatement" />
    <result column="title" property="title" />
    <result column="update_time" property="updateTime" />
    <result column="views" property="views" />
    <result column="type_id" property="typeId" />
    <result column="user_id" property="userId" />
    <!-- 指定联合查询出对博客信息-->
    <association property="type" javaType="com.mzr.blog.pojo.Type">
      <id column="id" property="id"></id>
      <result column="name" property="name"/>
    </association>
    <!-- 指定联合查询出对用户信息-->
    <association property="user" javaType="com.mzr.blog.pojo.User">
      <id column="id" property="id"></id>
      <result column="avatar" property="avatar"/>
      <result column="nickname" property="nickname"/>
      <result column="email" property="email"/>
    </association>
    <!--多表关联-->
    <collection property="tags" ofType="com.mzr.blog.pojo.Tag" column="id" select="com.mzr.blog.dao.TagMapper.findTagById">
    </collection>
  </resultMap>

  <!--根据标签查询博客以及博客类别和博主-->
  <select id="listBlogByTagId" parameterType="java.lang.Long" resultMap="TagWithBlogResult">
    select distinct tb.*,tu.*,tp.*,tt.* from t_blog tb
            left join t_blog_tags tbt on tb.id = tbt.blogs_id
            left join t_tag tt on tt.id = tbt.tags_id
            left join t_user tu on tu.id = tb.user_id
			left join t_type tp on tp.id = tb.type_id
            where tt.id = #{tagId}
  </select>
</mapper>

TagMapper.xml(标签实体映射文件):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mzr.blog.dao.TagMapper">
  <resultMap id="BaseResultMap" type="com.mzr.blog.pojo.Tag">
    <result column="id" jdbcType="BIGINT" property="id" />
    <result column="name" jdbcType="VARCHAR" property="name" />
  </resultMap>
  
  <select id="findTagById" resultMap="BaseResultMap" parameterType="java.lang.Long">
    select * from t_tag where id in(select tags_id from t_blog_tags WHERE blogs_id = #{id})
  </select>

</mapper>

5. 编写测试类

import com.mzr.blog.service.BlogService;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class MapperTest {

   @Autowired
    private BlogService blogServiceImpl;

    /**
     * 测试BlogMapper
     */

    @Before
    public void init() {
        System.out.println("-----------------开始测试-----------------");
    }

    @After
    public void after() {
        System.out.println("-----------------测试结束-----------------");
    }

    @Test
    public void testListBlogByTagId(){
        System.out.println(blogServiceImpl.findBlogsByTagId(Long.parseLong("3")));
    }

}

结果如下 (去除部分字段):

-----------------开始测试-----------------
[Blog(id=1,  title=学习日志, type=Type(id=1, name=后端), user=User(id=1, nickname=Ryan), tags=[Tag(id=7, name=Spring), Tag(id=3, name=Java)])]
-----------------测试结束-----------------
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值