MyBatis-Plus如何通過注解使用TypeHandler
通過注解使用TypeHandler
在使用MyBatis時,我們與數(shù)據(jù)表中字段映射的java中的bean的屬性字段,往往包含了自定義復(fù)雜類型,比如一個varchar保存的json字符串映射到的java字段是Person類型的時候,就需要用到 “字段類型處理器了”,也就是TypeHandler.
使用MyBatis的TypeHandler的時候,自定義實(shí)現(xiàn)起來還是比較麻煩,需要統(tǒng)一配置,自動識別java字段類型,然后匹配了才處理。
這樣在開發(fā)的時候并不好控制,而且不是很直觀。
在新版本的MyBatis-Plus中提供了一種新的配置 “字段處理器” 的方法,通過在javaBean中加入對應(yīng)的注解即可實(shí)現(xiàn)。
下面我們先看一下MyBatis-Plus官方文檔中的使用說明:
官方示例
類型處理器,用于 JavaType 與 JdbcType 之間的轉(zhuǎn)換,用于 PreparedStatement 設(shè)置參數(shù)值和從 ResultSet 或 CallableStatement 中取出一個值,本文講解 mybaits-plus 內(nèi)置常用類型處理器如何通過TableField注解快速注入到 mybatis 容器中。
示例工程:
?? mybatis-plus-sample-typehandlerJSON 字段類型
@Data @Accessors(chain = true) @TableName(autoResultMap = true) public class User { ? ? private Long id; ? ? ... ? ? /** ? ? ?* 注意!! 必須開啟映射注解 ? ? ?* ? ? ?* @TableName(autoResultMap = true) ? ? ?* ? ? ?* 以下兩種類型處理器,二選一 也可以同時存在 ? ? ?* ? ? ?* 注意??!選擇對應(yīng)的 JSON 處理器也必須存在對應(yīng) JSON 解析依賴包 ? ? ?*/ ? ? @TableField(typeHandler = JacksonTypeHandler.class) ? ? // @TableField(typeHandler = FastjsonTypeHandler.class) ? ? private OtherInfo otherInfo; }
該注解對應(yīng)了 XML 中寫法為
<result column="other_info" jdbcType="VARCHAR" property="otherInfo" typeHandler="com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler" />
下面我們參照官方給出的案例,用kotlin實(shí)現(xiàn)一個具體的:
Kotlin案例
首先是kotlin實(shí)體類:
@TableName(autoResultMap = true) data class Policy ?( ? ? ... ? ? /** ? ? ?* 策略內(nèi)容,json格式,規(guī)則參考文檔 ? ? ?*/ ? ? @TableField(typeHandler = PolicyBodyTypeHandler::class) ? ? var content: PolicyBody? = null, ? ? ... )
然后是對應(yīng)TypeHandler的實(shí)現(xiàn),主要就是json序列化規(guī)則,因?yàn)槲覀冊贁?shù)據(jù)庫存的就是json字符串。
class PolicyBodyTypeHandler : BaseTypeHandler<PolicyBody>() { ? ? override fun getNullableResult(p0: ResultSet?, p1: String?): PolicyBody? { ? ? ? ? val result = p0?.getString(p1) ?: return null ? ? ? ? return JSON.parseObject(result, PolicyBody::class.java) ? ? } ? ? override fun getNullableResult(p0: ResultSet?, p1: Int): PolicyBody? { ? ? ? ? val result = p0?.getString(p1) ?: return null ? ? ? ? return JSON.parseObject(result, PolicyBody::class.java) ? ? } ? ? override fun getNullableResult(p0: CallableStatement?, p1: Int): PolicyBody? { ? ? ? ? val result = p0?.getString(p1) ?: return null ? ? ? ? return JSON.parseObject(result, PolicyBody::class.java) ? ? } ? ? override fun setNonNullParameter(statement: PreparedStatement?, index: Int, javaObj: PolicyBody?, jdbcType: JdbcType?) { ? ? ? ? statement?.setString(index, JSON.toJSONString(javaObj)) ? ? } }
下面是xml中的使用:
<!-- 通用查詢映射結(jié)果 --> ? ? <resultMap id="BaseResultMap" type="com.inooy.write.ucenter.entity.Policy"> ? ? ? ? <id column="id" property="id" /> ? ? ? ? <result column="code" property="code" /> ? ? ? ? <result column="name" property="name" /> ? ? ? ? <result column="description" property="description" /> ? ? ? ? <result column="content" property="content" typeHandler="com.inooy.write.ucenter.policy.PolicyBodyTypeHandler"/> ? ? ? ? <result column="deleted" property="deleted" /> ? ? ? ? <result column="createTime" property="createTime" /> ? ? ? ? <result column="updateTime" property="updateTime" /> ? ? ? ? <result column="version" property="version" /> ? ? </resultMap>
自定義TypeHandler使用
可通過自定義的TypeHandler實(shí)現(xiàn)某個屬性在插入數(shù)據(jù)庫以及查詢時的自動轉(zhuǎn)換,本例中是要將Map類型的屬性轉(zhuǎn)化成CLOB,然后存入數(shù)據(jù)庫。由于是復(fù)雜的Map,mp自帶的json轉(zhuǎn)換器會丟失部分信息。
類型轉(zhuǎn)換器還可以通過注解配置 java 類型和 jdbc 類型:
@MappedTypes
:注解配置 java 類型@MappedJdbcTypes
:注解配置 jdbc 類型
定義:
@Slf4j @MappedTypes({Object.class}) @MappedJdbcTypes(JdbcType.VARCHAR) public class WeightListTypeHandler ?extends AbstractJsonTypeHandler<Object> { ? ? private static Gson gson = new Gson(); ? ? private final Class<?> type; ? ? public WeightListTypeHandler(Class<?> type) { ? ? ? ? if (log.isTraceEnabled()) { ? ? ? ? ? ? log.trace("WeightListTypeHandler(" + type + ")"); ? ? ? ? } ? ? ? ? Assert.notNull(type, "Type argument cannot be null"); ? ? ? ? this.type = type; ? ? } ? ? @Override ? ? protected Object parse(String json) { ? ? ? ? Type type1 = new TypeToken<Map<String, List<WeightItem>>>(){}.getType(); ? ? ? ? return gson.fromJson(json, type1); ? ? } ? ? @Override ? ? protected String toJson(Object obj) { ? ? ? ? return gson.toJson(obj); ? ? } ? ? public static void setGson(Gson gson) { ? ? ? ? Assert.notNull(gson, "Gson should not be null"); ? ? ? ? WeightListTypeHandler.gson = gson; ? ? } }
使用:
注意@TableName 注解 autoResultMap 屬性
@Data @NoArgsConstructor @TableName(value = "mix_target",autoResultMap = true) public class MixTarget extends Model<MixTarget> { ? ? @TableId(value = "id", type = IdType.AUTO) ? ? private Long id; ? ? /** ? ? ?*指標(biāo)描述 ? ? ?*/ ? ? @TableField("description") ? ? private String description; ? ? /** ? ? ?* 指標(biāo)名 ? ? ?*/ ? ? @TableField("name") ? ? private String name; ? ? /** ? ? ?* 對應(yīng)屬性名 ? ? ?*/ ? ? @TableField("property_name") ? ? private String propertyName; ? ? /** ? ? ?* 起始點(diǎn)類型 ? ? ?*/ ? ? @TableField("source_type") ? ? private String sourceType; ? ? /** ? ? ?* 屬性對應(yīng)權(quán)值列表 ? ? ?* key 屬性名 value指定條件下的權(quán)值 ? ? ?*/ ? ? @TableField(value = "weight_list",typeHandler = WeightListTypeHandler.class,jdbcType = JdbcType.CLOB) ? ? private Map<String, List<WeightItem>> weightList; ? ? /** ? ? ?* 運(yùn)行狀態(tài) ? ? ?* 0 新建未運(yùn)行 ? ? ?* 1 運(yùn)行中 ? ? ?* 2 已運(yùn)行 成功 ? ? ?* 3 已運(yùn)行 失敗 ? ? ?*/ ? ? @TableField("status") ? ? private Integer status; ? ? /** ? ? ?* 是否可用 ? ? ?* 1 true ? ? ?* 0 false ? ? ?*/ ? ? @TableField("enable") ? ? private Integer enable; ? ? @TableField("create_time") ? ? private LocalDateTime createTime; }
以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
如何基于SpringMVC實(shí)現(xiàn)斷點(diǎn)續(xù)傳(HTTP)
這篇文章主要介紹了如何基于SpringMVC實(shí)現(xiàn)斷點(diǎn)續(xù)傳(HTTP),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-01-01maven模塊化開發(fā)部署實(shí)現(xiàn)方案
有些用戶有定制化需求,需要添加新的模塊功能,因此需要平臺主體功能迭代的同時,非主體功能和定制化功能插件化,本文給大家介紹maven模塊化開發(fā)部署實(shí)現(xiàn)方案,感興趣的朋友一起看看吧2024-01-01Mybatis-Plus多表關(guān)聯(lián)查詢的使用案例解析
這篇文章主要介紹了Mybatis-Plus多表關(guān)聯(lián)查詢的使用,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-05-05SpringBoot如何配置數(shù)據(jù)庫主從shardingsphere
這篇文章主要介紹了SpringBoot如何配置數(shù)據(jù)庫主從shardingsphere問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-04-04