MyBatis学习(五)

一对多查询

1. 多表设计

一对一 ,一对一可以设计成一张表结构

一对多

多对一

多对多

2. 搭建开发的环境

以用户(User)和账户(Account)为例,一个用户可以有多个账户。

2.1执行建表语句

sql 复制代码
CREATE TABLE `user` (
  `id` int(11) NOT NULL auto_increment,
  `username` varchar(32) NOT NULL COMMENT '用户名称',
  `birthday` datetime default NULL COMMENT '生日',
  `sex` char(1) default NULL COMMENT '性别',
  `address` varchar(256) default NULL COMMENT '地址',
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

insert  into `user`(`id`,`username`,`birthday`,`sex`,`address`) values (1,'老王','2018-02-27 17:47:08','男','北京'),(2,'熊大','2018-03-02 15:09:37','女','上海'),(3,'熊二','2018-03-04 11:34:34','女','深圳'),(4,'光头强','2018-03-04 12:04:06','男','广州');

CREATE TABLE `account` (
  `ID` int(11) NOT NULL COMMENT '编号',
  `UID` int(11) default NULL COMMENT '用户编号',
  `MONEY` double default NULL COMMENT '金额',
  PRIMARY KEY  (`ID`),
  KEY `FK_Reference_8` (`UID`),
  CONSTRAINT `FK_Reference_8` FOREIGN KEY (`UID`) REFERENCES `user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

insert  into `account`(`ID`,`UID`,`MONEY`) values (1,1,1000),(2,2,1000),(3,2,2000);

2.2编写Account的JavaBean类

java 复制代码
package com.qcby.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;
    }
}

2.3编写AccountMapper接口

java 复制代码
 
package com.qcby.mapper;
​
public interface AccountMapper {
    
}

2.4编写AccountMapper.xml的配置文件

java 复制代码
 
<?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.qcby.mapper.AccountMapper">
​
</mapper>

2.5主配置文件中引入映射配置文件

java 复制代码
 
<!--引入映射配置文件-->
<mappers>
    <mapper resource="mappers/UserMapper.xml" />
    <mapper resource="mappers/AccountMapper.xml" />
</mappers>
​

3. 多对一查询(一对一查询)

需求:查询账户信息时,同时查询出所属用户的名称和地址。

3.1在Account类中添加user的属性,表示该帐户只属于这个用户

java 复制代码
package com.qcby.domain;
​
import java.io.Serializable;
​
/**
 * 账号
 */
public class Account implements Serializable{
    
    private Integer id;
    private Integer uid;
    private Double money;
​
    // 用户
    private User user;
​
    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;
    }
​
    public User getUser() {
        return user;
    }
​
    public void setUser(User user) {
        this.user = user;
    }
}

3.2在AccountMapper接口中编写查询的方法

java 复制代码
 
package com.qcby.mapper;
​
import com.qcby.domain.Account;
​
import java.util.List;
​

public interface AccountMapper {
​
    public List<Account> findAll();
​
}

3.4编写配置文件

java 复制代码
 
<?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.qcby.mapper.AccountMapper">
​
    <!--内连接查询-->
    <select id="findAll" resultMap="accountMap">
        select a.*,u.username,u.address from account a,user u where a.uid = u.id
    </select>
​
    <!--进行数据封装-->
    <resultMap id="accountMap" type="com.qcby.domain.Account">
        <result property="id" column="id" />
        <result property="uid" column="uid"/>
        <result property="money" column="money"/>
        <association property="user" javaType="com.qcby.domain.User">
            <result property="username" column="username"/>
            <result property="address" column="address"/>
        </association>
    </resultMap>
​
</mapper>

3.5测试方法

java 复制代码
package com.qcby.test;
​
import com.qcby.domain.Account;
import com.qcby.mapper.AccountMapper;
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.Test;
​
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
​
/**
 *
 * 
 *
 * 测试账号相关
 */
public class Test02 {
​
    /**
     * 多对一查询
     * @throws IOException
     */
    @Test
    public void testFindAll() throws IOException {
        // 先加载主配置文件,加载到输入流中
        InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        // 创建SqlSessionFactory对象,创建SqlSession对象
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
        // 创建SqlSession对象
        SqlSession session = factory.openSession();
        // 获取代理对象
        AccountMapper mapper = session.getMapper(AccountMapper.class);
        // 查询
        List<Account> list = mapper.findAll();
        // 遍历
        for (Account account : list) {
            System.out.println(account);
        }
​
        // 关闭资源
        session.close();
        inputStream.close();
    }
​
}

4. 一对多查询

**需求:**如果想查询 select u.*,a.money from user u left join account a on u.id = a.uid 语句的内容

3.1在User类中添加List的属性

java 复制代码
package com.qcby.domain;
​
import java.io.Serializable;
import java.util.Date;
import java.util.List;
​
/**
 * 
 * 
 *
 * 实现类  推荐使用序列化接口 HttpSession序列化
 */
public class User implements Serializable{
​
    // 主键
    private Integer id;
    // 用户名
    private String username;
    // 生日
    private Date birthday;
    // 性别
    private String sex;
    // 地址
    private String address;
​
    // 演示foreach标签
    private List<Integer> ids;
    
    // 演示一对多查询
    private List<Account> accounts;
​
    public Integer getId() {
        return id;
    }
​
    public void setId(Integer id) {
        this.id = id;
    }
​
    public String getUsername() {
        return username;
    }
​
    public void setUsername(String username) {
        this.username = username;
    }
​
    public Date getBirthday() {
        return birthday;
    }
​
    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
​
    public String getSex() {
        return sex;
    }
​
    public void setSex(String sex) {
        this.sex = sex;
    }
​
    public String getAddress() {
        return address;
    }
​
    public void setAddress(String address) {
        this.address = address;
    }
​
    public List<Integer> getIds() {
        return ids;
    }
​
    public void setIds(List<Integer> ids) {
        this.ids = ids;
    }
​
    public List<Account> getAccounts() {
        return accounts;
    }
​
    public void setAccounts(List<Account> accounts) {
        this.accounts = accounts;
    }
​
    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", birthday=" + birthday +
                ", sex='" + sex + '\'' +
                ", address='" + address + '\'' +
                ", ids=" + ids +
                ", accounts=" + accounts +
                '}';
    }
}

3.2在UserMapper接口中定义方法

java 复制代码
public interface UserMapper {
    // 查询一对多
    public List<User> findOneToMany();
}

3.3编写配置文件

java 复制代码
 <!--一对多查询-->
    <select id="findOneToMany" resultMap="userMap">
        select u.*,a.money from user u left join account a on u.id = a.uid
    </select>
​
    <resultMap type="com.qcby.domain.User" id="userMap">
        <result property="id" column="id"/>
        <result property="username" column="username"/>
        <result property="birthday" column="birthday"/>
        <result property="sex" column="sex"/>
        <result property="address" column="address"/>
        <collection property="accounts" ofType="com.qcby.domain.Account">
            <result property="money" column="money"/>
        </collection>
    </resultMap>

3.5编写测试的方法

java 复制代码
  /**
     * 一对多查询
     */
    @Test
    public void testOneToMany() throws IOException {
        // 先加载主配置文件,加载到输入流中
        InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        // 创建SqlSessionFactory对象,创建SqlSession对象
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
        // 创建SqlSession对象
        SqlSession session = factory.openSession();
        UserMapper mapper = session.getMapper(UserMapper.class);
        List<User> list = mapper.findOneToMany();
        // 遍历list集合
        for (User user : list) {
            System.out.println(user);
        }
        // 关闭资源
        session.close();
        inputStream.close();
    }

5. 多对多查询

可以看成一对多查询,与一对多一样

相关推荐
a11177634 分钟前
2FA 验证码生成器(github登录验证 app)
笔记·学习
我的xiaodoujiao1 小时前
API 接口自动化测试详细图文教程学习系列32--Allure测试报告2
python·学习·测试工具·pytest
破碎的南瓜2 小时前
sqli--sql注入过关笔记(1,2,3,4,5,9)
数据库·笔记·sql
你想知道什么?3 小时前
线性回归-学习笔记
笔记·学习·线性回归
鱼毓屿御3 小时前
从「只会聊」到「边想边做」的跃迁
前端·学习·react.js
谙弆悕博士3 小时前
系统集成项目管理工程师教程(第3版)笔记——第17章:法律法规和标准规范
笔记·职场和发展·学习方法·业界资讯·软考·法律·法规
AOwhisky4 小时前
Python 学习笔记(第十五期)——运维自动化(下·后篇):堡垒机实战——paramiko高阶篇
运维·python·学习·云原生·自动化·运维开发
谙弆悕博士4 小时前
系统集成项目管理工程师教程(第3版)笔记——第4章:信息系统架构
笔记·系统架构·项目管理·创业创新·学习方法·业界资讯·物理
minglie15 小时前
zynq中linux系统的自动登录和免密登录
学习
茯苓gao6 小时前
嵌入式开发笔记:Qt信号槽机制深度解析——从原理到实战的全方位指南
开发语言·笔记·嵌入式硬件·qt·学习