首页 > 其他 > 详细

07 Mybatis的多表查询

时间:2019-08-06 11:38:12      阅读:82      评论:0      收藏:0      [点我收藏+]

1.表与表之间的关系及其举例

表之间的关系有4种:一对多、多对一、一对一、多对多。
举例:
  (1)用户和订单就是一对多

    一个用户可以下多个订单
  (2)订单和用户就是多对一
    多个订单属于同一个用户

  (3)人和身份证号就是一对一
    一个人只能有一个身份证号
    一个身份证号只能属于一个人

  (4)老师和学生之间就是多对多
    一个学生可以被多个老师教过
    一个老师可以交多个学生

2.mybatis中的多表查询
示例:用户和账户
  一个用户可以有多个账户
  一个账户只能属于一个用户(多个账户也可以属于同一个用户)
步骤:
  1、建立两张表:用户表,账户表
    让用户表和账户表之间具备一对多的关系:需要使用外键在账户表中添加
  2、建立两个实体类:用户实体类和账户实体类
    让用户和账户的实体类能体现出来一对多的关系
  3、建立两个配置文件
    用户的配置文件
    账户的配置文件
  4、实现配置:
    当我们查询用户时,可以同时得到用户下所包含的账户信息
    当我们查询账户时,可以同时得到账户的所属用户信息

3.操作案例

(1)案例1

查询所有查询所有账户,及其用户名和地址信息(逻辑为:账户表account-----》用户信息表user)

<1>对数据库表Account对应的实体类Account.java进行改造,加入User对象作为成员变量

package domain;

import java.io.Serializable;

/**
 * 数据库的account表对应的实体类
 */
public class Account implements Serializable {
    private Integer id;
    private Integer uid;
    private Double money;
    //从表实体应该包含一个主表实体的对象引用
    private User user;

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.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;
    }

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

<2>IAccountDao中添加findAll()方法

package dao;

import domain.Account;
import domain.AccountUser;

import java.util.List;

public interface IAccountDao {

    /**
     * 查询所有查询所有账户,及其用户名和地址信息
     * @return
     */
    List<Account> findAll();

  
}

<3>IAccountDao.xml

ResultMap标签基本作用:建立SQL查询结果字段与实体属性的映射关系信息

标签属性id和type的含义:

  id:该resultMap的标志
  type:返回值的类名

子标签含义:

  id:用于设置主键字段与领域模型属性的映射关系,此处主键为ID,对应id。
  result:用于设置普通字段与领域模型属性的映射关系
  association 为关联关系,是实现一对一的关键
    1. property 为javabean中容器对应字段名     
    2. javaType 指定关联的类型,当使用select属性时,无需指定关联的类型
    3. select 使用另一个select查询封装的结果
    4. column 为数据库中的列名,与select配合使用

 

<?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="dao.IAccountDao">

    <resultMap id="accountUserMap" type="domain.Account">
        <id property="id" column="aid"></id>
        <result property="uid" column="uid"></result>
        <result property="money" column="money"></result>
        <!--配置所外键所关联表user的内容-->
        <association property="user" column="uid" javaType="domain.User">
            <id property="id" column="id"></id>
            <result property="username" column="username"></result>
            <result property="birthday" column="birthday"></result>
            <result property="sex" column="sex"></result>
            <result property="address" column="address"></result>
        </association>
    </resultMap>
    
    <!-- 查询所有查询所有账户,及其用户名和地址信息:方法1(更通用) -->
    <!--account a 给account表起一个别名-->
    <select id="findAll" resultMap="accountUserMap">
        select u.*,a.id as aid,a.uid,a.money from account a , user u where u.id = a.uid;
    </select>


</mapper>

<4>测试代码

package test;

import dao.IAccountDao;
import dao.IUserDao;
import domain.Account;
import domain.AccountUser;
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.InputStream;
import java.util.List;

public class MybatisTest01 {

    private InputStream in;
    private SqlSession sqlSession;
    private IAccountDao accountDao;

    /**
     * 初始化MyBatis
     * @throws Exception
     */
    public void initMyBatis() throws Exception{
        //1.读取配置文件
        in = Resources.getResourceAsStream("SqlMapConfig.xml");
        //2.创建SqlSessionFactory
        SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder(); //创建SqlSessionFactory的构建者builder
        SqlSessionFactory factory=builder.build(in);  //利用构建者builder创建SqlSessionFactory
        //3.使用工厂生产SqlSession对象
        sqlSession = factory.openSession();
        //4.使用SqlSessions对象创建Dao接口的代理对象
        accountDao = sqlSession.getMapper(IAccountDao.class);
    }

    /**
     * 释放资源
     * @throws Exception
     */
    public void destroy() throws Exception{
        sqlSession.commit();//提交事务
        sqlSession.close();
        in.close();
    }

    /**
     * 查询所有
     * @throws Exception
     */
    @Test
    public void testFindAll()throws Exception{
        initMyBatis();
        List<Account> accounts = accountDao.findAll();
        for (Account account : accounts) {
            System.out.println(account);
            System.out.println(account.getUser());
        }
        destroy();
    }

  
}

效果图:

技术分享图片

 

(2)案例2

查询所有查询用户信息,及其拥有的账户信息(逻辑为:用户信息表user-----》账户表account)

<1>对数据库表user对应的实体类User.java进行改造,加入List<Account>作为成员变量

package domain;

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

/**
 * 数据库表对应的实体类
 */
public class User implements Serializable {
    //实体类的成员变量名称应该与数据库中的列名一致
    private Integer id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;
    private List<Account> accounts;

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

    public void setAccounts(List<Account> accounts) {
        this.accounts = 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;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username=‘" + username + ‘\‘‘ +
                ", birthday=" + birthday +
                ", sex=‘" + sex + ‘\‘‘ +
                ", address=‘" + address + ‘\‘‘ +
                ‘}‘;
    }
}

<2>IUserDao中添加findAll()方法

package dao;

import domain.User;

import java.util.List;

/**
 *
 */
public interface IUserDao {
    /**
     * 查询所有
     * @return
     */
    List<User> findAll();

}

<3>IUserDao.xml

ResultMap标签基本作用:建立SQL查询结果字段与实体属性的映射关系信息

标签属性id和type的含义:

  id:该resultMap的标志
  type:返回值的类名

子标签含义:

  id:用于设置主键字段与领域模型属性的映射关系,此处主键为ID,对应id。
  result:用于设置普通字段与领域模型属性的映射关系
  association 为关联关系,是实现一对一的关键 
    1. property 为javabean中容器对应字段名     
    2. javaType 指定关联的类型,当使用select属性时,无需指定关联的类型
    3. select 使用另一个select查询封装的结果
    4. column 为数据库中的列名

  collection 为关联关系,是实现一对多的关键
    1. property 为javabean中容器对应字段名
    2. ofType 指定集合中元素的对象类型
    3. select 使用另一个查询封装的结果
    4. column 为数据库中的列名,与select配合使用

<?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="dao.IUserDao">

    <resultMap id="userAccountMap" type="domain.User">
        <id property="id" column="id"></id>
        <result property="username" column="username"></result>
        <result property="birthday" column="birthday"></result>
        <result property="sex" column="sex"></result>
        <result property="address" column="address"></result>
        <!--配置user对象中accounts集合的映射-->
        <collection property="accounts" ofType="domain.Account">
            <id property="id" column="aid"></id>
            <result property="uid" column="uid"></result>
            <result property="money" column="money"></result>
        </collection>
    </resultMap>
    <!-- 查询所有 -->
    <select id="findAll" resultMap="userAccountMap">
        select * from user u left outer join account a on u.id = a.uid
    </select>
    
</mapper>

<4>测试代码

package test;

import dao.IAccountDao;
import dao.IUserDao;
import domain.Account;
import domain.AccountUser;
import 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.Test;

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

public class MybatisTest02_User {

    private InputStream in;
    private SqlSession sqlSession;
    private IUserDao userDao;

    /**
     * 初始化MyBatis
     * @throws Exception
     */
    public void initMyBatis() throws Exception{
        //1.读取配置文件
        in = Resources.getResourceAsStream("SqlMapConfig.xml");
        //2.创建SqlSessionFactory
        SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder(); //创建SqlSessionFactory的构建者builder
        SqlSessionFactory factory=builder.build(in);  //利用构建者builder创建SqlSessionFactory
        //3.使用工厂生产SqlSession对象
        sqlSession = factory.openSession();
        //4.使用SqlSessions对象创建Dao接口的代理对象
        userDao = sqlSession.getMapper(IUserDao.class);
    }

    /**
     * 释放资源
     * @throws Exception
     */
    public void destroy() throws Exception{
        sqlSession.commit();//提交事务
        sqlSession.close();
        in.close();
    }

    /**
     * 查询所有
     * @throws Exception
     */
    @Test
    public void testFindAll()throws Exception{
        initMyBatis();
        List<User> users = userDao.findAll();
        for (User user : users) {
            System.out.println(user);
            System.out.println(user.getAccounts());
        }
        destroy();
    }

}

效果图:

技术分享图片

07 Mybatis的多表查询

原文:https://www.cnblogs.com/luckyplj/p/11307874.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!