MyBatis里json型字段到Java类的映射
一、简介
我们在用MyBatis里,很多时间有这样一个需求:POJO里有个属性是非基本数据类型,在DB存储时我们想存的是json格式的字符串,从DB拿出来时想直接映射成目标类型,也即json格式的字符串字段与Java类的相互类型转换。
当然,你可以为每个类写一个MyClassTypeHandler,但问题是要为每个类都写一个TypeHandler,过于繁琐。
有了泛型,一个通用的TypeHandler直接搞定。
二、源码
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>
a
MyBatis里json型字段到Java类的映射的更多相关文章
- JAVA类的创建: 创建JAVA的类 ,JAVA的字段,JAVA类的方法
1. 创建Java的类 如果说Java的一切都是对象,那么类型就是决定了某一类对象的外观与行为.可是类型的关键字不是type,而是class,创建一个新的类型要用下面的代码: 1 2 3 class ...
- 数据表-java类的映射
1.一个数据表对应一个java类 2.数据表的字段对应java类的属性 3.一对多的数据表关系 一方用一个java对象表示 多方用一个java对象数组表示 4.多对多的数据表关系:采用中间表,将多对多 ...
- Hibernate、Mybatis 通过数据库表反向生成java类和配置
一.通过MyEclipse生成Hibernate类文件和hbm.xml文件,或者annotation文件 (转载孙宇老师的文章) 二.Mybatis生成实体类和配置文件: myeclipse下生 ...
- mybatis的判定时间字段问题 java.lang.IllegalArgumentException: invalid comparison: cn.hutool.core.date.DateTime and java.lang.String
今天听组员说: mybatis在3.30版本及以上判定时间时 <if test="date_time != null and date_time != '' "> da ...
- mybatis的mapper.xml中使用java类中的全局变量
select * from demo where status = '${@cn.jichi.Global@zz}'
- MyBatis里字段到枚举类型的转换/映射
一.简介 我们在用MyBatis里,很多时间有这样一个需求:bean里有个属性是枚举,在DB存储时我们想存的枚举的代号,从DB拿出来时想直接映射成目标枚举类型,也即代号字段与Java枚举类的相互类型转 ...
- 使用mybatis中的自定义TypeHandler处理PostgreSQL中的Json类型字段
业务扩展字段在PostgreSQL数据库中经常会使用json格式的数据来存储,然而mybatis默认是没有实现json类型字段对应的TypeHandler,所以一般我们需要自定义mybatis的Typ ...
- Json串的字段如果和类中字段不一致,如何映射、转换?
Json串是我们现在经常会遇到的一种描述对象的字符串格式.在用Java语言开发的功能中,也经常需要做Json串与Java对象之间的转换. fastjson就是经常用来做Json串与Java对象之间的转 ...
- fastjson将json字符串转化为java对象
目录 一.导入一个fastjson的jar包 二.Json字符串格式 三.根据json的格式创建Java类 四.给java类的所有属性添加setter方法 五.转换为java对象 一.导入一个fast ...
随机推荐
- HDU_1010——小狗走迷宫DFS
Problem Description The doggie found a bone in an ancient maze, which fascinated him a lot. However, ...
- 移动web app开发框架
文章地址:http://www.cnblogs.com/soulaz/p/5586787.html jQuery Mobile jQuery Mobile框架能够帮助你快速开发出支持多种移动设备的Mo ...
- HER COFFEE夜场代金券【1折】_北京美食团购_360团购导航
HER COFFEE夜场代金券[1折]_北京美食团购_360团购导航 HER COFFEE夜场代金券
- Storm拓扑的并行度(parallelism)介绍
Storm拓扑的并行度(parallelism)介绍 1.Storm分为3个主要实体,用于在Storm集群中运行拓扑 工作进程:Worker Process,也称为Worker ...
- DedeCMS官方手册
DedeCMSV5.3使用手册 DedeCMSV57数据库结构文档 Dedecms 文件目录结构
- openflow tutorial 开始openflow的学习(一)
首先不废话介绍openflow了,自己也还搞不清楚究竟是个什么玩意儿,概括不出什么内容来,先做试验,有个大体的感性了解回来再总结吧. 第一步,搭建环境,这一步就是安装工具,不同的系统环境搭建不一致,我 ...
- C# List 泛型用法
List 类是 ArrayList 类的泛型等效类,某些情况下,用它比用数组和 ArrayList 都方便. 我们假设有一组数据,其中每一项数据都是一个结构. public struct Item{ ...
- django: template - built-in tags
本节介绍模板中的内置标签:if for 承上文,修改 views.py 如下: from django.shortcuts import render_to_response class Person ...
- Task与Thread间的区别
通过查找一些文章,得知,Task与Thread不可比.Task是为了利用多CPU多核的机制而将一个大任务不断分解成小任务,这些任务具体由哪一个线程或当前线程执行由OS来决定.如果你想自己控制由哪一个T ...
- for语句应用:乘法表
乘法表: for语句应用: 1: 2: public class chengfa { 3: public static void main(String[] args) { 4: //int i; 5 ...