解决Mybatis-plus自定义TypeHandler查询映射结果一直为null问题
作者:霁月清风与谁同
这篇文章主要介绍了解决Mybatis-plus自定义TypeHandler查询映射结果一直为null问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
踩坑背景
需求
将实体类中的JSONObject对象与MySQL数据库中VARCHAR类型进行映射
//实体类 @TableName(autoResultMap = true) @Data public class ImportItem implements Serializable { ... @ExcelIgnore @TableField(typeHandler = Fastjson2TypeHandler.class , value = "dynamic_information") private JSONObject dynamicInformation; ... }
//自定义类Fastjson2TypeHandler @MappedTypes({JSONObject.class}) @MappedJdbcTypes({JdbcType.VARCHAR}) public class Fastjson2TypeHandler extends AbstractJsonTypeHandler<JSONObject> { private static final Logger log = LoggerFactory.getLogger(Fastjson2TypeHandler.class); private final Class<JSONObject> type = JSONObject.class; public Fastjson2TypeHandler() { log.trace("Fastjson2TypeHandler({})", type); } @Override protected JSONObject parse(String json) { return JSON.parseObject(json, this.type); } @Override protected String toJson(JSONObject obj) { return obj != null ? obj.toJSONString() : null; } }
//自定义查询语句 public interface ImportItemMapper extends MyMapper<ImportItem> { @Select("<script>" + "SELECT * from import_item \n" + "WHERE company_id=#{companyId} \n" + "<if test='batchNumber!= null and batchNumber!=\"\" '>AND batch_number=#{batchNumber}</if> \n" + "<if test='mark!= null'>AND mark=#{mark}</if> \n" + "${params.dataScope}" + "</script>") List<ImportItem> getByBatchNumber(ItemQuery itemQuery); }
此时在操作的时候增删改都没为问题,但是调用自定义的查询接口的时候dynamicInformation始终查询结果为空,通过开启Mybatis-plus日志打印发现sql查询结果是正常的,因此判断是自定义的Fastjson2TypeHandler没有生效。
问题排查
1、实体类注解
@TableName(autoResultMap = true)
2、需要映射处理的字段需要添加注解
@TableField(typeHandler = Fastjson2TypeHandler.class , value = "dynamic_information") private JSONObject dynamicInformation;
3、各种路径问题,字段拼写排查确保正确
4、可以尝试xml中resultMap使用 typeHandler 属性
此时问题依旧存在,于是怀疑ImportItemMapper接口问题,由于之前一直没有使用xml文件,于是决定尝试使用xml
public interface ImportItemMapper extends MyMapper<ImportItem> { List<ImportItem> getByBatchNumber(ItemQuery itemQuery); }
<?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.ruoyi.plm.mapper.ImportItemMapper"> <resultMap id="BaseResultMap" type="com.ruoyi.plm.model.entity.ImportItem"> <id column="dynamic_information" jdbcType="VARCHAR" property="dynamicInformation" typeHandler="com.ruoyi.plm.util.Fastjson2TypeHandler"/> </resultMap> <select id="getByBatchNumber" resultMap="BaseResultMap" parameterType="com.ruoyi.system.api.model.plm.ItemQuery"> SELECT * FROM import_item WHERE company_id = #{companyId} <if test="batchNumber != null and !batchNumber.isEmpty()"> AND batch_number = #{batchNumber} </if> <if test="mark != null"> AND mark = #{mark} </if> ${params.dataScope} </select> </mapper>
此时再次尝试后发现问题已经解决,既然这种方式可以解决问题,那么很有可能是因为自定义 TypeHandler 没能正确注册到 MyBatis,因此可以尝试放弃使用xml选则最后一种方式
5、 注册自定义TypeHandler到 MyBatis
@Configuration public class MyBatisConfig { @Bean public ConfigurationCustomizer mybatisConfigurationCustomizer() { return configuration -> { // 注册自定义 TypeHandler configuration.getTypeHandlerRegistry().register(JSONObject.class, JdbcType.VARCHAR, new Fastjson2TypeHandler()); }; } }
经测试注册后结合注解自定义sql语句查询一切正常,问题完美解决。
总结
出现增删改数据正常,但查询结果为null,很有可能是自定义的TypeHandler未生效,可以参考上述4或5的方法来解决问题。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。