Mybatis实现数据库的Json字符串转换为Java对象的方式


在工作中遇到数据库中,某些表的字段存的是Json字符串,取出来的时候需要反序列化为Java对象,特此记录。
主要借助TypeHandler来帮助实现。

一、反序列化Json对象

前提配置

表数据如下,最主要关注function字段,现在为Json对象,后面演示Json数组的方式
在这里插入图片描述

对应的Java类

@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class Permission{
  private int seq;
  private String title;
  private boolean countEnable;
}

@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class Code {
  private int id;
  private Permission function;
}

1.1 自定义类型处理器,继承BaseTypeHandler

@MappedJdbcTypes(JdbcType.VARCHAR) // 表明对应字段在数据库中的类型,也可以写在对应的SQL语句处
public class PermissionHandler extends BaseTypeHandler<Permission> {
  // 序列化工具,我这里用的Jackson,也可以用gson等,需要自己写
  private Serializer serializer = new Serializer();

  @Override
  public void setNonNullParameter(PreparedStatement preparedStatement, int i, Permission permission, JdbcType jdbcType) throws SQLException {
    preparedStatement.setString(i, serializer.encode(permission));
  }

  @Override
  public Permission getNullableResult(ResultSet resultSet, String s) throws SQLException {
    return serializer.decode(resultSet.getString(s), Permission.class);
  }

  @Override
  public Permission getNullableResult(ResultSet resultSet, int i) throws SQLException {
    return serializer.decode(resultSet.getString(i), Permission.class);
  }

  @Override
  public Permission getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
    return serializer.decode(callableStatement.getString(i), Permission.class);
  }

1.2 配置PermissionHandler

在Mybatis的配置文件中,需要声明自定义的处理器,否则会一直报错

org.apache.ibatis.exceptions.PersistenceException: 
### Error building SqlSession.
### The error may exist in com/mediacomm/dao/IRegCodeDao.java (best guess)
### Cause: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: java.lang.IllegalStateException: Type handler was null on parameter mapping for property 'function'. It was either not specified and/or could not be found for the javaType (java.util.List) : jdbcType (null) combination.

【注意】mybatis的配置文件中是有顺序要求的,如果configuration字段下出现了报错,就要看一下提示的内容,我就是因为typeHandlers的位置不对。

<configuration>
    ......
    <typeHandlers>
        <typeHandler handler="com.ccc.handler.PermissionHandler"/>
    </typeHandlers>
    ......
    <configuration>

1.3 SQL语句中声明字段类型

在对应的字段上,使用javaType声明字段的类型。
前面提到的@MappedJdbcTypes(JdbcType.VARCHAR),也可以不写,然后在此处用
jdbcType = JdbcType.VARCHAR声明

public interface IDao{
  @Select("select * from code")
  @Results(id = "codeMap",
          value = {
                  @Result(id = true, column = "id", property = "id"),
                  @Result(column = "function", property = "function", javaType = com.ccc.domain.Permission.class),
          })
  Code findAll();

二、反序列化Json数组

前提配置

表数据如下,function字段,现在为Json数组的方式
在这里插入图片描述

对应的Java类

@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class Permission{
  private int seq;
  private String title;
  private boolean countEnable;
}

@Data
@JsonIgnoreProperties(ignoreUnknown = true)
public class Code {
  private int id;
  private List<Permission> function;
}

2.1 自定义类型处理器,继承BaseTypeHandler

@MappedJdbcTypes(JdbcType.VARCHAR)
public class PermissionHandler extends BaseTypeHandler<List<Permission>> {
  private Serializer serializer = new LicenceSerializer();

  @SneakyThrows
  @Override
  public void setNonNullParameter(PreparedStatement preparedStatement, int i, List<Permission> permission, JdbcType jdbcType) throws SQLException {
    preparedStatement.setString(i, serializer.encode(permission));
  }

  @SneakyThrows
  @Override
  public List<Permission> getNullableResult(ResultSet resultSet, String s) throws SQLException {
    // 使用Jackson解析Json数组的方式,并以集合的方式返回
    return serializer.decodeList(resultSet.getString(s), Permission.class);
  }

  @SneakyThrows
  @Override
  public List<Permission> getNullableResult(ResultSet resultSet, int i) throws SQLException {
    return serializer.decodeList(resultSet.getString(i), Permission.class);
  }

  @SneakyThrows
  @Override
  public List<Permission> getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
    return serializer.decodeList(callableStatement.getString(i), Permission.class);
  }
}

2.2 配置PermissionHandler

同样的,在Mybatis的配置文件中,声明自定义的处理器

<configuration>
    ......
    <typeHandlers>
        <typeHandler handler="com.ccc.handler.PermissionHandler"/>
    </typeHandlers>
    ......
    <configuration>

2.3 SQL语句中声明字段类型

【注意】此处的javaType要用List而不再是Permission

public interface IDao{
  @Select("select * from code")
  @Results(id = "codeMap",
          value = {
                  @Result(id = true, column = "id", property = "id"),
                  @Result(column = "function", property = "function", javaType = java.util.List.class),
          })
  Code findAll();

二、测试结果

[Code(id=1,function=[Permission(seq=3, title=null, countEnable=false), Permission(seq=3, title=null, countEnable=false)])]```

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要将MyBatis中的JSON字符串转换对象,你需要进行以下步骤: 1. 首先,在你的实体类中定义对应的属性,确保属性的类型与数据库中存储的JSON字符串所表示的类型相匹配。在你的实体类中,你应该有一个名为limiting的属性,类型为Object。 2. 然后,在你的实体类的构造函数中,将limiting参数的类型设置为Object,而不是ParameterLimiting。这是因为在数据库中存储的是JSON字符串,而不是具体的ParameterLimiting对象。 3. 接下来,创建一个类型处理器(TypeHandler)来完成从JSON字符串对象转换。你可以继承BaseTypeHandler类,并指定泛型为ParameterLimiting。在该类型处理器中,你需要实现一些方法,例如setNonNullParameter用于将对象转换JSON字符串并写入数据库,getNullableResult用于从数据库中读取JSON字符串并将其转换对象。在setNonNullParameter方法中,你可以使用JSON.toJSONString方法将对象转换JSON字符串,并调用PreparedStatement的setObject方法将其写入数据库。 4. 最后,在你的MyBatis的配置文件中,将该类型处理器注册为对应属性的类型处理器。你需要在<mappers>标签下添加一个<typeHandlers>标签,并在其中配置你的类型处理器。在配置中,你需要指定对应属性的Java类型以及该属性在数据库中的JDBC类型。 总结起来,将MyBatis中的JSON字符串转换对象的过程包括:在实体类中定义属性,修改构造函数,创建类型处理器,并在配置文件中注册该类型处理器。这样,在查询结果集时,MyBatis就会自动将数据库中的JSON字符串转换为对应的对象

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值