MyBatis learning summary (9): MyBatis many-to-many query

Many-to-many is not implemented in MyBatis, because many-to-many cascades can be replaced by two one-to-many cascades. In real life, one order can have multiple products, and one product can correspond to multiple orders. The relationship between orders and products is many-to-many. Similarly, one person can have multiple identities, and one identity can be owned by multiple people. If MyBatis wants to achieve many-to-many, it needs to use an intermediate table to convert the many-to-many into two one-to-many relationships. The cases in this article will use the relationship between people and identities to achieve many-to-many.

(1) Create database tables and intermediate tables.

CREATE TABLE `t_people` (
  `pid` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(20) DEFAULT NULL,
  `address` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`pid`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
INSERT INTO `t_people` VALUES (1,'tom','北京'),(2,'jerry','天津'),(3,'李承','湖南');
CREATE TABLE `t_role` (
  `rid` int(11) NOT NULL AUTO_INCREMENT,
  `act` varchar(20) DEFAULT NULL,
  PRIMARY KEY (`rid`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
INSERT INTO `t_role` VALUES (1,'教师'),(2,'公务员'),(3,'大将军'),(4,'市长');
CREATE TABLE `t_peoplerole` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `pid` int(11) DEFAULT NULL,
  `rid` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;
INSERT INTO `t_peoplerole` VALUES (1,1,3),(2,2,2),(3,2,4),(4,3,3),(5,1,1),(6,1,4);

(2) Create People class and Role class

People class:

public class People {
    private Integer id;
    private String name;
    private String address;
    private List<Role> roleList;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public List<Role> getRoleList() {
        return roleList;
    }

    public void setRoleList(List<Role> roleList) {
        this.roleList = roleList;
    }

    @Override
    public String toString() {
        return "People{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", address='" + address + '\'' +
                ", roleList=" + roleList +
                '}';
    }
}

Role class:

public class Role {
    private Integer id;
    private String act;
    private List<People> peopleList;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getAct() {
        return act;
    }

    public void setAct(String act) {
        this.act = act;
    }

    public List<People> getPeopleList() {
        return peopleList;
    }

    public void setPeopleList(List<People> peopleList) {
        this.peopleList = peopleList;
    }

    @Override
    public String toString() {
        return "Role{" +
                "id=" + id +
                ", act='" + act + '\'' +
                ", peopleList=" + peopleList +
                '}';
    }
}

(3) Create the IPeopleDao class

public interface IPeopleDao {
    List<People> findAllPeople();
}

(4) Create peopleMapper.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">
<!--namespace:指定了唯一的命名空间-->
<mapper namespace="com.day1.dao.IPeopleDao">
    <resultMap id="peopleRole" type="com.day1.entity.People">
        <id property="id" column="pid"></id>
        <result property="name" column="name"></result>
        <result property="address" column="address"></result>
        <collection property="roleList" ofType="com.day1.entity.Role" resultMap="role"></collection>
    </resultMap>
    <resultMap id="role" type="com.day1.entity.Role">
        <id property="id" column="rid"></id>
        <result property="act" column="act"></result>
    </resultMap>
    <select id="findAllPeople" resultMap="peopleRole">
        select p.*, r.* from t_people p, t_role r, t_peoplerole pr where p.pid = pr.pid and pr.rid = r.rid;
    </select>
</mapper>

(5) Configure the peopleMapper.xml file in SqlMapperConfig.xml

        <mapper resource="com/day1/peopleMapper.xml"></mapper>

(6) Test

    @Test
    public void testSelect() throws IOException {
        //1、读取配置文件
        InputStream in = Resources.getResourceAsStream("SqlMapperConfig.xml");
        //2、创建SqlSessionFactory工厂
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory factory = builder.build(in);
        //3、使用工厂生产SqlSession对象
        SqlSession sqlSession = factory.openSession();
        //4、使用SqlSession创建dao接口的代理对象
        IPeopleDao peopleDao= sqlSession.getMapper(IPeopleDao.class);
        //5、使用代理对象执行方案
        List<People> peopleList = peopleDao.findAllPeople();
        for(People people : peopleList){
            System.out.println(people);
        }
        //6、释放资源
        sqlSession.close();
        in.close();
    }

Regarding the reason why only one piece of data appears in the many-to-many query or the problem caused by the same primary key names of the two tables I mentioned in the previous article (the primary key names of t_people and t_role are both id), this is a need to pay attention to The place. When the primary key names are inconsistent, this problem will not occur, that is, the primary key of t_people is pid, and the primary key of t_role is rid.

Guess you like

Origin blog.csdn.net/weixin_47382783/article/details/113838774