MyBatis之(五)Mybatis中的关联关系映射

五、MyBatis中的关联关系映射

5.1 什么是关联关系映射?

关联关系是面向对象分析、面向对象设计最重要的知识。合理的关联关系将大大简化持久层数据的访问。关联关系大致分为以下几类:

  • 一对一
  • 一对多
  • 多对一
  • 多对多

5.2 一对一关联关系映射

以qqUser表和baseInfo表为例,一个qq号对应一个用户信息表,这就是我们所说的一对一关联关系。

已知QQUser实体类中包含了这5个属性值和其映射的实体类对象:
MyBatis之(五)Mybatis中的关联关系映射

BaseInfo实体类中包含了这8个属性值:
MyBatis之(五)Mybatis中的关联关系映射

  • qquser映射到baseinfo
    association:表示关联关系,Property属性表示映射的实体类对象,column表示映射的实体类;
    id:表示关联外键,property表示实体类中的属性名,column表示表中的字段名;
    result:表示映射结果,property表示实体类中的属性名,column表示表中的字段名。

    <?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="cn.ebuy.dao.QQUserMapper">
        <resultMap id="qquserMap" type="cn.ebuy.pojo.QQUser">
            <result property="qqid" column="qqid"/>
            <result property="password" column="password"/>
            <result property="lastlogtime" column="lastlogtime"/>
            <result property="onlines" column="onlines"/>
            <result property="levels" column="levels"/>
            <!--配置关联映射-->
            <association property="baseInfo" column="cn.ebuy.pojo.BaseInfo">
                <id property="qqid" column="qqid"/>
                <result property="nickname" column="nickname"/>
                <result property="sex" column="sex"/>
                <result property="age" column="age"/>
                <result property="province" column="province"/>
                <result property="city" column="city"/>
                <result property="address" column="address"/>
                <result property="phone" column="phone"/>
            </association>
        </resultMap>
        <!--查询所有qquser信息:qquser映射到baseinfo-->
        <select id="selectAll" resultMap="qquserMap">
            select * from QQUSER a,baseinfo b where a.qqid=b.qqid
        </select>
    </mapper>
    
    /**
     * QQUser映射接口(相当于原来的DAO接口)
     */
    public interface QQUserMapper{
        /**
         * 查询所有qquser信息
         * @return
         */
        List<QQUser> selectAll();
    }
    
    
    //测试类
    /**
     * 查找所有qquser信息
     */
    @Test
    public void selectAll(){
        List<QQUser> list;
        SqlSession sqlSession = MyBatisUtil.createSqlSession();
        QQUserMapper qqUserMapper = sqlSession.getMapper(QQUserMapper.class);
        list = qqUserMapper.selectAll();
        for (QQUser qqUser:list){
            System.out.println(qqUser);
        }
        MyBatisUtil.closeeSqlSession(sqlSession);
    }
    
  • baseinfo映射到qquser
    与qquser映射到baseinfo同理。

5.3 多对一关联关系映射(在多中定义一的对象)

以用户表和角色表为例,多个用户可以共同使用这一个角色,用户与角色之间是多对一关系。

已知SystemUser3实体类:

package cn.ebuy.pojo;
import java.io.Serializable;
/**
 * 用户实体
 */
public class SystemUser3 implements Serializable {
    /**
     * 用户ID
     */
    private String userinfouid;
    /**
     * 登录名
     */
    private String userinfologinid;
    /**
     * 姓名
     */
    private String userinfoname;
    /**
     * 密码
     */
    private String userinfopassword;
    /**
     * 性别
     */
    private String userinfo_sex;
    /**
     * 电子邮箱
     */
    private String userinfo_email;
    /**
     * 手机
     */
    private String userinfo_mobile;
    /**
     * 用户状态(1 正常 2 锁定 3注销)
     */
    private int userinfo_status;
    /**
     * 角色实体类
     */
    SystemRole systemRole;
    public SystemUser3() {
    }
    public String getUserinfouid() {
        return userinfouid;
    }
    public void setUserinfouid(String userinfouid) {
        this.userinfouid = userinfouid;
    }
    public String getUserinfologinid() {
        return userinfologinid;
    }
    public void setUserinfologinid(String userinfologinid) {
        this.userinfologinid = userinfologinid;
    }
    public String getUserinfoname() {
        return userinfoname;
    }
    public void setUserinfoname(String userinfoname) {
        this.userinfoname = userinfoname;
    }
    public String getUserinfopassword() {
        return userinfopassword;
    }
    public void setUserinfopassword(String userinfopassword) {
        this.userinfopassword = userinfopassword;
    }
    public String getUserinfo_sex() {
        return userinfo_sex;
    }
    public void setUserinfo_sex(String userinfo_sex) {
        this.userinfo_sex = userinfo_sex;
    }
    public String getUserinfo_email() {
        return userinfo_email;
    }
    public void setUserinfo_email(String userinfo_email) {
        this.userinfo_email = userinfo_email;
    }
    public String getUserinfo_mobile() {
        return userinfo_mobile;
    }
    public void setUserinfo_mobile(String userinfo_mobile) {
        this.userinfo_mobile = userinfo_mobile;
    }
    public int getUserinfo_status() {
        return userinfo_status;
    }
    public void setUserinfo_status(int userinfo_status) {
        this.userinfo_status = userinfo_status;
    }
    public SystemRole getSystemRole() {
        return systemRole;
    }
    public void setSystemRole(SystemRole systemRole) {
        this.systemRole = systemRole;
    }
}

角色SystemRole实体类:
MyBatis之(五)Mybatis中的关联关系映射

用户到角色的映射(多对一):
关联关系association中的id是在“多”的一方定义“一”的外键:
MyBatis之(五)Mybatis中的关联关系映射

<?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="cn.ebuy.dao.SystemUserMapper">
	<resultMap id="userMap3" type="cn.ebuy.pojo.SystemUser3">
        <result property="userinfouid" column="userinfo_uid"/>
        <result property="userinfologinid" column="userinfo_loginid"/>
        <result property="userinfoname" column="userinfo_name"/>
        <result property="userinfopassword" column="userinfo_password"/>
        <result property="userinfo_sex" column="userinfo_sex"/>
        <result property="userinfo_email" column="userinfo_email"/>
        <result property="userinfo_mobile" column="userinfo_mobile"/>
        <result property="userinfo_status" column="userinfo_status"/>

        <!--关联映射 用户到角色的映射 多对一-->
        <association property="systemRole" javaType="cn.ebuy.pojo.SystemRole2">
            <id property="role_id" column="userinfo_role"/>
            <result property="role_name" column="role_name"/>
            <result property="role_code" column="role_code"/>
            <result property="role_description" column="role_description"/>
        </association>
    </resultMap>
    <!--关联映射 用户到角色的映射-->
    <select id="selectAllByAssociation" resultMap="userMap3">
         select * from system_userinfo a,system_role b where a.userinfo_role=b.role_id
    </select>
</mapper>
/**
 * 关联映射 用户到角色的映射
 * @return
 */
List<SystemUser3> selectAllByAssociation();


//测试类
/**
 * 测试关联映射 用户映射到角色
 */
@Test
public void selectAllByAssociation(){
    List<SystemUser3> list;
    SqlSession sqlSession = MyBatisUtil.createSqlSession();
    SystemUserMapper systemUserMapper = sqlSession.getMapper(SystemUserMapper.class);
    list = systemUserMapper.selectAllByAssociation();
    for (SystemUser3 systemUser3:list){
        System.out.println(systemUser3);
    }
    MyBatisUtil.closeeSqlSession(sqlSession);
}

5.4 一对多关联关系映射(在一种定义多的对象集合)

还以角色类和用户类为例,一个角色可以对应多个用户,此时角色与用户的关系为一对多关系。

已知SystemUser3实体类:

package cn.ebuy.pojo;
import java.io.Serializable;
/**
 * 用户实体
 */
public class SystemUser3 implements Serializable {
    /**
     * 用户ID
     */
    private String userinfouid;
    /**
     * 登录名
     */
    private String userinfologinid;
    /**
     * 姓名
     */
    private String userinfoname;
    /**
     * 密码
     */
    private String userinfopassword;
    /**
     * 性别
     */
    private String userinfo_sex;
    /**
     * 电子邮箱
     */
    private String userinfo_email;
    /**
     * 手机
     */
    private String userinfo_mobile;
    /**
     * 用户状态(1 正常 2 锁定 3注销)
     */
    private int userinfo_status;
    public SystemUser3() {
    }
    public String getUserinfouid() {
        return userinfouid;
    }
    public void setUserinfouid(String userinfouid) {
        this.userinfouid = userinfouid;
    }
    public String getUserinfologinid() {
        return userinfologinid;
    }
    public void setUserinfologinid(String userinfologinid) {
        this.userinfologinid = userinfologinid;
    }
    public String getUserinfoname() {
        return userinfoname;
    }
    public void setUserinfoname(String userinfoname) {
        this.userinfoname = userinfoname;
    }
    public String getUserinfopassword() {
        return userinfopassword;
    }
    public void setUserinfopassword(String userinfopassword) {
        this.userinfopassword = userinfopassword;
    }
    public String getUserinfo_sex() {
        return userinfo_sex;
    }
    public void setUserinfo_sex(String userinfo_sex) {
        this.userinfo_sex = userinfo_sex;
    }
    public String getUserinfo_email() {
        return userinfo_email;
    }
    public void setUserinfo_email(String userinfo_email) {
        this.userinfo_email = userinfo_email;
    }
    public String getUserinfo_mobile() {
        return userinfo_mobile;
    }
    public void setUserinfo_mobile(String userinfo_mobile) {
        this.userinfo_mobile = userinfo_mobile;
    }
    public int getUserinfo_status() {
        return userinfo_status;
    }
    public void setUserinfo_status(int userinfo_status) {
        this.userinfo_status = userinfo_status;
    }
    public SystemRole getSystemRole() {
        return systemRole;
    }
    public void setSystemRole(SystemRole systemRole) {
        this.systemRole = systemRole;
    }
}

角色SystemRole实体类:
MyBatis之(五)Mybatis中的关联关系映射

角色到用户的映射(一对多):
一对多的映射要在“一”中定义“多”的对象集合:collection
collection:表示映射集合,property表示外键集合对象名,ofType表示外键对象的实体类;
result表示映射结果,property表示实体类中的属性名,column表示表中的字段名。

<?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="cn.ebuy.dao.SystemRoleMapper">
	<!--角色和表的映射-->
    <resultMap id="roleMap" type="cn.ebuy.pojo.SystemRole2">
        <result property="roleid" column="role_id"/>
        <result property="rolename" column="role_name"/>
        <result property="rolecode" column="role_code"/>
        <result property="roledescription" column="role_description"/>

        <!--配置关联关系 角色映射到用户 一对多  1-->
        <!--注意:此时的多关系应该为collection集合-->
        <collection property="listUser" ofType="cn.ebuy.pojo.SystemUser">
            <result property="userinfo_uid" column="userinfo_uid"/>
            <result property="userinfo_loginid" column="userinfo_loginid"/>
            <result property="userinfo_name" column="userinfo_name"/>
            <result property="userinfo_password" column="userinfo_password"/>
            <result property="userinfo_sex" column="userinfo_sex"/>
            <result property="userinfo_email" column="userinfo_email"/>
            <result property="userinfo_mobile" column="userinfo_mobile"/>
            <result property="userinfo_status" column="userinfo_status"/>
        </collection>
    </resultMap>
    <resultMap id="roleMap2" type="cn.ebuy.pojo.SystemRole2">
        <result property="roleid" column="role_id"/>
        <result property="rolename" column="role_name"/>
        <result property="rolecode" column="role_code"/>
        <result property="roledescription" column="role_description"/>
        <!--配置关联关系 角色映射到用户 一对多  2-->
        <!--注意:此时的多关系应该为collection集合-->
        <!--可以通过添加多个映射,然后在集合里再次映射来提高代码的复用率-->
        <collection property="listUser" ofType="cn.ebuy.pojo.SystemUser" resultMap="userMap"/>
    </resultMap>
    <resultMap id="userMap" type="cn.ebuy.pojo.SystemUser">
        <result property="userinfo_uid" column="userinfo_uid"/>
        <result property="userinfo_loginid" column="userinfo_loginid"/>
        <result property="userinfo_name" column="userinfo_name"/>
        <result property="userinfo_password" column="userinfo_password"/>
        <result property="userinfo_sex" column="userinfo_sex"/>
        <result property="userinfo_email" column="userinfo_email"/>
        <result property="userinfo_mobile" column="userinfo_mobile"/>
        <result property="userinfo_status" column="userinfo_status"/>
    </resultMap>
    <!--关联映射 角色到用户的映射 一对多-->
    <select id="selectAllByAssociation" resultMap="roleMap">
         select * from system_userinfo a,system_role b where a.userinfo_role=b.role_id
    </select>
</mapper>
/**
 * 角色到用户的映射 一对多
 * @return
 */
List<SystemRole2> selectAllByAssociation();


//测试类
/**
 * 关联映射 角色到用户的映射 一对多
 */
@Test
public void selectAllByAssociation(){
    List<SystemRole2> list;
    SqlSession sqlSession = MyBatisUtil.createSqlSession();
    SystemRoleMapper systemRoleMapper = sqlSession.getMapper(SystemRoleMapper.class);
    list = systemRoleMapper.selectAllByAssociation();
    for (SystemRole2 systemRole2:list){
        System.out.println(systemRole2);
    }
    MyBatisUtil.closeeSqlSession(sqlSession);
}

小贴士:
当映射实体类的属性名宇宙无敌多时,我们不需要每次使用时都将其映射一遍再关联,这时我们只要将映射对象的实体类作为一个结果映射,在collection集合中再次映射即可。
MyBatis之(五)Mybatis中的关联关系映射

上一篇:Spring Boot整合Spring cache缓存


下一篇:调用三方webservice