#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标签哈!
最后附上源码:
项目结构:
数据库的相关信息:
MySQL:8.0.16 port:3306 database:multi_table
account表:
user表:
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&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); } } }