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. 多对多查询

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

相关推荐
fake_ss1988 小时前
AI时代学习全栈项目开发的新范式
java·人工智能·学习·架构·个人开发·学习方法
Upsy-Daisy9 小时前
AI Agent 项目学习笔记(二):Spring AI 与 ChatClient 主链路解析
人工智能·笔记·学习
C+++Python10 小时前
C++ 进阶学习完整指南
java·c++·学习
杨浦老苏10 小时前
AI原生笔记应用Tolaria
笔记·ai·markdown·obsidian
中屹指纹浏览器11 小时前
浏览器网络栈隔离技术研究:TCP/IP底层指纹生成与规避原理
经验分享·笔记
sulikey11 小时前
个人Linux操作系统学习笔记2 - gcc与库的理解
linux·笔记·学习·操作系统·gcc·
南浦别a11 小时前
第102天--时隔多日的书写
学习·程序人生
Jackyzhe11 小时前
从零学习Kafka:消费者组重平衡
分布式·学习·kafka
吃好睡好便好11 小时前
在Creo中如何把新建零件文件时的默认模板设置为公制单位
学习·3d·信息可视化
优橙教育12 小时前
5G网络优化关键参数解读:从入门到实战
网络·学习·5g