1、ResultMap的association与collection

association与collection功能类似,区别是一对一与一对多,这里以association为例。

首先说明一下需求:通过员工ID获取员工信息,同时获取员工的角色,涉及到了员工信息表、角色表、还有二者的关联表。最简单的做法是写一个SQL语句,语句里写了三个表,互相关联进行查询,但这种方式存在问题:1、SQL语句不易维护 2、复用性不强 3、我只想获取用户的信息,不用角色信息时,查询了多余的信息,徒增消耗。

解决办法:1、对每个实体都定义一个基础的ResultMap,根据需要继承基础ResultMap再添加自定义的属性 2、在ResultMap中使用association或者collection进行关联查询 3、使用y延迟加载,需要角色信息时再去查询。

实际操作过程:

新建实体类User和Role

package com.forest.owl.entity;

import java.util.Date;

public class Role {
    private Long id;

    private String roleName;

    private Integer enabled;

    private Long createBy;

    private Date createTime;

    private Long updateBy;

    private Date updateTime;

    public Long getId() {
        return id;
    }

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

    public String getRoleName() {
        return roleName;
    }

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

    public Integer getEnabled() {
        return enabled;
    }

    public void setEnabled(Integer enabled) {
        this.enabled = enabled;
    }

    public Long getCreateBy() {
        return createBy;
    }

    public void setCreateBy(Long createBy) {
        this.createBy = createBy;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public Long getUpdateBy() {
        return updateBy;
    }

    public void setUpdateBy(Long updateBy) {
        this.updateBy = updateBy;
    }

    public Date getUpdateTime() {
        return updateTime;
    }

    public void setUpdateTime(Date updateTime) {
        this.updateTime = updateTime;
    }
}
package com.forest.owl.entity;

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

public class User {
    private Long id;

    private String userName;

    private String userPassword;

    private String userPhone;

    private String userEmail;

    private Date createTime;

    private Date updateTime;

    private byte[] headImg;

    private Role role;

    public Long getId() {
        return id;
    }

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

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getUserPassword() {
        return userPassword;
    }

    public void setUserPassword(String userPassword) {
        this.userPassword = userPassword;
    }

    public String getUserPhone() {
        return userPhone;
    }

    public void setUserPhone(String userPhone) {
        this.userPhone = userPhone;
    }

    public String getUserEmail() {
        return userEmail;
    }

    public void setUserEmail(String userEmail) {
        this.userEmail = userEmail;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public Date getUpdateTime() {
        return updateTime;
    }

    public void setUpdateTime(Date updateTime) {
        this.updateTime = updateTime;
    }

    public byte[] getHeadImg() {
        return headImg;
    }

    public void setHeadImg(byte[] headImg) {
        this.headImg = headImg;
    }

    public Role getRole() { return role; }

    public void setRole(Role role) { this.role = role; }
}

然后编写Mapper.xml,首先先编写BaseResultMap

UserMapper.xml

  <resultMap id="BaseResultMap" type="com.forest.owl.entity.User">
    <id column="id" jdbcType="BIGINT" property="id" />
    <result column="user_name" jdbcType="VARCHAR" property="userName" />
    <result column="user_password" jdbcType="VARCHAR" property="userPassword" />
    <result column="user_phone" jdbcType="VARCHAR" property="userPhone" />
    <result column="user_email" jdbcType="VARCHAR" property="userEmail" />
    <result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
    <result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
    <result column="head_img" jdbcType="LONGVARBINARY" property="headImg" />
  </resultMap>

RoleMapper.xml

  <resultMap id="BaseResultMap" type="com.forest.owl.entity.Role">
    <id column="id" jdbcType="BIGINT" property="id" />
    <result column="role_name" jdbcType="VARCHAR" property="roleName" />
    <result column="enabled" jdbcType="INTEGER" property="enabled" />
    <result column="create_by" jdbcType="BIGINT" property="createBy" />
    <result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
    <result column="update_by" jdbcType="BIGINT" property="updateBy" />
    <result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
  </resultMap>

编写RoleMapper.xml获取Role的接口和XML

package com.forest.owl.mapper;

import com.forest.owl.entity.Role;

public interface RoleMapper {
    Role selectByPrimaryKey(Long id);
}

RoleMapper.xml

  <select id="selectByPrimaryKey" resultMap="BaseResultMap">
    select id, role_name, enabled, create_by, create_time, update_by, update_time
    from role
    where id = #{id,jdbcType=BIGINT}
  </select>

然后编写UserMapper.xml

  <resultMap id="UserAndRole" extends="BaseResultMap" type="com.forest.owl.entity.User">
    <association property="role" fetchType="lazy" column="{id=role_id}" select="com.forest.owl.mapper.RoleMapper.selectByPrimaryKey"/>
  </resultMap>

  <select id="selectUsersById" resultMap="UserAndRole">
    SELECT u.*, ur.role_id
    FROM user u
    INNER JOIN user_role ur on ur.user_id=u.id
    WHERE u.id=#{id}
  </select>

可以看到,UserMapper的SQL语句中少了role表,这样SQL语句就简洁多了。需要注意,association中的fetchType=“lazy”选项,当执行getRole()的时候,才回去查询角色信息加载到查询结果中。如果用户还是需要在触发某个方法时加载全部数据,则可以配置mybatis的配置选项lazyLoadTriggerMethods,按需加载。

对于3.4.1 及之前版本的mybatis用户,还需要配置mybatis-config.xml的一个选项:

<setting name="aggressiveLazyLoading" value="false"/>

测试:

    @Test
    public void UserMapperTest(){
        SqlSession sqlSession = getSqlSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        List<User> userList = userMapper.selectUsersById(();
        System.out.println(userList.size());
        System.out.println("--------getRole---------");
        System.).getRole());
    }

执行结果

collection的代码

User实体类

package com.forest.owl.entity;

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

public class User {
    private Long id;

    private String userName;

    private String userPassword;

    private String userPhone;

    private String userEmail;

    private Date createTime;

    private Date updateTime;

    private byte[] headImg;

    private List<Role> roleList;

    public Long getId() {
        return id;
    }

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

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getUserPassword() {
        return userPassword;
    }

    public void setUserPassword(String userPassword) {
        this.userPassword = userPassword;
    }

    public String getUserPhone() {
        return userPhone;
    }

    public void setUserPhone(String userPhone) {
        this.userPhone = userPhone;
    }

    public String getUserEmail() {
        return userEmail;
    }

    public void setUserEmail(String userEmail) {
        this.userEmail = userEmail;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

    public Date getUpdateTime() {
        return updateTime;
    }

    public void setUpdateTime(Date updateTime) {
        this.updateTime = updateTime;
    }

    public byte[] getHeadImg() {
        return headImg;
    }

    public void setHeadImg(byte[] headImg) {
        this.headImg = headImg;
    }

    public List<Role> getRoleList() { return roleList; }

    public void setRoleList(List<Role> roleList) { this.roleList = roleList; }
}

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.forest.owl.mapper.UserMapper">
  <resultMap id="BaseResultMap" type="com.forest.owl.entity.User">
    <id column="id" jdbcType="BIGINT" property="id" />
    <result column="user_name" jdbcType="VARCHAR" property="userName" />
    <result column="user_password" jdbcType="VARCHAR" property="userPassword" />
    <result column="user_phone" jdbcType="VARCHAR" property="userPhone" />
    <result column="user_email" jdbcType="VARCHAR" property="userEmail" />
    <result column="create_time" jdbcType="TIMESTAMP" property="createTime" />
    <result column="update_time" jdbcType="TIMESTAMP" property="updateTime" />
    <result column="head_img" jdbcType="LONGVARBINARY" property="headImg" />
  </resultMap>

  <resultMap id="UserAndRole" extends="BaseResultMap" type="com.forest.owl.entity.User">
    <collection property="roleList" columnPrefix="role_" fetchType="lazy"
                resultMap="com.forest.owl.mapper.RoleMapper.BaseResultMap">
      <id property="id" column="id"/>
      <result column="role_name" property="roleName" />
      <result column="enabled" property="enabled" />
      <result column="create_by" property="createBy" />
      <result column="create_time" property="createTime" />
      <result column="update_by" property="updateBy" />
      <result column="update_time" property="updateTime" />
    </collection>
  </resultMap>

  <select id="selectUsersById" resultMap="UserAndRole">
    SELECT u.*,
    r.id role_id,
    r.role_name role_role_name,
    r.enabled role_enabled,
    r.create_by role_create_by,
    r.create_time role_create_time,
    r.update_by role_update_by,
    r.update_time role_update_time
    FROM user u
    INNER JOIN user_role ur on ur.user_id=u.id
    INNER JOIN role r on r.id=ur.role_id
    WHERE u.id=#{id}
  </select>
</mapper>

UserMapper接口

package com.forest.owl.mapper;

import com.forest.owl.entity.User;

public interface UserMapper {
    User selectUsersById(Long id);
}

测试:

    @Test
    public void UserMapperTest(){
        SqlSession sqlSession = getSqlSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        User user = userMapper.selectUsersById(();
        System.).getRoleName());
        System.).getRoleName());
    }

mybatis入门篇:Mybatis高级查询的更多相关文章

  1. mybatis入门篇:通过SqlSession.selectList进行数据查询

    作为一个java菜鸟,早就从慕课网中学到一些基本的mybatis的用法,但是一直不成体系,懵懵懂懂,既然正式入了java这个坑,就打算好好学学,所以买了本<MyBatis从入门到精通>,在 ...

  2. Mybatis入门篇之结果映射,你射准了吗?

    目录 前言 什么是结果映射? 如何映射? 别名映射 驼峰映射 配置文件开启驼峰映射 配置类中开启驼峰映射 resultMap映射 总结 高级结果映射 关联(association) 例子 关联的嵌套 ...

  3. MyBatis入门篇

    一.什么是MyBatis MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改 ...

  4. mybatis入门基础(六)----高级映射(一对一,一对多,多对多)

    一:订单商品数据模型 1.数据库执行脚本 创建数据库表代码: CREATE TABLE items ( id INT NOT NULL AUTO_INCREMENT, itemsname ) NOT ...

  5. mybatis入门篇:代码生成器(MyBatis Generator)

    这篇文章只是按照自己的需要去配置代码生成器,未对所有配置进行讲解,需要了解具体详情的,请到官网查阅文档.传送门:http://www.mybatis.org/generator/ 1.首先引入相关的依 ...

  6. MyBatis(7)高级查询

    本次全部学习内容:MyBatisLearning 高级查询:   对于整体的工程是时候增加一点文件了: 具体用到那个类再去说明类的内容   一对一查询: 1.resultType进行实现: 执行的sq ...

  7. mybatis入门(三):mybatis的基础特性

    mybatis的知识点: 1.mybatis和hibernate本质区别和应用场景 hibernate:是一个标准的ORM框架(Ojbect relation mapper对象关系映射).入门门槛较高 ...

  8. Mybatis入门之MyBatis基础

    一.MyBatis概述 1.ORM模型简介 ORM:对象关系映射(Object Relation Mapping) 1)传统JDBC程序的设计缺陷(实际项目不使用) a.大量配置信息硬编码 b.大量的 ...

  9. mybatis入门--初识mybatis

    初识mybatis 今天,一起来说说mybits这个框架吧.这是一个持久层的框架.之前叫做ibatis.所以,在它的代码中出现ibatis这个词的时候,不要感到惊讶.不是写错了,它确实就是这个样子的. ...

  10. 《Java从入门到放弃》入门篇:hibernate查询——HQL

    不知不觉又到了hibernate的最后一篇了,只感觉时光飞逝~,岁月如梭~! 转眼之间,我们就···························,好吧,想装个X,结果装不下去了,还是直接开始吧· ...

随机推荐

  1. margin外边距属性

    外边距属性: 设置元素与元素之间的距离(外边距),4个方向(上右下左). margin:长度值|百分比|auto margin-top margin-right margin-bottom margi ...

  2. Java程序第二次作业

    1.编写“人”类及其测试类.1.1 “人”类: 类名:Person 属性:姓名.性别.年龄.身份证号码 方法:在控制台输出各个信息1.2 测试类 类名:TestPerson 方法:main ...

  3. java数据类型运算符类型转换

    Java基本数据类型 基本类型,或者叫做内置类型,是JAVA中不同于类的特殊类型.它们是我们编程中使用最频繁的类型,因此面试题中也总少不了它们的身影,在这篇文章中我们将从面试中常考的几个方面来回顾一下 ...

  4. 2018.5.11 B树总结

    小结 B树:二叉树,每个结点只存储一个关键字,等于则命中,小于走左结点,大于 走右结点: B-树:多路搜索树,每个结点存储M/2到M个关键字,非叶子结点存储指向关键 字范围的子结点: 所有关键字在整颗 ...

  5. UT源码 105032014098

    package exam1; import java.util.Scanner; public class test01 { static String nextDate(int year,int m ...

  6. 【学习】C++多态机制

    多态:静态(早绑定) 在编译阶段和链接就能确定功能调用的函数.     动态(晚绑定) 在程序运行时根据需要的功能确定调用的函数. 实现晚绑定就要定义虚函数,使用虚函数则会用到基类指针. 继承基类虚成 ...

  7. pip install torch on windows, and the 'from torch._C import * ImportError: DLL load failed:' solution

    通过pip安装PyTorch 0.4.0成功(cpu, not gpu; python3.5; pip): pip3 install http://download.pytorch.org/whl/c ...

  8. Windows环境下C++中关于文件结束符的问题

    参考资料:http://www.cnblogs.com/day-dayup/p/3572374.html 一.前言 在不同的OS环境下,程序中对应的文件结束符有所不一样,根据<C++ Prime ...

  9. robot framework类型强制转换

    在测试过程中需要比较两个数值是否存在一定的关系 1.若新增一个数据,删除一个数据,判断他是否新增成功或者删除成功,除了判断本身数据成功显示与不显示之外,可以通过总数间接去判断是否成功 A)新增删除前获 ...

  10. Vector Math for 3D Computer Graphics (Bradley Kjell 著)

    https://chortle.ccsu.edu/VectorLessons/index.html Chapter0 Points and Lines (已看) Chapter1 Vectors, P ...