赞
踩
写在前面:各位看到此博客的小伙伴,如有不对的地方请及时通过私信我或者评论此博客的方式指出,以免误人子弟。多谢!
上篇springboot+mybatis中对枚举类型参数的处理EnumOrdinalTypeHandler与EnumTypeHandler区别我们测试了下EnumTypeHandler和EnumOrdinalTypeHandler的使用,假如有一个枚举类STUDENT("a","学生"),TEACHER("b","教师"); 我们存的是实例名STUDENT/TEACHER,或者ordinal值0/1,但是我们希望数据库中存储code值,也就是a或者b,那就需要通过自定义类型处理器来实现。
自定义处理器的写法可以参考EnumOrdinalTypeHandler或者EnumTypeHandler的源码。
看一下EnumOrdinalTypeHandler的源码:
贴一下自定义的一个处理器:
- package com.example.springbootmybatis.config;
-
-
- import com.example.springbootmybatis.enums.PersonType;
-
- import java.sql.CallableStatement;
- import java.sql.PreparedStatement;
- import java.sql.ResultSet;
- import java.sql.SQLException;
-
- import org.apache.ibatis.type.BaseTypeHandler;
- import org.apache.ibatis.type.JdbcType;
-
- public class PersonTypeHandler extends BaseTypeHandler<PersonType> {
-
- private Class<PersonType> type;
-
- private PersonType[] enums;
-
- public PersonTypeHandler(Class<PersonType> type) {
- if (type == null)
- throw new IllegalArgumentException("Type argument cannot be null");
- this.type = type;
- this.enums = type.getEnumConstants();
- if (this.enums == null)
- throw new IllegalArgumentException(type.getSimpleName()
- + " does not represent an enum type.");
- }
-
-
- /**
- * 定义设置参数时,该如何把Java类型的参数转换为对应的数据库类型
- */
- @Override
- public void setNonNullParameter(PreparedStatement ps, int i, PersonType parameter,
- JdbcType jdbcType) throws SQLException {
- ps.setString(i, parameter.getCode());
- }
-
- /**
- * 定义通过字段名称获取字段数据时,如何把数据库类型转换为对应的Java类型
- */
- @Override
- public PersonType getNullableResult(ResultSet rs, String columnName) throws SQLException {
- // 根据数据库存储类型决定获取类型,本例子中数据库中存放String类型
- String i = rs.getString(columnName);
- if (rs.wasNull()) {
- return null;
- } else {
- // 根据数据库中的value值,定位PersonType子类
- return PersonType.getEnum(i);
- }
-
- }
-
- /**
- * 定义通过字段索引获取字段数据时,如何把数据库类型转换为对应的Java类型
- */
- @Override
- public PersonType getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
- return null;
- }
-
- /**
- * 定义调用存储过程后,如何把数据库类型转换为对应的Java类型
- */
- @Override
- public PersonType getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
- return null;
- }
- }
如上:通过我们对源码的分析,没办法直接根据列值(a/b)从enums[]中直接获取我们想要枚举,可以考虑将枚举转为map,map的key为数据库保存的值(a/b),map的value为枚举值,所以在取值的时候直接通过key取值就可以,return PersonType.getEnum(i);
贴一下转map的代码,直接写到Person类中了,当然你也可以单独写一个工具类,
- package com.example.springbootmybatis.enums;
-
- import java.util.HashMap;
- import java.util.Map;
-
- public enum PersonType {
- STUDENT("a","学生"),
- TEACHER("b","教师");
-
- private String code;
- private String text;
-
- PersonType(String code,String text) {
- this.code=code;
- this.text=text;
- }
-
- public String getCode() {
- return code;
- }
-
- public void setCode(String code) {
- this.code = code;
- }
-
- public String getText() {
- return text;
- }
-
- public void setText(String text) {
- this.text = text;
- }
-
- static Map<String, PersonType> enumMap = new HashMap<String, PersonType>();
-
- static {
- for (PersonType type : PersonType.values()) {
- enumMap.put(type.getCode(), type);
- }
- System.out.println(enumMap);
- }
-
- public static PersonType getEnum(String code) {
- return enumMap.get(code);
- }
-
-
- }
最后别忘了在配置文件中配置一下自定义的处理器:
- <typeHandlers>
- <!--<typeHandler handler="org.apache.ibatis.type.EnumOrdinalTypeHandler"
- javaType="com.example.springbootmybatis.enums.PersonType" />-->
-
- <typeHandler handler="com.example.springbootmybatis.config.PersonTypeHandler"
- javaType="com.example.springbootmybatis.enums.PersonType" />
- </typeHandlers>
测试下,插入四条数据:
看下数据库中:
测试下查询:
一切正常,但是考虑一下如果我们有很多枚举,这样转换的话,那我们需要为每一个枚举定义一个Handler,然后在mybatis配置文件中添加多个typeHandler。其实不必这样,我们可以参考EnumOrdinalTypeHandler源码的写法使用泛型定义成一个通用的枚举转换处理器,有时间再补充。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。