Mybatis Plus typeHandler 指定自定义类型处理器 List转varchar

1.需求

在实际需求中,经常会存在实体对象的标签信息,通常这些标签是固定的,我们在Java中用枚举来表示,针对枚举类型在数据库与Java之间的转换,Mybatis plus提供了@EnumValue注解。其实是针对该枚举类型生成了类型处理器。但如果标签允许多选,基础的无法满足,我们就需要自定义类型处理器了。

2. 实现

2.1 

 首先实现自定义类型处理器,只需要继承Mybatis提供的BaseTypeHandler 类,并实现其类型处理方法。

2.2

第二步是将实体类与类型转换器关联起来,Plus通过注解实现,有两步:

  1. 实体类上标记注解@TableName(autoResultMap=true) 开启自动填充ResultMap。

  1. 属性上通过@TableField(typeHandler = xxx.class)指定类型处理器。

3. 示例

 3.1 相关类

    

标签枚举

实体类(因为是多标签,这里用List封装枚举)

Service

Mapper

3.2 自定义类型处理器

  继承BaseTypeHandler类

 实现处理方法(可以根据需求定制转换规则,这里我直接用JSON处理了。)

3.3 在实体类种配置注解

3.4 演示

3.4.1. 保存实体类

调试运行,查看断点

可以看到处理器拦截到对象并转成了JSON

数据库中保存的为JSON字符串

3.4.2. 查询实体类

调试运行,查看断点,可以看到处理器拦截到了JSON字符串并转成了List集合

4. 注意事项
  1.    通过注解配置的方式,只对Plus提供的基础方法生效,也就是如果你在Mapper里写了个方法,并且自定义了SQL,是不会生效的。Plus根据扫描实体类注解生成了一个ResultMap并且其Service生成的基础方法都关联引用。这么一来Plus提供的基础方法,都会触发类型转换器。

可以看看原生mapper.xml里配置自定义类型转换器

以上方法只对查询生效

 保存时的配置方法

  1. 关于mybatis-plus.type-handlers-package 开启扫描包中的类型处理器,这里有个坑,mybatis是用java类型作为key保存typeHandler,如果定义了两个相同java类型但不同逻辑的处理器,它只会存一个。并且,它对所有包含该类型的实体类都会生效,除非你指定关联了其他类型处理器。也就是全局通用的。如果不想做全局通用,建议不要开启包扫描。特别是像List这种类型,其实我们更关注的是内部的对象,并且会有不同的处理逻辑。

例如:

可以看到List集合里对象并不相同,可能处理逻辑也不同。但只要你开启了包扫描,并包含List类型的处理器 它们的命中方式是这样的

如果我们是一套逻辑处理所有的List类型,那么自定义一个List类型处理器并开启包扫描即可,如果有不同的处理逻辑,则需要指定类型处理器,否则要么命中全局的,要么找不到处理器抛异常。

以上是笔者结合源码通过测试所得出的结论,如果有理解错误的地方,欢迎指出。

  • 9
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MyBatis中,你可以使用自定义类型处理器TypeHandler)来处理自定义的Map类型类型处理器用于在Java对象和数据库字段之间进行换。 以下是一种实现自定义类型处理器处理自定义的Map的示例: 1. 定义一个自定义的Map类型,例如`CustomMap`: ```java public class CustomMap extends HashMap<String, Object> { // 添加自定义的方法或属性 } ``` 2. 实现一个自定义类型处理器,继承自`org.apache.ibatis.type.BaseTypeHandler`类,并实现对应的方法。 ```java import org.apache.ibatis.type.BaseTypeHandler; import org.apache.ibatis.type.JdbcType; import java.sql.CallableStatement; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class CustomMapTypeHandler extends BaseTypeHandler<CustomMap> { @Override public void setNonNullParameter(PreparedStatement ps, int i, CustomMap parameter, JdbcType jdbcType) throws SQLException { // 将CustomMap换为需要的数据类型,并设置到PreparedStatement中 // ps.setXXX(i, convertedValue); } @Override public CustomMap getNullableResult(ResultSet rs, String columnName) throws SQLException { // 从ResultSet中获取指定列名的值,并将其换为CustomMap类型 // Object columnValue = rs.getXXX(columnName); // CustomMap map = convertToCustomMap(columnValue); // return map; return null; } @Override public CustomMap getNullableResult(ResultSet rs, int columnIndex) throws SQLException { // 与上面类似,只是根据列索引获取值 return null; } @Override public CustomMap getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { // 与上面类似,只是在CallableStatement中获取值 return null; } } ``` 在上述示例中,我们继承了`BaseTypeHandler`类,并重写了父类的方法,在这些方法中进行了自定义类型换逻辑。 3. 在MyBatis的配置文件中,注册自定义类型处理器。 ```xml <typeHandlers> <typeHandler handler="com.example.CustomMapTypeHandler"/> </typeHandlers> ``` 通过以上步骤,你就可以使用自定义的Map类型,并通过自定义类型处理器来处理该类型换逻辑。在数据库操作时,MyBatis会自动调用类型处理器来进行换。你可以根据实际需求,在类型处理器中编写相应的换逻辑,将自定义的Map类型与数据库字段进行换。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值