mybatis存取mysql中的json

Posted guofx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mybatis存取mysql中的json相关的知识,希望对你有一定的参考价值。

mysql 5.7后新增了一个json类型字段,以往json入库都是转字符串,取到前端造成了不少困扰。今天就做了个小例子把这个整合到ssm例子中。

这里插句题外话,因为最近开始改用idea,配置项目的时候出了一大堆问题,这边也顺便说下如果idea在启动tomcat客户端控制台出现乱码处理办法

打开idea安装目录-bin
用记事本打开idea.exe.vmoptions和idea64.exe.vmoptions文件
在文件后面添加一行:-Dfile.encoding=UTF-8

好了进入整体

第一步先配置一个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);
    

  mapper代码

<?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.cm.dao.UserDao">

    <resultMap id="user" type="com.cm.model.UserModel">
        <id column="id" jdbcType="NUMERIC" property="id"/>
        <result column="name" jdbcType="VARCHAR" property="name"/>
        <result column="age" jdbcType="NUMERIC" property="age"/>
        <result column="hobby" jdbcType="NUMERIC" property="hobby" typeHandler="com.cm.mybaits.JsonTypeHandler"/>

    </resultMap>
    <select id="getAllUsers" resultMap="user">
        select * from user
    </select>
    
    <insert id="addUser">
        <!--ignore忽略自动增长的主键id-->
        insert ignore into user (name, age, hobby) values (#id, #name ,#hobby, typeHandler=com.cm.mybaits.JsonTypeHandler)
    </insert>
    
    <update id="updateUser">
        update user set name=#name where id=#id
    </update>

    <delete id="deleteUser" parameterType="String">
        delete from user where id=#id
    </delete>

    <select id="getUser" resultType="UserModel">
        select * from user where id = #id
    </select>
</mapper>

  mysql表结构

技术图片

插入的测试代码

技术图片

效果预览

入库

技术图片

取数据

技术图片

这边有个坑是mysql 驱动一定要5.1.40,不然取出来的json中文是乱码。虽然说是低于5.1.36会乱码,但是我试了5.1.6还是乱码。

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.40</version>
</dependency>
最后附上我的项目是一个SSM框架的小demo,有兴趣的小伙伴可以下载参考

链接:https://pan.baidu.com/s/14yaYRg-fXeyaPN7oWU7-Ow
提取码:dggg



以上是关于mybatis存取mysql中的json的主要内容,如果未能解决你的问题,请参考以下文章

spring + mybatis 存取clob

使用java语言操作,如何来实现MySQL中Blob字段的存取

mybatis中支持mysql中的变量吗?

MySQL 和 Oracle 在 MyBatis 使用中的区别

mybatis中的模糊查询,Oracle和MySQL中的concat

Atitit Mysql查询优化器 存取类型 范围存取类型 索引存取类型 AND or的分析