day03-Mybatis中一对一、一对多、多对多查询

一对一查询

一对一的表结构:

my_account表:

 my_user表:

 一对一是互相的,A可以找到B,B也可以找到A,方法是一样的,这里就只写一个方向的

通过my_count表找到my_user表的对应元素

实际意义:一个账户(银行卡)只能被一个用户拥有

方法一(最常用):在Account实体类包含一个User类型对象的引用

Account实体类:

package com.zyb.pojo;

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

public class Account implements Serializable {
    private Integer id;
    private Integer uid;
    private Double money;
    //包含另一个对象的引用
    private User user;

    public Account() {
    }
    
    @Override
    public String toString() {
        return "Account{" +
                "id=" + id +
                ", uid=" + uid +
                ", money=" + money +
                ", 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;
    }


}

User实体类:

package com.zyb.pojo;

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

public class User {

    private int uid;
    private String uname;
    private Date birthday;
    private String userSex;
    private String userAddress;

    public User() {
    }



    public User(int uid, String uname, Date birthday, String userSex, String userAddress) {
        this.uid = uid;
        this.uname = uname;
        this.birthday = birthday;
        this.userSex = userSex;
        this.userAddress = userAddress;
    }

    @Override
    public String toString() {
        return "User{" +
                "uid=" + uid +
                ", uname='" + uname + '\'' +
                ", birthday=" + birthday +
                ", userSex='" + userSex + '\'' +
                ", userAddress='" + userAddress + '\'' +
                '}';
    }

    public int getUid() {
        return uid;
    }

    public void setUid(int uid) {
        this.uid = uid;
    }

    public String getUname() {
        return uname;
    }

    public void setUname(String uname) {
        this.uname = uname;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public String getUserSex() {
        return userSex;
    }

    public void setUserSex(String userSex) {
        this.userSex = userSex;
    }

    public String getUserAddress() {
        return userAddress;
    }

    public void setUserAddress(String userAddress) {
        this.userAddress = userAddress;
    }
}

AccountMapper.xml

<?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.zyb.dao.AccountDao">
    <resultMap id="accountUserMap" type="com.zyb.pojo.Account">
        <!--这里写account_id是因为id重名在SQL语句中起的别名-->
        <id property="id" column="account_id"></id>
        <result property="uid" column="uid"></result>
        <result property="money" column="money"></result>
<!--        一对一关系映射配置user的-->
<!-- 下面property是user是因为在Account实体类User类型变量名是user
第二个javaType是user是因为我给User实体类在mybatis-config.xml起了别名
-->
        <association property="user" javaType="user">
        <!--主键字段对应-->
        <id property="uid" column="id"></id>
        <!--    非主键属性对应-->
        <result property="uname" column="username"></result>
        <result property="birthday" column="birthday"></result>
        <result property="userSex" column="sex"></result>
        <result property="userAddress" column="address"></result>
        </association>
    </resultMap>
    <select id="selAllAccount" resultType="com.zyb.pojo.Account">
        select * from my_account
    </select>
<!--    通过书写Account的子类完成一对多-->
<!--    <select id="selAllAccount2User" resultType="com.zyb.pojo.AccountUser" >-->
<!--        select a.*,u.username,u.address from my_account a,my_user u where a.uid=u.id;-->
<!--    </select>-->

        <select id="selAllAccount2User" resultType="com.zyb.pojo.Account" resultMap="accountUserMap" >
            select u.*,a.id as account_id,a.money,a.uid from my_user u,my_account a where a.UID=u.id
        </select>


</mapper>    

测试类:

package com.zyb.test;

import com.zyb.dao.AccountDao;
import com.zyb.pojo.Account;
import com.zyb.pojo.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.After;
import org.junit.Before;
import org.junit.Test;

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

public class AccountTst {


    InputStream in;
    SqlSession session;
    AccountDao accountDao;

    @Before
    public void init() throws IOException {
        //1.读取配置文件
        in = Resources.getResourceAsStream("mybatis-config.xml");
        //2.创建SqlSessionFactory工厂
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory factory = builder.build(in);
        //3.使用工厂生产SqlSession对象
        session = factory.openSession();
        //4.使用SqlSession创建Dao接口的代理对象
        accountDao = session.getMapper(AccountDao.class);
    }

    @After
    public void destory() throws IOException {
        //session.commit();
        //6.释放资源
        session.close();
        in.close();

    }

    @Test
    public  void testSelAllAccount(){
     List<Account> accounts = accountDao.selAllAccount();
     accounts.forEach(x-> System.out.println(x));
    }

    @Test
    public void testSelAllAccount2User(){
        List<Account> accountUsers=accountDao.selAllAccount2User();
        accountUsers.forEach(x-> System.out.println(x));
    }


}

方法二:建立一个中间类(属性包含需要查询User类的属性)继承Account之后,之后返回一个中间类型的列表就ok了

中间类:

package com.zyb.pojo;

public class AccountUser  extends Account{
    private String username;
    private String address;

    public AccountUser() {
    }

    @Override
    public String toString() {
        return super.toString()+"AccountUser{" +
                "username='" + username + '\'' +
                ", address='" + 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;
    }
}

AccountMapper.xml中的SQL语句以及配置就是上面注释的那个

测试文件将

换成

 不细说这个了,不常用。

一对多查询

需要用到的表:my_user、my_account

实际意义:一个用户可以有多个账户(银行卡)

思路:通过上面的一对一,这个思路应该就不是很难想,那就是用户(User)包含一个属于自己账户集合的引用

user实体类:

与上面比就多了一个

UserMapper.xml

<?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.zyb.dao.UserDao">
<!--    返回类型可以写成user是因为我在mybatis-config.xml已经声明了,否则得写全限定类名-->
<resultMap id="userMap" type="user">
<!--主键字段对应-->
    <id property="uid" column="id"></id>
<!--    非主键属性对应-->
    <result property="uname" column="username"></result>
    <result property="birthday" column="birthday"></result>
    <result property="userSex" column="sex"></result>
    <result property="userAddress" column="address"></result>
<!--    这里写accounts是因为在User中List<Account>的变量名为accounts-->
   <collection property="accounts" ofType="com.zyb.pojo.Account">
<!--       aid是列名重复SQl语句起别名的缘故-->
        <id property="id" column="aid"></id>
        <result property="uid" column="uid"></result>
        <result property="money" column="money"></result>
   </collection>
</resultMap>
    <sql id="defaultSql">
        select * from my_user
    </sql>
    <select id="selAll" resultType="User" resultMap="userMap">
    select u.*,a.id as aid,a.uid,a.money from my_user u left outer join my_account a on a.uid=u.id
    <!--根据id查询一个人-->
    </select>
    <select id="selOne" resultType="USER" resultMap="userMap" parameterType="int">
        <include refid="defaultSql"></include>
         where id=#{uid};
    </select>




</mapper>

测试类:

package com.zyb.test;


import com.zyb.dao.UserDao;
import com.zyb.pojo.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.After;
import org.junit.Before;
import org.junit.Test;

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

public class TestUnit {

    InputStream in;
    SqlSession session;
    UserDao userDao;

    @Before
    public void init() throws IOException {
        //1.读取配置文件
        in = Resources.getResourceAsStream("mybatis-config.xml");
        //2.创建SqlSessionFactory工厂
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory factory = builder.build(in);
        //3.使用工厂生产SqlSession对象
        session = factory.openSession();
        //4.使用SqlSession创建Dao接口的代理对象
        userDao = session.getMapper(UserDao.class);
    }

    @After
    public void destory() throws IOException {
        //session.commit();
        //6.释放资源
        session.close();
        in.close();

    }

    @Test
    public void testSelAll(){
    List<User>users= userDao.selAll();
        for(User user:users){
            System.out.println("----------------------------------------");
        System.out.println(user);
        System.out.println(user.getAccounts());
            System.out.println("************************************************");
        }

    }

    @Test
    public void testSelOne(){
        User user = userDao.selOne(52);

        System.out.println(user);


    }


}

测试结果:老王有两个账户,传智播客有一个,其它都是空

多对多查询

需要用到的表:my_user、my_role、role_user

思路:互相包含对方类型的的集合

实际意义:一个人扮演多个角色(儿子、父亲、学生),一个角色被多个人扮演

my_role:

 user_role(中间表):

 注意:这里的uid与my_user表的id相关联,rid与my_role的id相关联

Role实体类:

package com.zyb.pojo;

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

public class Role implements Serializable {
private Integer roleId;
private String roleName;
private String roleDesc;
private List<User> users;

    public Role() {
    }

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

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

    @Override
    public String toString() {
        return "Role{" +
                "roleId=" + roleId +
                ", roleName='" + roleName + '\'' +
                ", roleDesc='" + roleDesc + '\'' +
                '}';
    }

    public Integer getRoleId() {
        return roleId;
    }

    public void setRoleId(Integer roleId) {
        this.roleId = roleId;
    }

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

User实体类:

package com.zyb.pojo;

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

public class User {

    private int uid;
    private String uname;
    private Date birthday;
    private String userSex;
    private String userAddress;
    //一对多映射
    //主表应该包含从表对象集合的引用
    //之后collection的property属性填roles
    private List<Role> roles;

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

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

    public User() {
    }



    public User(int uid, String uname, Date birthday, String userSex, String userAddress) {
        this.uid = uid;
        this.uname = uname;
        this.birthday = birthday;
        this.userSex = userSex;
        this.userAddress = userAddress;
    }

    @Override
    public String toString() {
        return "User{" +
                "uid=" + uid +
                ", uname='" + uname + '\'' +
                ", birthday=" + birthday +
                ", userSex='" + userSex + '\'' +
                ", userAddress='" + userAddress + '\'' +
                '}';
    }

    public int getUid() {
        return uid;
    }

    public void setUid(int uid) {
        this.uid = uid;
    }

    public String getUname() {
        return uname;
    }

    public void setUname(String uname) {
        this.uname = uname;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public String getUserSex() {
        return userSex;
    }

    public void setUserSex(String userSex) {
        this.userSex = userSex;
    }

    public String getUserAddress() {
        return userAddress;
    }

    public void setUserAddress(String userAddress) {
        this.userAddress = userAddress;
    }
}

UserMapper.xml

<?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.zyb.dao.UserDao">
<!--    返回类型可以写成user是因为我在mybatis-config.xml已经声明了,否则得写全限定类名-->
<resultMap id="userMap" type="user">
<!--主键字段对应-->
    <id property="uid" column="id"></id>
<!--    非主键属性对应-->
    <result property="uname" column="username"></result>
    <result property="birthday" column="birthday"></result>
    <result property="userSex" column="sex"></result>
    <result property="userAddress" column="address"></result>
    <collection property="roles" ofType="com.zyb.pojo.Role">
        <id property="roleId" column="rid"></id>
        <result property="roleName" column="role_name"></result>
        <result property="roleDesc" column="role_desc"></result>
    </collection>

</resultMap>
    <sql id="defaultSql">
    select * from my_user
    </sql>
    <select id="selAll"  resultMap="userMap">
        select u.*,r.ROLE_NAME,r.ROLE_DESC,r.ID as rid  from my_user u
        left outer join user_role ur
        on u.id=ur.UID
        left outer join my_role r
        on r.ID=ur.RID
    <!--根据id查询一个人-->
    </select>
    <select id="selOne" resultType="USER" resultMap="userMap" parameterType="int">
        <include refid="defaultSql"></include>
         where id=#{uid};
    </select>




</mapper>

RoleMapper.xml

<?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.zyb.dao.RoleDao">

    <resultMap id="roleMap" type="com.zyb.pojo.Role">
<!--        因为有两个id所以在查询结果重命名了id-->
<!--        select u.*,r.ROLE_NAME,r.ROLE_DESC,r.ID as rid-->
        <id property="roleId" column="rid"></id>
        <result property="roleName" column="role_name"></result>
        <result property="roleDesc" column="role_desc"></result>
<!--        collection中的property是包含集合的名字-->
        <collection property="users" ofType="user">
            <!--主键字段对应-->
            <id property="uid" column="id"></id>
            <!--    非主键属性对应-->
            <result property="uname" column="username"></result>
            <result property="birthday" column="birthday"></result>
            <result property="userSex" column="sex"></result>
            <result property="userAddress" column="address"></result>
        </collection>
    </resultMap>
<select id="selAll" resultMap="roleMap">
    select u.*,r.ROLE_NAME,r.ROLE_DESC,r.ID as rid from
    my_role r left outer join user_role ur
    on  r.ID=ur.RID
    left outer join my_user u
    on ur.UID=u.id
</select>

</mapper>

测试类大同小异就不写了

运行结果:

}

猜你喜欢

转载自www.cnblogs.com/cstdio1/p/11914831.html