1. 前言
不知道大家在平时有没有手写sql的习惯,当还没有开源mybatis-plus时,手写sql那是非常的常见,但是在维护一个老项目的时候,竟然勾起了我的一丝回忆。涉及到一个需求,我要追溯到它sql语句上,发现了一个很有趣的东西,竟然还有人记得用它,虽然符合的应用场景很少,但是能把它派上场,属实是有点惊艳到我了。
如上运用场景是根据一个type字段来区别,0是启用,1是禁止,启用可以查到对于的权限属性,1是没有权限属性也查询不到,于是这位同事就巧妙地用到了它。
所以,今天我就给大家讲讲它discriminator,估计很多小伙伴未曾见过或者基本很少人用过吧,是不是,大家说,知道这个是干嘛用的嘛。
2. 环境说明
本地的开发环境:
- 开发工具:IDEA 2021.3
- JDK版本: JDK 1.8
- Spring Boot版本:2.3.1 RELEASE
- Maven版本:3.8.2
3. discriminator
3.1 简介
discriminator,中文翻译过来就是鉴别器的意思。至于它是干啥用的,顾名思义,在mybatis中可以使用discriminator来判断某列的值,然后根据某列的值改变封装结构。你就可以理解成在中的Java 语言中的 switch 语句,这样大家可明白了吧。有时候,一个数据库查询可能会返回多个不同的结果集,它就派上用场了。
3.2 结构使用
一个鉴别器的定义需要指定 column 和 javaType 属性。例如:
<resultMap type="com.example.demo.entity.UserEntity" id="getUserForSex"><discriminator javaType="java.lang.String" column="sex"><case value="男" resultType="com.example.demo.vo.user.boy"/><case value="女" resultType="com.example.demo.vo.user.girl"/></discriminator>
</resultMap>
3.3 属性介绍
- column:设置要进行鉴别比较值的列名。
- javaType:指定列的类型,保证使用相同的Java类型来比较值。
其中discriminator标签可以有1个或多个case标签,case标签包含以下3个属性:
- value:该值为discriminator标签column属性用来匹配的值。
- resultMap:当column的值和value的值匹配时,可以配置使用resultMap指定的映射,resultMap优先级高于resultType。
- resultType:当column的值和value的值匹配时,用于配置使用resultType指定的映射。
更多详细可自行查阅官方文档:mybatis – MyBatis 3 | XML 映射器
4. 代码测试
接下来,我带着大家来实践一波,学习任何东西不光是理论,更注重实践,这样才能提高对该知识点的认知与理解。
4.1 定义查询方法
顾,我先在UserMapper.xml中定义一个查询方法。根据用户id查询信息。
<select id="getUserByIdFor" resultMap="getUserForSex">select * from user where id= #{id}
</select>
然后我再通过user表中的sex作为鉴别比较值,其sex共分男女两个值,所以接下来我们在写case的时候其实就只有两种情况。
4.2 定义resultMap
<!--根据sex返回指定结构体-->
<resultMap type="com.example.demo.entity.UserEntity" id="getUserForSex"><discriminator javaType="java.lang.String" column="sex"><case value="男" resultType="com.example.demo.vo.user.boy"/><case value="女" resultType="com.example.demo.vo.user.girl"/></discriminator>
</resultMap>
如上我是直接定义了两个pojo结构体,分别为boy与girl
4.3 定义pojo
boy.java
@Data
public class boy {private String sex;private String address;
}
girl.java
@Data
public class girl {private String sex;private String age;
}
大家可以看出,boy与girl的构造一字段之差,没错,我就是要让大家直观感受discriminator到底做了一件什么事。很明确啊,如果查询到的数据中sex=男,那就返回体为boy,反之返回体为girl。
接下来我们来验证一下。
先写个Controller请求方法。
4.4 定义Controller
/*** 根据id查询区分性别返回不同结构体内容*/
@GetMapping("/get-user-for-id")
@ApiOperation(value = "根据id查询区分性别返回不同结构体内容", notes = "根据id查询区分性别返回不同结构体内容")
public List<UserEntity> getUserInfo(@RequestParam Integer id) {return userMapper.getUserByIdFor(id);
}
完事之后,我们直接重启项目,在swagger中进行接口测试。
我们对于id分别传入一个sex=男和sex=女的数据试试。
大家请看,当传入id=1.
4.5 Swagger测试
正确返回的结构体就是girl。
我们再将id=3传入。
从截图返回内容可以看到,sex=男,毫无悬念返回的是boy结构体。
5. 热文推荐🔥
- 浅谈你对单例类中使用volatile关键字的理解
- Mysql分页 vs Oracle分页 对比分析
- Java 如何实现手动连接数据库(MySQL或Oracle)?
- Java 如何实现获取客户端公网IP地址?
- 为什么print和println输出java对象时会打印内存地址?
- 如何解决springboot拦截器@Autowried注入为空问题?
- MyBatis中的discriminator鉴别器如何使用?
- 如何快速手撕单例类?一文教会你
- 如何保证三个线程按顺序执行?不懂我教你
- 简谈你对synchronized关键字的使用
6. 最后🔥
🏆本文收录于《Java进阶实战》,需要的小伙伴可以进去瞅瞅。
本专栏致力打造最硬核Java进阶系列学习内容,🚀均为全网独家首发,打造精品专栏,专栏持续更新中…欢迎大家订阅持续学习。
我是bug菌,一名CSDN / 阿里云 / 华为云 / 51CTO 等社区博客专家,历届博客之星Top30,掘金年度人气作者Top40,51CTO年度博主Top12,掘金/InfoQ/51CTO等社区优质创作者,全网粉丝合计10w+,硬核微信公众号「猿圈奇妙屋」,欢迎你的加入!一起学习,一起变强。
关注公众号,获取最新BAT互联网公司面试题、4000G pdf电子书籍、简历模板等硬核资源