#MyBatis_一以多查询 @FDDLC

一个用户可能对应多个账户,因此用户与账户存在一对多的关系。

#MyBatis_一以多查询 @FDDLC

关键配置:

<resultMap id="userWithAccount" type="cn.liuxingchang.domain.User">
    <id property="id" column="id" />
    <result property="name" column="name" />
    <result property="age" column="age" />
    <collection property="accounts" ofType="cn.liuxingchang.domain.Account">
        <id property="id" column="aid" />
        <result property="money" column="money" />
    </collection>
</resultMap>
<select id="findAll" resultMap="userWithAccount">
    select u.*, a.id as aid, money from user u left outer join account a on u.id = a.uid
</select>

说明:

1、上面这个findAll的结果是List集合(List<User>)。

2、要用左外连接left outer join(如果user表在account表右边就用右外连接),不能用where接条件,而是用on!

3、一个用户可能有多个账户,因此User类里有个类型为List<Account>的accounts成员。给User类中的id、name、age赋值很简单,怎么把数据封装到这个accounts成员呢?于是来了个配了个resultMap标签。resultMap标签里的collection子标签是重头戏!MyBatis就是通过collection来给accounts成员赋值的!collection标签里的property="accounts"好理解,就是User类里的accounts成员呗!ofType属性是说集合里的元素属于什么类型。另外,这个collection其实相当于是一种嵌套版的resultMap标签哈!

 


最后附上源码:

 

项目结构:

#MyBatis_一以多查询 @FDDLC

 

数据库的相关信息:

MySQL:8.0.16    port:3306    database:multi_table

account表:

#MyBatis_一以多查询 @FDDLC

user表:

#MyBatis_一以多查询 @FDDLC

 

Account类:

package cn.liuxingchang.domain;

import java.io.Serializable;

public class Account implements Serializable {
    private Integer id;
    private Integer uid;
    private Double money;

    public Integer getId() {
        return id;
    }

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

    public Integer getUid() {
        return uid;
    }

    public void setUid(Integer uid) {
        this.uid = uid;
    }

    public Double getMoney() {
        return money;
    }

    public void setMoney(Double money) {
        this.money = money;
    }


    @Override
    public String toString() {
        return "Account{" +
                "id=" + id +
                ", uid=" + uid +
                ", money=" + money +
                '}';
    }
}

 

User类:

package cn.liuxingchang.domain;

import java.io.Serializable;
import java.util.List;

public class User implements Serializable {
    private Integer id;
    private String name;
    private Integer age;
    private List<Account> accounts;

    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 Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public List<Account> getAccounts() {
        return accounts;
    }

    public void setAccounts(List<Account> accounts) {
        this.accounts = accounts;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", accounts=" + accounts +
                '}';
    }
}

 

UserDao接口

package cn.liuxingchang.dao;

import cn.liuxingchang.domain.User;

import java.util.List;

public interface UserDao {
    List<User> findAll();
}

 

UserMapper.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="cn.liuxingchang.dao.UserDao">
    <resultMap id="userWithAccount" type="cn.liuxingchang.domain.User">
        <id property="id" column="id" />
        <result property="name" column="name" />
        <result property="age" column="age" />
        <collection property="accounts" ofType="cn.liuxingchang.domain.Account">
            <id property="id" column="aid" />
            <result property="money" column="money" />
        </collection>
    </resultMap>
    <select id="findAll" resultMap="userWithAccount">
        select u.*, a.id as aid, money from user u left outer join account a on u.id = a.uid
    </select>
</mapper>

 

mybatis.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

    <environments default="mysql">
        <environment id="mysql">
            <transactionManager type="JDBC"></transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/multi_table?characterEncoding=UTF8&amp;serverTimezone=Asia/Shanghai"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <mapper resource="mapper/UserMapper.xml" />
    </mappers>
</configuration>

 

pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>P075_MyBatis_One2Many</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.16</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.5</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

</project>

 

Test.java:

import cn.liuxingchang.dao.UserDao;
import cn.liuxingchang.domain.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;

import java.io.InputStream;
import java.util.List;

public class Test {
    private InputStream in;
    private SqlSessionFactory factory;
    private SqlSession sqlSession;
    private UserDao userDao;

    @Before
    public void before() throws Exception {
        in = Resources.getResourceAsStream("mybatis.xml");
        factory = new SqlSessionFactoryBuilder().build(in);
        sqlSession = factory.openSession();
        userDao = sqlSession.getMapper(UserDao.class);
    }

    @After
    public void after() throws Exception {
        sqlSession.commit();
        sqlSession.close();
        in.close();
    }

    @org.junit.Test
    public void findAllTest() {
        List<User> users = userDao.findAll();
        for (User user : users) {
            System.out.println(user);
        }
    }
}