一. MyBatis的鉴别器
在resultMap 里面,除了 allocation 一对一,collection 一对多之外,还有一个discriminator 鉴别器, 可以根据类中某个属性的值不同,去执行不同的resultMap 结果。 如,User 类中有一个sex 性别的属性, 需要体检,那么就会有一个男生的健康表,一个女生的健康表, 对应user 表中的外键。 在查询的时候,会根据sex中的性别不同,去不同的表中查询结果。 如果女生去了解男生的健康表,那会出问题的,当然,如果男生去了解女生的健康表,也是会出现问题的, 所以这个时候,就需要discriminator 鉴别器了。
数据库表信息:
User表:
男生健康表 boy_healthy:
女生健康表 girl_healthy:
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)); } }
运行结果如下:
如果传入的是女性的id, 如2
User user=userMapper.getUserById(2);
当然,也有对应的嵌套result 的形式。