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

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

相关推荐
优化控制仿真模型1 小时前
【社工】初级社会工作者历年真题及答案解析PDF电子版(2010-2025年)
经验分享·pdf
林下月光1 小时前
从地震数据提取子波
经验分享
user_admin_god2 小时前
SSE 流式响应 Chunk 被截断问题的排查与修复
java·人工智能·spring boot·spring·maven·mybatis
ECT-OS-JiuHuaShan2 小时前
整体论体系定理,全球开放,无法绕过
人工智能·科技·学习·算法·生活
AI_661465972 小时前
副业平台收益效率评估:实验设计、指标体系与数据分析框架
经验分享·笔记
阿星_2 小时前
Windows Subsystem for Linux (WSL) 运行 Firefox 浏览器时遇到中文乱码的解决方法
笔记
淘矿人3 小时前
2026年4月-DeepSeek V4 vs GPT-5.5深度对比测评:weelinking一键切换实测
服务器·数据库·人工智能·python·gpt·学习·php
老花眼猫3 小时前
三角函数绘制椭圆和椭圆旋转
c语言·经验分享·青少年编程·课程设计
一只机电自动化菜鸟3 小时前
一建机电备考笔记(27)测量技术—仪器(含考频+题型)
经验分享·笔记·学习·职场和发展·求职招聘·课程设计