欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Mybatis讀取和存儲json類型數(shù)據(jù)的實現(xiàn)

 更新時間:2023年06月08日 15:23:32   作者:怪 咖@  
本文主要介紹了Mybatis讀取和存儲json類型數(shù)據(jù)的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

不管數(shù)據(jù)庫當中是以json還是longtext數(shù)據(jù)類型來存json,都可以在mybatis當中使用string來接數(shù)據(jù)。這一點毋庸置疑!但是想要使用JSONObject類型的字段來取值是否可以呢?

一、測試使用JSONObject來獲取json

接下來我們來測試一下,我用的是mybatis-plus框架,mybatis-plus和mybatis是一樣的,無非就是mybatis-plus封裝好了一些crud方法。但是對于手寫xml來說兩個框架是一樣的。

實體類如下:這里的JSONObject我用的hutool工具包的,JSONObject一般引用的json框架都有

測試接口如下:這里一共寫了兩個接口,一個接口是手寫的,一個是調(diào)用的mybatis-plus當中提供的BaseMapper的selectList方法

查詢結(jié)果如下:假如想要使用JSONObject來映射數(shù)據(jù)庫當中的json數(shù)據(jù),不做任何配置是取不到的。

這個是訪問mybatis-plus當中提供的查詢方法

得出結(jié)論:在不做任何配置的情況下,不管是手寫的xml接口還是用mybatis-plus自帶的查詢接口,都是無法將json數(shù)據(jù)映射到JSONObject類型的字段當中的。

二、設置@TableName的autoResultMap為true,@TableField的typeHandler為JacksonTypeHandler.class

兩個接口測試如下:調(diào)整過后,mybatis-plus當中自帶的接口是可以將json數(shù)據(jù)映射到JSONObject類型的字段當中的(不管是longtext類型存儲的json還是json類型存儲的json數(shù)據(jù))

對于mybatis-plus框架我們將@TableName的autoResultMap為true,然后@TableField的typeHandler為JacksonTypeHandler.class之后,調(diào)用mybatis-plus自帶的查詢接口是可以將json數(shù)據(jù)映射到JSONObject類型的字段當中的。

注意:如果@TableName的autoResultMap不設置為true,那么設置typeHandler不會生效

三、設置xml當中的resultMap

使用mybatis,有兩個屬性標簽<resultType>、<resultMap>可以提供結(jié)果映射。

雖然resultType 屬性在大部分情況下都夠用,但是在一些特殊情況下無能為力,比如屬性名和列名不一致,為一些連接的復雜語句編寫映射代碼。遇到這些情況,我們要使用<resultMap>標簽,一份 <resultMap> 能夠代替實現(xiàn)同等功能的數(shù)千行代碼。

resultMap 元素是 MyBatis 中最重要最強大的元素。resultMap 的設計思想是,對簡單的語句做到零配置,對于復雜一點的語句,只需要描述語句之間的關系就行了。

注意:這里去掉了<reslutType>屬性,用<resultMap>代替,二者只能選擇其中的一個。

其實在上面設置@TableName的autoResultMap為true,@TableField的typeHandler為JacksonTypeHandler.class等同于在xml當中配置resultMap的某個屬性使用JacksonTypeHandler。只不過mybatis-plus這塊使用的是注解的形式,而mybatis應該是沒有注解方式的。所以他只能用以下方式:

<?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.gzl.cn.mysqljson.mapper.UserMapper">
    <resultMap id="BaseResultMap" type="com.gzl.cn.mysqljson.model.User">
        <id column="id" jdbcType="BIGINT" property="id" />
        <result column="name" jdbcType="VARCHAR" property="name" />
        <result column="age" jdbcType="INTEGER" property="age" />
        <result column="email" jdbcType="VARCHAR" property="email" />
        <result column="result_json" jdbcType="OTHER" property="resultJson" javaType="cn.hutool.json.JSONObject" typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler"/>
        <result column="result_text" jdbcType="VARCHAR" property="resultText" javaType="cn.hutool.json.JSONObject" typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler"/>
    </resultMap>
    <select id="getAllList" resultMap="BaseResultMap">
        select * from user
    </select>
</mapper>

查詢結(jié)果如下:

四、JacksonTypeHandler講解

JacksonTypeHandler是mybatis-plus提供的,不管是使用注解方式還是使用xml方式當中都使用到了JacksonTypeHandler類。那么這個類到低是干什么的?假如我使用的是mybatis而并不是mybatis-plus該怎么辦?

JacksonTypeHandler就是專門用來做數(shù)據(jù)映射轉(zhuǎn)換的。是mybatis-plus的,但是實際上繼承的是BaseTypeHandler,而BaseTypeHandler是mybatis的,那么我們也就可以基于BaseTypeHandler來自己寫一個。

import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class JsonTypeHandler<T> 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 {
            	// 核心轉(zhuǎn)換,將數(shù)據(jù)庫讀取的字符串,轉(zhuǎn)換為指定的class類型
                return (T) mapper.readValue(content, clazz);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        } else {
            return null;
        }
    }
}

五、新增假如是JSONObject異常問題

而對于 typeHandler 屬性,MyBatis 只支持寫在 2 個地方:

定義在 resultMap 里,作用于查詢結(jié)果的封裝

定義在 insert 和 update 語句的 #{property} 中的 property后面
(例:#{property,typehandler=xxx.xxx.xxx}),并且只作用于當前 設置值

假如不配置是會報錯的!

六、遇到轉(zhuǎn)義的問題

在使用JSONObject作為Java對象的類型存值和取值是可以原樣返回的:

那假如是使用的String存值和取值會發(fā)生什么樣的場景呢?

首先使用String來直接接json對象肯定是不可以的,直接會報400異常。

針對于這個問題有兩種方案,一種是對json建立Java對象,還有一種是直接使用JSONObject

假如使用字符串來查詢會出現(xiàn)轉(zhuǎn)義的問題

遇到這個問題可以使用commons-lang3包下的StringEscapeUtils.unescapeJava進行轉(zhuǎn)換一下

查詢結(jié)果如下:

 到此這篇關于Mybatis讀取和存儲json類型數(shù)據(jù)的實現(xiàn)的文章就介紹到這了,更多相關Mybatis讀取和存儲json內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

最新評論