MyBatis in json-type field to map Java classes (rpm)

Transfer from https://www.cnblogs.com/waterystone/p/5547254.html

I. Introduction

  We use MyBatis, many times there is such a demand: POJO there attributes non-basic data types, stored in the DB when we want to keep the string json format directly mapped to the destination type from the DB out, i.e. json type string fields each Java class format conversion .

  Of course, you can write a MyClassTypeHandler for each class, but the problem is to write a TypeHandler for each class, too cumbersome.

  With generics, a generic TypeHandler get directly.

 

Second, the source

See: the Spring-the mybatis-the Test

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
package  com.adu.spring_test.mybatis.typehandler;
 
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;
import  org.codehaus.jackson.map.ObjectMapper;
import  org.codehaus.jackson.map.SerializationConfig.Feature;
import  org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion;
 
 
/**
  * mapper里json型字段到类的映射。
  * 用法一:
  * 入库:#{jsonDataField, typeHandler=com.adu.spring_test.mybatis.typehandler.JsonTypeHandler}
  * 出库:
  * <resultMap>
  * <result property="jsonDataField" column="json_data_field" javaType="com.xxx.MyClass" typeHandler="com.adu.spring_test.mybatis.typehandler.JsonTypeHandler"/>
  * </resultMap>
  *
  * 用法二:
  * 1)在mybatis-config.xml中指定handler:
  *      <typeHandlers>
  *              <typeHandler handler="com.adu.spring_test.mybatis.typehandler.JsonTypeHandler" javaType="com.xxx.MyClass"/>
  *      </typeHandlers>
  * 2)在MyClassMapper.xml里直接select/update/insert。
  *
  *
  * @author yunjie.du
  * @date 2016/5/31 19:33
  */
public  class  JsonTypeHandler<T  extends  Object>  extends  BaseTypeHandler<T> {
     private  static  final  ObjectMapper mapper =  new  ObjectMapper();
     private  Class<T> clazz;
 
     public  JsonTypeHandler(Class<T> clazz) {
         if  (clazz ==  null throw  new  IllegalArgumentException( "Type argument cannot be null" );
         this .clazz = clazz;
     }
 
     @Override
     public  void  setNonNullParameter(PreparedStatement ps,  int  i, T parameter, JdbcType jdbcType)  throws  SQLException {
         ps.setString(i,  this .toJson(parameter));
     }
 
     @Override
     public  T getNullableResult(ResultSet rs, String columnName)  throws  SQLException {
         return  this .toObject(rs.getString(columnName), clazz);
     }
 
     @Override
     public  T getNullableResult(ResultSet rs,  int  columnIndex)  throws  SQLException {
         return  this .toObject(rs.getString(columnIndex), clazz);
     }
 
     @Override
     public  T getNullableResult(CallableStatement cs,  int  columnIndex)  throws  SQLException {
         return  this .toObject(cs.getString(columnIndex), clazz);
     }
 
     private  String toJson(T object) {
         try  {
             return  mapper.writeValueAsString(object);
         catch  (Exception e) {
             throw  new  RuntimeException(e);
         }
     }
 
     private  T toObject(String content, Class<?> clazz) {
         if  (content !=  null  && !content.isEmpty()) {
             try  {
                 return  (T) mapper.readValue(content, clazz);
             catch  (Exception e) {
                 throw  new  RuntimeException(e);
             }
         else  {
             return  null ;
         }
     }
 
     static  {
         mapper.configure(Feature.WRITE_NULL_MAP_VALUES,  false );
         mapper.setSerializationInclusion(Inclusion.NON_NULL);
     }
}

  

 

三、QA

3.1 Q:Cause: java.lang.RuntimeException: Unable to find a usable constructor for class

A:mybatis版本过低,类型不能识别,造成通用typeHandler的构造函数构造失败。之前用3.1.1时报过这个错,后来改成3.2.3就没问题了,现在用3.4.0也没问题。贴上现在的配置吧:

复制代码
<!-- mybatis -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.4.0</version>
</dependency>
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>1.3.0</version>
</dependency>

Guess you like

Origin www.cnblogs.com/ffaiss/p/11430144.html