The way Mybatis implements the conversion of Json strings in the database to Java objects


In the database at work, the fields of some tables store Json strings, which need to be deserialized into Java objects when they are taken out, so hereby record.
Mainly with the help of TypeHandler to help achieve.

1. Deserialize Json object

prerequisite configuration

The table data is as follows, the main focus is on the function field, which is now a Json object, and the method of Json array will be demonstrated later
insert image description here

Corresponding Java class

@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 Custom type handler, inherit 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 Configure PermissionHandler

In the Mybatis configuration file, you need to declare a custom processor, otherwise it will always report an error

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.

[Note] There are order requirements in the configuration file of mybatis. If there is an error under the configuration field, you have to look at the content of the prompt. It is because the position of typeHandlers is wrong.

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

1.3 Declare the field type in the SQL statement

On the corresponding field, use javaType to declare the type of the field.
The aforementioned @MappedJdbcTypes(JdbcType.VARCHAR) can also be omitted, and then
declared here with 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();

2. Deserialize Json array

prerequisite configuration

The table data is as follows, the function field is now a Json array
insert image description here

Corresponding Java class

@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 Custom type handler, inherit 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 Configure PermissionHandler

Similarly, in the Mybatis configuration file, declare a custom processor

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

2.3 Declare the field type in the SQL statement

[Note] The javaType here should use List instead of 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();

2. Test results

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

Guess you like

Origin blog.csdn.net/weixin_42717117/article/details/128500096