Mybatis多表查询

在数据库中表具有以下几种关系:

	一对多	
	多对一
	一对一
	多对多

前期准备,我们需要在数据库中添加账户表:

DROP TABLE IF EXISTS `account`;
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,46,1000),(2,45,1000),(3,46,2000);

分析账户和用户的关系:可得一个用户可以有一个或者多个账户,那么每个账户都有一个用户对应。则可以看出来 多对一是一种特殊的一对一。

一对一(多对一)查询

查询所有账户信息,并且查询下单用户信息。

**方式一:**通过继承实现

  1. 定义账户实体类
package com.liang.domain;

import java.io.Serializable;

/**
 * 账户实体类
 */
public class Account implements Serializable {

    private int id;
    private int uid;
    private Double money;

    public int getId() {
        return id;
    }

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

    public int getUid() {
        return uid;
    }

    public void setUid(int 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. 定义能够封装包含同时包含账户信息和用户信息的类。
package com.liang.domain;

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

/**
 * 用于存放账户以及账户持有者的信息
 */
public class AccountUser extends Account implements Serializable {

    private String username;
    private Date birthday;
    private String sex;
    private String address;

    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 super.toString() + " AccountUser{" +
                "username='" + username + '\'' +
                ", birthday=" + birthday +
                ", sex='" + sex + '\'' +
                ", address='" + address + '\'' +
                '}';
    }

}
  1. 定义持久层接口类以及查询方法
package com.liang.dao;

import com.liang.domain.Account;

import java.util.List;

/**
 * 账户的持久层接口
 */
public interface AccountDao {

    /**
     * 查询所有账户信息,同时包含其用户信息
     * @return
     */
    List<AccountUser> findAll();
}
  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.liang.dao.AccountDao">

    <!--查询所有账户信息,同时包含其用户信息-->
    <select id="findAll" resultType="com.liang.domain.AccountUser">
       select *from account,user where account.uid=user.id;
    </select>

</mapper>
  1. 创建测试类测试方法
  /**
     * 查询所有账户信息,同时包含其用户信息
     */
    @Test
    public void testFindAll()
    {
        List<AccountUser> accountUsers = accountDao.findAll();
        for (AccountUser accountUser:accountUsers)
        {
            System.out.println(accountUser);
        }
    }

**方式二:**通过面向对象的has a关系,使用resultMap,映射一对一查询结果。

  1. 编写账户实体类,在账户类加入一个用户类的对象来表示此账户属于哪个用户
    在这里插入图片描述
  2. 编写持久层接口方法
package com.liang.dao;

import com.liang.domain.Account;

import java.util.List;

/**
 * 账户的持久层接口
 */
public interface AccountDao {

    /**
     * 查询所有账户信息,同时包含其用户信息
     * @return
     */
    List<Account> findAll();
}
  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.liang.dao.AccountDao">

    <resultMap id="accountMap" type="com.liang.domain.Account">
        <id property="id" column="id"></id>
        <result column="uid" property="uid"></result>
        <result column="money" property="money"></result>
        <!--建立Account类中user属性对应的数据库表 -->
        <association property="user" column="user" javaType="com.liang.domain.User">
            <id property="id" column="id"></id>
            <result column="username" property="username"></result>
            <result column="sex" property="sex"></result>
            <result column="birthday" property="birthday"></result>
            <result column="address" property="address"></result>
        </association>
    </resultMap>
    <!--查询所有账户信息,同时包含其用户信息-->
    <select id="findAll" resultMap="accountMap">
       select *from account,user where account.uid=user.id;
    </select>

</mapper>
  • 主要标签、属性介绍
     association标签 : 一个复杂类型的关联,用于建立多(一)对一中对象属性的对应关系。
     javaType属性 : 一个 Java 类的完全限定名,或一个类型别名。
    
  • 编写测试方法
    /**
     * 查询所有账户信息,同时包含其用户信息
     */
    @Test
    public void testFindAll()
    {
        List<Account> accounts = accountDao.findAll();
        for (Account account:accounts)
        {
            System.out.println(account);
            System.out.println(account.getUser());
        }
    }

一对多查询

查询所有用户信息及用户关联的账户信息。
  • 编写用户实体类。
    上面分析过,用户和账户存在一对多的关系,则需要在用户(主表)实体类包含账户(从表)实体类的集合引用。
package com.liang.domain;

import java.util.Date;
import java.util.List;

public class User {

    private int id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;
    private List<Account> accountList;

    public List<Account> getAccountList() {
        return accountList;
    }

    public void setAccountList(List<Account> accountList) {
        this.accountList = accountList;
    }

    public int getId() {
        return id;
    }

    public void setId(int 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 + '\'' +
                '}';
    }
}
  • 编写持久层接口以及查询方法
   /**
     * 查询所有用户,同时获取每个用户下的所有账户信息
     * @return
     */
    List<User> findAllUserAndAccount();
  • 编写持久层映射文件
    在这里插入图片描述
  • 主要标签、属性介绍
     collection标签 : 一个复杂类型的集合,用于建立一对多中集合元素属性的对应关系。
     ofType属性 : 用于指定集合元素的数据类型。
    
  1. 编写测试方法
 /**
     * 查询所有用户,同时获取每个用户下的所有账户信息
     */
    @Test
    public void testFindAllUserAndAccount()
    {
        List<User> users = userDao.findAllUserAndAccount();
        for (User user:users)
        {
            System.out.println("--- --- --- --- --- ");
            System.out.println(user);
            System.out.println(user.getAccountList());
        }
    }

多对多查询

查询所用用户信息并且查询其角色信息(角色表在前面文章可查找)

1.编写角色类,和用户类

package com.liang.domain;

/**
 * 角色类
 */
public class Role {

    private int id;
    private String roleName;
    private String roleDesc;

    public int getId() {
        return id;
    }

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

    public String getRoleName() {
        return roleName;
    }

    public void setRoleName(String roleName) {
        this.roleName = roleName;
    }

    public String getRoleDesc() {
        return roleDesc;
    }

    public void setRoleDesc(String roleDesc) {
        this.roleDesc = roleDesc;
    }

    @Override
    public String toString() {
        return "Role{" +
                "id=" + id +
                ", roleName='" + roleName + '\'' +
                ", roleDesc='" + roleDesc + '\'' +
                '}';
    }
}
package com.liang.domain;

import java.util.Date;
import java.util.List;

/**
 * 用户类
 */
public class User {

    private int id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;

    private List<Role> roles;

    public List<Role> getRoles() {
        return roles;
    }

    public void setRoles(List<Role> roles) {
        this.roles = roles;
    }

    public int getId() {
        return id;
    }

    public void setId(int 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 + '\'' +
                '}';
    }
}
  1. 编写持久层接口方法
  /**
     * 查询所用用户信息并且查询其角色信息
     * @return
     */
    List<User> findAllUserAndRole();
  1. 编写持久层接口映射文件
    <resultMap id="userAndRoleMap" type="com.liang.domain.User">
        <id property="id" column="id"></id>
        <result column="username" property="username"></result>
        <result column="address" property="address"></result>
        <result column="sex" property="sex"></result>
        <result column="birthday" property="birthday"></result>
        <collection property="roles" ofType="com.liang.domain.Role">
            <id property="id" column="rid"></id>
            <result column="role_name" property="roleName"></result>
            <result column="role_Desc" property="roleDesc"></result>
        </collection>
    </resultMap>
    <select id="findAllUserAndRole" resultMap="userAndRoleMap">
            select user.*, role.id as rid, role.role_name,role.role_desc from user left join
            user_role on user.id = user_role.uid left join
            role on user_role.rid = role.id;
    </select>

4 编写测试方法

  /**
     * 查询所用用户信息并且查询其角色信息
     */
    @Test
    public void testFindAllUserAndAccount()
    {
        List<User> users = userDao.findAllUserAndRole();
        for (User user:users)
        {
            System.out.println("--- --- --- --- --- ");
            System.out.println(user);
            System.out.println(user.getRoles());
        }
    }
发布了71 篇原创文章 · 获赞 6 · 访问量 5389
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章