Mybatis框架学习(八)多表操作

表之间的关系有几种:

  1. 一对多
  2. 多对一
  3. 一对一
  4. 多对多

环境准备

  1. 数据库
 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;

2.创建实体类Account

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 +
                '}';
    }
}

  1. 创建Dao接口
public interface IAccountDao {

    List<Account> findAll();

    List<AccountUser> findAccount();
}
  1. 创建接口配置文件
<?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.lwb.dao.IAccountDao">
    <!--查询所有-->
    <select id="findAll" resultType="com.lwb.domain.Account">
        SELECT * FROM account
    </select>


</mapper>
  1. 配置SqlMapConfig.xml文件中的Mapper
        <mapper resource="com/lwb/dao/IAccountDao.xml"></mapper>

一对一查询

  1. 第一种方式:为了能够封装上面 SQL 语句的查询结果,定义 AccountCustomer 类中要包含账户信息同时还要包含用户信息,所以我们要在定义 AccountUser 类时可以继承 Account 类
  • 创建AccountUser实体类继承Account类
public class AccountUser extends Account {
    private String username;
    private String address;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return super.toString() +
                "username='" + username + '\'' +
                ", address='" + address + '\'' +
                '}';
    }
}

  • 在接口IAccountDao创建方法
    List<AccountUser> findAccount();
  • 配置接口配置文件
    <!--查询账户信息-->
    <select id="findAccount" resultType="com.lwb.domain.AccountUser">
       select account.*,user.username,user.address from user,account where user.id = account.uid;
    </select>
  • 测试
    @Test
    public void test8()throws Exception {

        // 第五步:执行dao中的方法
        List<AccountUser> accountUser = accountDao.findAccount();
        for (AccountUser account: accountUser) {
            System.out.println(account.toString());
        }

    }

在这里插入图片描述

  1. 第二种方式:使用 resultMap,定义专门的 resultMap 用于映射一对一查询结果。通过面向对象的(has a)关系可以得知,我们可以在 Account 类中加入一个 User 类的对象来代表这个账户是哪个用户的。
  • 在Account实体类中加入User类
    在这里插入图片描述
  • 在IAcountDao接口里修改方法
    在这里插入图片描述
  • 在配置文件里面设置
<mapper namespace="com.lwb.dao.IAccountDao">
    <resultMap id="AccountUser" type="com.lwb.domain.Account">
        <!--建立对应关系-->
        <id property="id" column="aid"></id>
        <result column="uid" property="uid"/>
        <result column="money" property="money"/>
        <!--指定从表中引用的实体类-->
        <association property="user" javaType="com.lwb.domain.User">
            <id property="id" column="id"></id>
            <result column="username" property="username"/>
            <result column="sex" property="sex"/>
            <result column="birthday" property="birthday"/>
            <result column="address" property="address"/>
        </association>
    </resultMap>

    <!--查询所有-->
    <select id="findAll" resultType="com.lwb.domain.Account">
        SELECT * FROM account
    </select>

    <!--查询账户信息-->
    <!--<select id="findAccount" resultType="com.lwb.domain.AccountUser">-->
       <!--select account.*,user.username,user.address from user,account where user.id = account.uid;-->
    <!--</select>-->
    <select id="findAccount" resultMap="AccountUser">
        select u.*,a.id as aid,a.uid,a.money from account a,user u where a.uid =u.id;
    </select>


</mapper>
  • 测试
    @Test
    public void test7()throws Exception {

        // 第五步:执行dao中的方法
        List<Account> accounts = accountDao.findAccount();
        for (Account account: accounts) {
            System.out.println(account.toString()+account.getUser());
        }

    }

在这里插入图片描述

一对多的查询

  1. 用户信息和他的账户信息为一对多关系,并且查询过程中如果用户没有账户信息,此时也要将用户信息查询出来,我们想到了左外连接查询比较合适
  2. User 类 类入 加入 List<Account>
    在这里插入图片描述
  3. 用户持久层 Dao 接口 中加入查询方法
    在这里插入图片描述
  4. 用户持久层 Dao 映射文件
  • collection:部分定义了用户关联的账户信息。表示关联查询结果集
  • property=“accList” :关联查询的结果集存储在 User 对象的上哪个属性。
  • ofType=“account” :指定关联查询的结果集中的对象类型即List中的对象类型。此处可以使用别名,也可以使用全限定名。
 <resultMap id="UserAccount" type="com.lwb.domain.User">
        <id property="id" column="id"></id>
        <result column="username" property="username"/>
        <result column="sex" property="sex"/>
        <result column="birthday" property="birthday"/>
        <result column="address" property="address"/>
        <collection property="accounts" ofType="com.lwb.domain.Account">
            <id property="id" column="aid"></id>
            <result column="uid" property="uid"/>
            <result column="money" property="money"/>
        </collection>
    </resultMap>
    <!--查询所有-->
    <select id="findAll" resultMap="UserAccount">
        select u.*,a.id as aid ,a.uid,a.money from user u left outer join account
a on u.id =a.uid
    </select>
  1. 测试
    在这里插入图片描述

多对多的查询

在这里插入图片描述

  • 查询角色我们需要用到Role表,但角色分配的用户的信息我们并不能直接找到用户信息,而是要通过中间表(USER_ROLE 表)才能关联到用户信息。
  1. 数据库
CREATE TABLE `role` (
  `ID` int(11) NOT NULL COMMENT '编号',
  `ROLE_NAME` varchar(30) default NULL COMMENT '角色名称',
  `ROLE_DESC` varchar(60) default NULL COMMENT '角色描述',
  PRIMARY KEY  (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

insert  into `role`(`ID`,`ROLE_NAME`,`ROLE_DESC`) values (1,'院长','管理整个学院'),(2,'总裁','管理整个公司'),(3,'校长','管理整个学校');

CREATE TABLE `user_role` (
  `UID` int(11) NOT NULL COMMENT '用户编号',
  `RID` int(11) NOT NULL COMMENT '角色编号',
  PRIMARY KEY  (`UID`,`RID`),
  KEY `FK_Reference_10` (`RID`),
  CONSTRAINT `FK_Reference_10` FOREIGN KEY (`RID`) REFERENCES `role` (`ID`),
  CONSTRAINT `FK_Reference_9` FOREIGN KEY (`UID`) REFERENCES `user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

insert  into `user_role`(`UID`,`RID`) values (41,1),(45,1),(41,2);

  1. 创建实体类Role,并且在user实体类中添加Role集合
public class Role implements Serializable{
    private Integer id;
    private String role_name;
    private String role_desc;

    private List<User> users;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getRole_name() {
        return role_name;
    }

    public void setRole_name(String role_name) {
        this.role_name = role_name;
    }

    public String getRole_desc() {
        return role_desc;
    }

    public void setRole_desc(String role_desc) {
        this.role_desc = role_desc;
    }

    public List<User> getUsers() {
        return users;
    }

    public void setUsers(List<User> users) {
        this.users = users;
    }

    @Override
    public String toString() {
        return "Role{" +
                "id=" + id +
                ", role_name='" + role_name + '\'' +
                ", role_desc='" + role_desc + '\'' +
                '}';
    }
}

在这里插入图片描述

  1. 创建IRoleDao接口
public interface IRoleDao {

    List<Role> findAll();
}
  1. 配置IRoleDao的配置文件和IUserDao的配置文件
  • IRoleDao.xml
<mapper namespace="com.lwb.dao.IRoleDao">
    <resultMap id="RoleUser" type="com.lwb.domain.Role">
        <id property="id" column="rid"/>
        <result property="role_name" column="role_name"/>
        <result property="role_desc" column="role_desc"/>
        <collection property="users" ofType="com.lwb.domain.User">
            <id property="id" column="id"></id>
            <result column="username" property="username"/>
            <result column="sex" property="sex"/>
            <result column="birthday" property="birthday"/>
            <result column="address" property="address"/>
        </collection>
    </resultMap>
    <select id="findAll" resultMap="RoleUser">
        SELECT u.*,r.id AS rid,r.role_name,r.role_desc FROM ROLE r LEFT JOIN USER_ROLE ur ON ( r.id = ur.rid) LEFT JOIN USER u ON (ur.uid = u.id)
    </select>
</mapper>
  • IUserDao.xml
    <resultMap id="UserRole" type="com.lwb.domain.User">
        <id property="id" column="id"></id>
        <result column="username" property="username"/>
        <result column="sex" property="sex"/>
        <result column="birthday" property="birthday"/>
        <result column="address" property="address"/>
        <collection property="roles" ofType="com.lwb.domain.Role">
            <id property="id" column="rid"/>
            <result property="role_name" column="role_name"/>
            <result property="role_desc" column="role_desc"/>
        </collection>
    </resultMap>
        <!--查询所有用户以及他们的角色-->
    <select id="findUserAndRole" resultMap="UserRole">
         SELECT u.*,r.id AS rid,r.role_name,r.role_desc FROM User u LEFT JOIN USER_ROLE ur ON ( u.id = ur.uid) LEFT JOIN role r ON (ur.rid = r.id)
    </select>

  1. 测试
  • 根据角色获取角色和相应的用户信息
   @Test
    public void test9()throws Exception {

        // 第五步:执行dao中的方法
        List<Role> roles = roleDao.findAll();
        for (Role role : roles) {
            System.out.println("--每个角色---");
            System.out.println(role);
            System.out.println(role.getUsers());
        }

    }

在这里插入图片描述

  • 每个用户对应的角色
    @Test
    public void test10()throws Exception {

        // 第五步:执行dao中的方法
        // List<User> users=  dao.findByName("%王%");
        List<User> users =  dao.findUserAndRole();
        for(User user:users) {
            System.out.println("----每一个用户------");
            System.out.println(user);
            System.out.println(user.getRoles());
        }

    }

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_41816516/article/details/106738186