MyBatis的discriminator 鉴别器使用(十一)上

简介: MyBatis的discriminator 鉴别器使用(十一)

一. MyBatis的鉴别器


在resultMap 里面,除了 allocation 一对一,collection 一对多之外,还有一个discriminator 鉴别器, 可以根据类中某个属性的值不同,去执行不同的resultMap 结果。 如,User 类中有一个sex 性别的属性, 需要体检,那么就会有一个男生的健康表,一个女生的健康表, 对应user 表中的外键。 在查询的时候,会根据sex中的性别不同,去不同的表中查询结果。 如果女生去了解男生的健康表,那会出问题的,当然,如果男生去了解女生的健康表,也是会出现问题的, 所以这个时候,就需要discriminator 鉴别器了。


数据库表信息:


User表:

20190711085608781.png

男生健康表 boy_healthy:


20190715182142556.png


女生健康表 girl_healthy:


20190715182155787.png


POJO 对象类:

User.java


package com.yjl.pojo;
/**
 @author:yuejl
 @date: 2019年6月15日 上午11:11:02
 @Description Mybatis 使用的基本类 User
*/
public class User {
  /**
   * @param id id编号,自增
   * @param name 姓名
   * @param age 年龄
   * @param sex 性别
   * @param description 描述
   */
  private Integer id;
  private String name;
  private Integer age;
  private String sex;
  private String description;
  public User(){
  }
  public Integer getId() {
    return id;
  }
  public void setId(Integer id) {
    this.id = id;
  }
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
  public Integer getAge() {
    return age;
  }
  public void setAge(Integer age) {
    this.age = age;
  }
  public String getSex() {
    return sex;
  }
  public void setSex(String sex) {
    this.sex = sex;
  }
  public String getDescription() {
    return description;
  }
  public void setDescription(String description) {
    this.description = description;
  }
  public String toString() {
    return "User [id=" + id + ", name=" + name + ", age=" + age + ", sex=" + sex + ", description=" + description
        + "]";
  }
}


男生健康 Boy_Healthy.java


package com.yjl.pojo;
/**
@atuhor:yuejl
@Description: 男性健康表
*/
public class BoyHealthy {
  /**
   * @param id 编号
   * @param height 高度
   * @param weight 体重
   * @param xin 心
   * @param gan 肝
   * @param qianleixian 前列腺
   * @param description 描述
   */
  private int id;
  private Double height;
  private Double weight;
  private String xin;
  private String gan;
  private String qianleixian;
  private String description;
  //对于员工的处理
  private User userId;
  public int getId() {
    return id;
  }
  public void setId(int id) {
    this.id = id;
  }
  public Double getHeight() {
    return height;
  }
  public void setHeight(Double height) {
    this.height = height;
  }
  public Double getWeight() {
    return weight;
  }
  public void setWeight(Double weight) {
    this.weight = weight;
  }
  public String getXin() {
    return xin;
  }
  public void setXin(String xin) {
    this.xin = xin;
  }
  public String getGan() {
    return gan;
  }
  public void setGan(String gan) {
    this.gan = gan;
  }
  public String getQianleixian() {
    return qianleixian;
  }
  public void setQianleixian(String qianleixian) {
    this.qianleixian = qianleixian;
  }
  public String getDescription() {
    return description;
  }
  public void setDescription(String description) {
    this.description = description;
  }
  public User getUserId() {
    return userId;
  }
  public void setUserId(User userId) {
    this.userId = userId;
  }
  @Override
  public String toString() {
    return "BoyHealthy [id=" + id +", height=" + height + ", weight=" + weight + ", xin="
        + xin + ", gan=" + gan + ", qianleixian=" + qianleixian + ", description=" + description + "]";
  }
}


女生健康表 Girl_Healthy.java


package com.yjl.pojo;
/**
@atuhor:yuejl
@Description: 女性健康表
*/
public class GirlHealthy {
  /**
   * @param id 编号
   * @param height 高度
   * @param weight 体重
   * @param xin 心
   * @param gan 肝
   * @param zigon 子宫
   * @param description 描述
   */
  private int id;
  private Double height;
  private Double weight;
  private String xin;
  private String gan;
  private String zigong;
  private String description;
  //引入员工的对象
  private User user;
  public int getId() {
    return id;
  }
  public void setId(int id) {
    this.id = id;
  }
  public Double getHeight() {
    return height;
  }
  public void setHeight(Double height) {
    this.height = height;
  }
  public Double getWeight() {
    return weight;
  }
  public void setWeight(Double weight) {
    this.weight = weight;
  }
  public String getXin() {
    return xin;
  }
  public void setXin(String xin) {
    this.xin = xin;
  }
  public String getGan() {
    return gan;
  }
  public void setGan(String gan) {
    this.gan = gan;
  }
  public String getZigong() {
    return zigong;
  }
  public void setZigong(String zigong) {
    this.zigong = zigong;
  }
  public String getDescription() {
    return description;
  }
  public void setDescription(String description) {
    this.description = description;
  }
  public User getUser() {
    return user;
  }
  public void setUser(User user) {
    this.user = user;
  }
  @Override
  public String toString() {
    return "GirlHealthy [id=" + id +", height=" + height + ", weight=" + weight + ", xin="
        + xin + ", gan=" + gan + ", zigong=" + zigong + ", description=" + description + "]";
  }
}


需要将员工与健康表进行关联, 一对多的形式,为了不改变实体对象的结构,故最好是创建一个Bean, 用来接收。 当然,也可以用一对多的形式,但是不建议那样写。


男生健康Bean. Boy_Bean.


package com.yjl.pojo;
import java.util.List;
/**
@atuhor:yuejl
@Description: 类描述
*/
public class BoyBean extends User{
  private List<BoyHealthy> healthyList;
  public List<BoyHealthy> getHealthyList() {
    return healthyList;
  }
  public void setHealthyList(List<BoyHealthy> healthyList) {
    this.healthyList = healthyList;
  }
}


女生健康Bean. Girl_Bean.


package com.yjl.pojo;
import java.util.List;
/**
@atuhor:yuejl
@Description: 类描述
*/
public class GirlBean extends User{
  /**
   * 一个员工,可能对应多个不同的体检表。 当然,也可以是单个的。 原理都一样。
   */
  private List<GirlHealthy> healthyList;
  public List<GirlHealthy> getHealthyList() {
    return healthyList;
  }
  public void setHealthyList(List<GirlHealthy> healthyList) {
    this.healthyList = healthyList;
  }
}


二. 根据员工编号 嵌套select 查询结果


UserMapper.java 接口:


public User getUserById(int id);


UserMapper.xml sql语句:


    <resultMap type="user" id="userResultMapWithDiscriminator">
    <!-- 员工的基本属性。 -->
    <id property="id" column="id"/>
    <result property="name" column="name"/>
    <result property="sex" column="sex"/>
    <result property="age" column="age"/>
    <result property="description" column="description"/>
    <!-- 鉴别器 ,写上类型-->
    <discriminator javaType="string" column="sex">
      <!--根据不同的值,执行不同的resultMap-->
      <case value="男" resultMap="boyHealthyMap"></case>
      <case value="女" resultMap="girlHealthyMap"></case>
    </discriminator>
  </resultMap>
  <select id="getUserById" parameterType="int" resultMap="userResultMapWithDiscriminator">
    select * from user where id=#{id}
  </select>
  <!-- 关于男性的鉴别器 -->
  <resultMap type="boyBean" id="boyHealthyMap" extends="userResultMapWithDiscriminator">
    <collection property="healthyList" ofType="boyHealthy" javaType="ArrayList"
    column="id" select="com.yjl.mapper.BoyHealthyMapper.findHealthyByUserId">
    </collection>
  </resultMap>
  <!-- 关于女性的鉴别器 -->
  <resultMap type="girlBean" id="girlHealthyMap" extends="userResultMapWithDiscriminator">
    <collection property="healthyList" ofType="girlHealthy" javaType="ArrayList"
    column="id" select="com.yjl.mapper.GirlHealthyMapper.findHealthyByUserId">
    </collection>
  </resultMap>


那么对应 就有一个

BoyHealthyMapper.java 提供了一个接口:


public List<BoyHealthy> findHealthyByUserId(@Param(value="userId") int userId);


BoyHealthyMapper.xml 的sql语句:


<?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.yjl.mapper.BoyHealthyMapper">
  <resultMap type="boyHealthy" id="boyHealthyMap">
    <id property="id" column="id"/>
    <result property="height" column="height"/>
    <result property="weight" column="weight"/>
    <result property="xin" column="xin"/>
    <result property="gan" column="gan"/>
    <result property="qianleixian" column="qianleixian"/>
    <result property="description" column="description"/>
  </resultMap>
  <select id="findHealthyByUserId" parameterType="int" resultMap="boyHealthyMap">
    select * from boy_healthy t where t.userId=#{userId}
  </select>
</mapper>


GirlHealthyMapper.java 也提供了一个接口:


public List<GirlHealthy> findHealthyByUserId(@Param(value="userId") int userId);


GirlHealthyMapper.xml 的sql语句:


<mapper namespace="com.yjl.mapper.GirlHealthyMapper">
  <resultMap type="girlHealthy" id="girlHealthyMap">
    <id property="id" column="id"/>
    <result property="height" column="height"/>
    <result property="weight" column="weight"/>
    <result property="xin" column="xin"/>
    <result property="gan" column="gan"/>
    <result property="zigong" column="zigong"/>
    <result property="description" column="description"/>
  </resultMap>
  <select id="findHealthyByUserId" parameterType="int" resultMap="girlHealthyMap">
    select * from girl_healthy t where t.userId=#{userId}
  </select>
</mapper>


测试方法:


  @Test
  public void getByIdTest(){
    SqlSession sqlSession=SqlSessionFactoryUtils.getSession();
    UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
    User user=userMapper.getUserById(1);
    System.out.println("员工信息:"+user);
    if("男".equals(user.getSex())){
      //需要进行向下转化。
      BoyBean boyBean=(BoyBean)user;
      List<BoyHealthy> boyHList=boyBean.getHealthyList();
      boyHList.forEach(n ->System.out.println(n));
    }else{
      GirlBean girlBean=(GirlBean)user;
      List<GirlHealthy> girlHList=girlBean.getHealthyList();
      girlHList.forEach(n ->System.out.println(n));
    }
  }


运行结果如下:


20190715182224660.png


如果传入的是女性的id, 如2

User user=userMapper.getUserById(2);


20190715182243401.png


当然,也有对应的嵌套result 的形式。

相关文章
|
SQL Java 数据库连接
Mybatis之discriminator(鉴别器)详解
前言 最近干了一个工作是使用discriminator去写一个新的API,那么写这个新的API原因是什么呢?原因是这样的:我们的项目使用Mybatis,我们项目中有一个实体类叫做User,在User中还含有很多别的实体类,例如Role,Permission,Address等(有经验的肯定知道这种嵌套实体类的情况,使用和)。
3976 0
|
SQL Java 数据库连接
MyBatis的discriminator 鉴别器使用(十一)下
MyBatis的discriminator 鉴别器使用(十一)
318 0
MyBatis的discriminator 鉴别器使用(十一)下
|
Java 数据库连接 mybatis
MyBatis从入门到精通(十三):使用discriminator鉴别器映射
MyBatis从入门到精通(十三):使用discriminator鉴别器映射最近在读刘增辉老师所著的《MyBatis从入门到精通》一书,很有收获,于是将自己学习的过程以博客形式输出,如有错误,欢迎指正,如帮助到你,不胜荣幸! 本篇博客主要讲解鉴别器映射discriminator标签的简单用法。
866 0
|
1月前
|
SQL Java 数据库连接
挺详细的spring+springmvc+mybatis配置整合|含源代码
挺详细的spring+springmvc+mybatis配置整合|含源代码
|
1月前
|
算法 Java 数据库连接
Spring+MySQL+数据结构+集合,Alibaba珍藏版mybatis手写文档
Spring+MySQL+数据结构+集合,Alibaba珍藏版mybatis手写文档
|
1月前
|
Java 数据库连接 Spring
Spring 整合mybatis
Spring 整合mybatis
28 2
|
6天前
|
Java 数据库连接 mybatis
在Spring Boot应用中集成MyBatis与MyBatis-Plus
在Spring Boot应用中集成MyBatis与MyBatis-Plus
38 5
|
6天前
|
Java 数据库连接 数据库
实现Spring Boot与MyBatis结合进行数据库历史数据的定时迁移
实现Spring Boot与MyBatis结合进行数据库历史数据的定时迁移
21 2
|
8天前
|
缓存 NoSQL Java
在 SSM 架构(Spring + SpringMVC + MyBatis)中,可以通过 Spring 的注解式缓存来实现 Redis 缓存功能
【6月更文挑战第18天】在SSM(Spring+SpringMVC+MyBatis)中集成Redis缓存,涉及以下步骤:添加Spring Boot的`spring-boot-starter-data-redis`依赖;配置Redis连接池(如JedisPoolConfig)和连接工厂;在Service层使用`@Cacheable`注解标记缓存方法,指定缓存名和键生成策略;最后,在主配置类启用缓存注解。通过这些步骤,可以利用Spring的注解实现Redis缓存。
26 2
|
1月前
|
Java 关系型数据库 数据库连接
MyBatis-Plus介绍及Spring Boot 3集成指南
MyBatis-Plus是一个MyBatis扩展工具,旨在简化Java开发中的CRUD操作。它具有无侵入性、低损耗、强大的CRUD功能、Lambda表达式支持、主键自动生成、ActiveRecord模式、全局操作和内置代码生成器等特点。在Spring Boot 3中集成MyBatis-Plus,需在pom.xml添加依赖,排除特定版本的mybatis-spring,并用@MapperScan注解指定Mapper接口路径。此外,还介绍了如何使用MyBatis-Plus代码生成器自动生成Mapper、Model、Service和Controller层代码,以加速开发。
77 2
MyBatis-Plus介绍及Spring Boot 3集成指南