Mybatis存取json字段轉為Java對象方案


背景:

項目中有一些數據只需要查詢,不需要檢索,這些數據可以通過存儲jsonStr,存儲在關系型數據庫中。

假設,我們需要記錄動物園小動物的一些信息,我們就可以新建一張animal表,

但是不同種類的小動物身上有不同的信息,比如大象需要記錄象牙的長度,這個信息,在其他小動物上是沒有的,不屬於通用屬性,這種信息以jsonStr的格式存到數據庫中就比較合適。但是我們的代碼中還是想用對象來接收數據,持久話層使用的是mybatis 的話,需要使用mybatis 自定義類型轉換器。

自定義typeHandler並使用,共有兩個步驟

  1. 自定義TypeHandler,繼承BaseTypeHandler或者實現TypeHandler
  2. 在mapper中配置所需要自定義TypeHandler的地方,如resultMap中指定參數。

1. 自定義TypeHandler

import cn.hutool.json.JSONUtil;
/**
	繼承BaseTypeHandler,實現一個json轉object通用的類
	注意:這里的json工具類使用的時hutool中的JSONUtil,用fastjson或其他json框架的注意替換
*/
public class AbstractObjectTypeHandler<T> extends BaseTypeHandler<T> {

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {
        ps.setString(i, JSONUtil.toJsonStr(parameter));
    }

    @Override
    public T getNullableResult(ResultSet rs, String columnName)
        throws SQLException {
        String data = rs.getString(columnName);
        return StringUtils.isBlank(data) ? null : JSONUtil.toBean(data, (Class<T>) getRawType());
    }

    @Override
    public T getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        String data = rs.getString(columnIndex);
        return StringUtils.isBlank(data) ? null : JSONUtil.toBean(data, (Class<T>) getRawType());
    }

    @Override
    public T getNullableResult(CallableStatement cs, int columnIndex)
        throws SQLException {
        String data = cs.getString(columnIndex);
        return StringUtils.isBlank(data) ? null : JSONUtil.toBean(data, (Class<T>) getRawType());
    }
}

@MappedJdbcTypes({JdbcType.VARCHAR})
@MappedTypes({Info.class})
public class UserInfoHandler extends  AbstractObjectTypeHandler<Info>{
    // 繼承通用json轉Object的AbstractObjectTypeHandler,指定所轉class類型
}

public class User{
    private String name;
    private Integer age;
    private Info info;
}

public class Info{
    private String usedName;
    private Integer height;
}

user表:image-20210309143456569
image-20210309143641306

2. 在mapper中配置

我們定義了MyDateTypeHandler,需要在mapper中配置:

  1. 查詢時,查詢時我們配置resultMap
  2. 插入、修改時,我們有三種配置方式
    1. javaType,jdbcType ,TypeHandler都指定
    2. 指定javaType,jdbcType
    3. 只指定typeHandler
<!--配置resultMap-->
<resultMap id="userResultMap" type="org.sang.bean.User">
        <result typeHandler="com.zyy.handler.UserInfoHandler" column="info" javaType="com.zyy.domain.Info"
                jdbcType="VARCHAR"
                property="info"/>
</resultMap>
<!--查詢-->
<select id="getUser" resultMap="userResultMap">
        select * from user
</select>

<!--1. javaType,jdbcType ,TypeHandler都指定-->
<insert id="insertUser" parameterType="org.sang.bean.User">
        INSERT INTO user(name,age,info) VALUES (#{name},#{age},#{info,javaType=com.zyy.domain.Info,jdbcType=VARCHAR,typeHandler=com.zyy.handler.UserInfoHandler})
 </insert>

<!--2. 指定javaType,jdbcType-->
<insert id="insertUser2">
        INSERT INTO user(name,age,info) VALUES (#{name},#{age},#{info,javaType=com.zyy.domain.Info,jdbcType=VARCHAR})
 </insert>

<!--3. 只指定typeHandler-->
<insert id="insertUser3">
        INSERT INTO user(name,age,info)  VALUES (#{name},#{age},#{info,typeHandler=com.zyy.handler.UserInfoHandler})
</insert>

除了在mapper文件中配置,我們也可以通過配置文件將typeHandler注冊進去,但是這種方式只能結果讀取時數據的轉換

mybatis:
	# 配置掃描包
    typeHandlersPackage: com.hc.etf.config.typeHandel

更多 Mybatis TypeHandler 相關知識可見:https://www.cnblogs.com/zhaoyuan72/p/14475120.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM