精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

實體類JSON字段的終極轉換思路

數據庫 其他數據庫
這種是最簡單最普遍的寫法,JSON不就是字符串嘛,能存能取就行了,存數據庫跟存銀行沒什么區別,數據庫存一條,銀行存一“張不夠花”。前后端要用?對不起,自己解析去吧,用Json工具類,轉完七七四十九遍以后,別把這個字符串玩壞就行。

哈嘍,各位代碼戰士們,我是Jensen,一個夢想著和大家一起在代碼的海洋里遨游,順便撿起那些散落的知識點的程序員小伙伴。

聽說大家都不愛當“接碼俠”,筆者在接盤別人代碼之時也常意難平,我的心情大部分是這樣的:

今天看看數據庫JSON字段是怎么映射到代碼上來的。

本文涉及技術棧:類型處理器、D3Boot。

一、都有些什么寫法

1.用String映射

這種是最簡單最普遍的寫法,JSON不就是字符串嘛,能存能取就行了,存數據庫跟存銀行沒什么區別,數據庫存一條,銀行存一“張不夠花”。

前后端要用?對不起,自己解析去吧,用Json工具類,轉完七七四十九遍以后,別把這個字符串玩壞就行。

完了以后,隔壁組的數據分析獅張開了她的獠牙看向你……

2.用JSONObject映射

那我用世界500強公司的com.alibaba.fastjson.JSONObject總可以了吧。

可以是可以,但麻煩是真麻煩,取元素出來還得轉換成具體的類型,只能通過字符串Key取值,還得引入個fastjson包,對于沒什么阿里信仰的同學可能不是那么的友好。

Hutool包也有個同類名的cn.hutool.json.JSONObject,一不小心把兩個給搞混就GG了。

要是再遇到你的同類把一個實體從頭傳到尾,再作為DTO提供Jar包出去就……

3.自定義類型處理器

其實,在Mybatis這個主流ORM框架中,有這么一個抽象類:

org.apache.ibatis.type.BaseTypeHandler<T>

它是 MyBatis 框架中一個非常重要的類,它提供了一個通用的基類,用于自定義類型處理器(TypeHandler)。

在 MyBatis 中,類型處理器負責在 Java 類型和 JDBC 類型之間的轉換。當你想要對某種類型進行特殊的處理,或者 MyBatis 默認的類型處理器不能滿足你的需求時,你可以自定義一個類型處理器。

以下是 BaseTypeHandler的一些關鍵點:

  1. 泛型:BaseTypeHandler<T> 使用泛型 T 來指定它所處理的 Java 類型。
  2. 繼承:自定義類型處理器通常繼承自 BaseTypeHandler<T>,并且重寫幾個核心方法。
  3. 核心方法——void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType):此方法用于將 Java 類型設置到 SQL 語句的參數中。
  4. 核心方法——T getResult(ResultGetter getter, Class<T> clazz):此方法用于從 SQL 查詢的結果集中獲取 Java 類型。
  5. 類型轉換:BaseTypeHandler 的子類可以實現具體的類型轉換邏輯,包括日期時間格式的轉換、枚舉類型的轉換、復雜對象的序列化和反序列化等。
  6. 配置:自定義的類型處理器可以在 MyBatis 的映射文件中配置,與特定的字段或結果集映射相關聯。
  7. 重用:由于 BaseTypeHandler 是泛型的,因此可以為不同的類型創建不同的處理器,同時重用相同的處理邏輯。

通過繼承 BaseTypeHandler<T> 并實現必要的方法,你可以完全控制數據在 Java 對象和數據庫之間的轉換過程,這為處理復雜的業務邏輯提供了靈活性。

通過類型處理器,我們可以映射成任意類型,存取數據其實沒有那么的麻煩。

不錯不錯,就它了。

二、還是先造個輪子吧

BaseTypeHandler子類已經支持挺多常見類型了,但我們要支持更多的類型,就必須自己寫。繼承BaseTypeHandler要覆寫的方法有點多,我們先封裝一輪,把核心的三個方法暴露出來:
public abstract class BaseTypeHandler<T> extends org.apache.ibatis.type.BaseTypeHandler<T> {
    /**
     * 獲取實際的類型,用于后續的類型注冊與類型判斷
     */
    public Class<T> type() {
        return (Class<T>) ReflectionKit.getSuperClassGenericType(this.getClass(), 0);
    }
    /**
     * 把指定類型轉換為字符串類型,對應寫庫
     */
    protected abstract String convert(T obj);
    /**
     * 把字符串類型解析成指定類型,對應讀庫
     */
    protected abstract T parse(String result);
    public void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {
        if (parameter == null) return;
        ps.setString(i, this.convert(parameter));
    }
    public T getNullableResult(ResultSet rs, String columnName) throws SQLException {
        String str = rs.getString(columnName);
        return str == null || str.isEmpty() ? null : this.parse(str);
    }
    public T getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        String str = rs.getString(columnIndex);
        return str == null || str.isEmpty() ? null : this.parse(str);
    }
    public T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        String str = cs.getString(columnIndex);
        return str == null || str.isEmpty() ? null : this.parse(str);
    }
}

接著,繼承這個抽象類再寫一個子抽象類:

/**
 * 自定義POJO類型轉換器父類:json/varchar <-> T
 * 繼承該類并加@Component注解,放在entity下的typehandlers目錄,PO類無需在@TableField注解上加類型處理器,能自動轉換
 *
 * @param <T> 自定義POJO,一般以VO命名,與Model同目錄,注意T不能是List集合或Map類型,但可以是數組類型(以實現對對象數組的互轉)
 * @author Jensen
 * @公眾號 架構師修行錄
 */
@Slf4j(topic = "### BASE-DATA : TypeHandlers ###")
public abstract class JsonStringTypeHandler<T> extends BaseTypeHandler<T> {
    private Class<?> componentType;
    private Object[] componentArray;
    public JsonStringTypeHandler() {
        Class<T> tClass = type();
        // 判斷具體的類型是否為數組
        if (tClass.isArray()) {
            Class<Object[]> arrayClass = (Class<Object[]>) tClass;
            this.componentType = arrayClass.getComponentType();
            this.componentArray = (Object[]) Array.newInstance(componentType, 0);
        }
        log.info("Loading {}, type: {}", this.getClass().getSimpleName(), type().getSimpleName());
    }
    @Override
    protected String convert(T obj) {
        // 轉換為Json字符串
        return JsonKit.toJson(obj);
    }
    @Override
    protected T parse(String json) {
        if (this.componentType != null) {
            // Json解析為對象數組
            List<?> list = JsonKit.toList(json, this.componentType);
            if (list == null) return null;
            return (T) list.toArray(this.componentArray);
        }
        // Json解析為對象
        return JsonKit.toObject(json, type());
    }
}

這個JsonString類型解析器,既可以轉換對象,也可以轉換對象數組(注意是Array不是List),不需要再分開記了。

不要心急,還沒完成,我們還需要把所有實現它的類型處理器注冊到類型處理器注冊器內:

/**
 * Mybatis 配置
 *
 * @author Jensen
 * @公眾號 架構師修行錄
 **/
@Configuration(proxyBeanMethods = false)
@ConditionalOnBean(DataSource.class)
@AllArgsConstructor
@AutoConfigureAfter({DataSourceAutoConfiguration.class, MybatisConfiguration.class})
public class MybatisPlusConfig implements InitializingBean {
    final MybatisPlusProperties mybatisPlusProperties;
    // 把所有實現了BaseTypeHandler的子類都注入進來
    final List<BaseTypeHandler> jsonStringTypeHandlers;
    @Override
    public void afterPropertiesSet() {
        MybatisConfiguration configuration = mybatisPlusProperties.getConfiguration();
        if (configuration == null) {
            configuration = new MybatisConfiguration();
            mybatisPlusProperties.setConfiguration(configuration);
        }
        // 核心的注冊邏輯
        TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
        // JavaObject、JavaArray
        if (jsonStringTypeHandlers != null && !jsonStringTypeHandlers.isEmpty()) {
            for (BaseTypeHandler baseTypeHandler : jsonStringTypeHandlers) {
                typeHandlerRegistry.register(baseTypeHandler.type(), baseTypeHandler);
            }
        }
    }
}

這里用到了Spring的依賴注入,一次注入多個Bean(記筆記,又是一個解耦神器),后續實現的自定義類型處理器只需要受Spring管理就行了。

至此,大功告成!

三、看看怎么用吧

比如訂單表存了用戶快照和商品列表快照:
@Data
@TableName("order_info")
public class OrderInfo {
    // 用戶快照
    private UserInfoVO userInfo;
    // 商品列表快照
    private GoodsSpuVO[] goodsSpus;
}

沒錯,就是這么定義,實體類啥都不用加了。

但我們還是要另外針對性加兩個類型處理器,只是這個類型處理器是不需要被實體類依賴的,隨便你放哪兒都行,我把它們安放在entity.typehandlers目錄下:

@Component
public class UserInfoTypeHandler extends JsonStringTypeHandler<UserInfoVO> {
  // 類名隨便起,啥都不用寫,加個@Component受Spring管理就行了
}


@Component
public class GoodsSpusTypeHandler extends JsonStringTypeHandler<GoodsSpuVO[]> {
  // 類名隨便起,啥都不用寫,加個@Component受Spring管理就行了
}

好了,咱就是說,以后再也不需要煩怎么存取的問題了,有道是,有頭發誰要吃咖喱?

四、OneMoreThing

以上是筆者研究了一段時間磨出來的方案,遺憾的是JSON對象數組的解析只能通過數組的方式,研究了很久都沒能映射到List類型,大概是Mybatis的鍋,大家如果有思路可以在評論區告訴我,我一定往厚里謝。除了{"k","v"}、[{"k","v"}]這兩種常用存儲形式,我們還會經常用到別的自定義存儲格式,如["xxx","xxx"]、[12.3, 45.6]、aaa,bbb等,并不能用上面的類型處理器,我把其他的類型處理器集成到了D3Boot框架的BASE-DATA組件內,大家需要的話可以移步Gitee抄作業。

圖片

Gitee源碼地址:https://gitee.com/jensvn/d3boot。

今天又是干貨滿滿的一天,果然在程序員的眼里,對象是最好處理的。

責任編輯:姜華 來源: 架構師修行錄
相關推薦

2009-09-10 10:09:46

LINQ to SQL

2020-04-22 10:35:57

實體類屬性映射

2011-06-01 15:45:28

實體類序列化

2023-01-04 08:53:52

JPA實體類注解

2025-07-08 08:20:39

2023-01-12 09:13:49

Mybatis數據庫

2022-04-18 09:54:37

JDK8日期前端

2025-04-07 02:33:00

項目開發Spring

2017-07-20 17:05:04

JavaScriptswagger-decSwagger

2011-04-26 15:26:38

PostgreSQL

2011-04-26 14:21:50

MySQL

2013-12-13 16:00:39

社交類APP設計思路產品經理

2009-06-15 15:10:02

Java數據轉換JSON

2022-12-27 08:41:51

FastjsonJson字段

2024-03-11 10:07:58

2020-11-20 08:36:59

Jpa數據代碼

2021-06-28 07:09:24

MybatisresultMapJava

2024-10-11 16:34:22

2009-09-28 09:56:53

Hibernate屬性

2009-08-13 09:33:07

JavaBean到XM
點贊
收藏

51CTO技術棧公眾號

91免费在线播放| 91超碰国产精品| 欧美亚洲尤物久久| 中文字幕一区综合| 亚洲经典一区二区三区| 久久九九电影| 欧美韩国理论所午夜片917电影| 加勒比精品视频| 欧美日韩破处视频| 亚洲丶国产丶欧美一区二区三区| 日本成人黄色免费看| 国产极品久久久| 久久综合图片| 欧美激情视频网址| 国产在线免费av| 精品日产乱码久久久久久仙踪林| 欧美色图在线观看| 日韩av在线第一页| 国产婷婷视频在线| 国产亚洲欧洲一区高清在线观看| 国产不卡一区二区在线观看| 黄色污污视频软件| 亚洲黄色在线| 久久国产天堂福利天堂| 69视频在线观看免费| 高清精品xnxxcom| 欧美电影影音先锋| 久草在在线视频| 91视频欧美| 亚洲人成电影网站色mp4| 欧美自拍资源在线| 午夜影院在线视频| 高清不卡在线观看av| 91精品久久久久久久久久另类| 99久久精品国产亚洲| 欧美精品二区| 欧美精品在线免费观看| 极品久久久久久久| 欧美少妇性xxxx| 亚洲欧美一区二区三区在线| 亚洲综合自拍网| 国产精品天天看天天狠| 日韩精品专区在线影院观看| 中文字幕丰满乱码| 日韩城人网站| 欧美伦理视频网站| 91小视频在线播放| 国产麻豆精品| 欧美一区二区三区思思人| 天天干天天操天天做| 激情久久99| 欧美午夜精品电影| 天堂在线资源视频| 69堂精品视频在线播放| 欧美亚州韩日在线看免费版国语版| 日日碰狠狠添天天爽超碰97| 在线能看的av网址| 欧美日韩精品在线播放| 超碰97人人射妻| 欧美123区| 欧美日韩卡一卡二| 在线观看免费av网址| 色噜噜成人av在线| 欧美一区二区三区视频| 91日韩精品视频| 狂野欧美xxxx韩国少妇| 欧美日韩国产美| 亚洲一区二区福利视频| 欧美黄视频在线观看| 精品国产免费人成在线观看| 中文字幕免费在线播放| 日本一区福利在线| 亚洲人成人99网站| 超碰人人人人人人人| 亚洲国产一区二区三区在线播放| 欧美黑人xxx| 欧美三级午夜理伦| 免费欧美日韩国产三级电影| 91夜夜未满十八勿入爽爽影院 | 高清美女视频一区| 国产精品国产自产拍高清av王其| 懂色av一区二区三区四区五区| 在线免费观看的av| 黄色成人av网| www.涩涩涩| 欧洲大片精品免费永久看nba| 精品国产一区二区三区av性色| 国产精品久久AV无码| 国产一区99| 欧美日本啪啪无遮挡网站| 中国一级免费毛片| 久久精品72免费观看| 国产精品播放| 国产网站在线播放| 亚洲精品伦理在线| 熟女人妇 成熟妇女系列视频| av成人在线网站| 亚洲黄色片网站| 欧美肥妇bbwbbw| 亚洲伊人观看| 99久久伊人精品影院| 欧美色18zzzzxxxxx| 亚洲欧美日韩国产另类专区| 免费看又黄又无码的网站| 国产精品亲子伦av一区二区三区| 精品成人一区二区三区四区| 在线观看免费黄色网址| 国产日韩综合| 亚洲一区二区三区香蕉| 能在线看的av| 亚洲成年人影院| 色婷婷综合网站| 欧美人与动xxxxz0oz| 免费91在线视频| 伊人久久亚洲综合| 337p粉嫩大胆噜噜噜噜噜91av| 一区二区成人国产精品| 依依综合在线| 欧美精品一区二区三| 我家有个日本女人| 久久99久久精品| 欧美日韩精品久久| 老牛影视精品| 欧美变态tickling挠脚心| 永久免费看片视频教学| 日韩精品电影在线| 鲁丝一区鲁丝二区鲁丝三区| ririsao久久精品一区| 538在线一区二区精品国产| 青娱乐国产视频| 久久久久久久高潮| 精品午夜一区二区| 国产亚洲成av人片在线观看| 日韩欧美区一区二| 日日骚一区二区三区| 国产一区二区三区免费播放| 伊人久久婷婷色综合98网| 欧美日韩视频免费观看| 亚洲欧美激情一区| 九九热精品视频在线| heyzo一本久久综合| 草b视频在线观看| 一区二区三区四区高清视频| 欧美国产激情18| www.中文字幕| 亚洲一区二区成人在线观看| 亚洲成人激情小说| 亚洲一级一区| 狠狠色噜噜狠狠狠狠色吗综合 | 91精品国产色综合| 少妇人妻一区二区| 欧美午夜影院在线视频| 精品久久久久久中文字幕人妻最新| 国产日韩一区二区三区在线播放| 韩国成人动漫在线观看| 蜜桃视频在线观看免费视频| 亚洲国产高清福利视频| 国产精品21p| 国产香蕉久久精品综合网| 中文字幕有码av| 久久精品青草| 成人18视频| 日本а中文在线天堂| 亚洲欧洲av一区二区| 波多野结衣av无码| 亚洲视频在线观看三级| 台湾佬美性中文| 亚洲一区成人| 婷婷四月色综合| 麻豆精品久久| 97久久精品人人澡人人爽缅北| 色吊丝在线永久观看最新版本| 日本韩国一区二区三区| 一本一本久久a久久| 国产福利精品导航| 黄色一级片播放| 第四色成人网| 99re国产在线播放| 中文在线免费二区三区| www.欧美精品| 视频一区 中文字幕| 在线精品视频小说1| 亚洲一级生活片| 不卡一区二区在线| 欧美精品性生活| 欧美激情1区| 牛人盗摄一区二区三区视频| 日韩综合久久| 性欧美办公室18xxxxhd| 欧美成人视屏| 日韩成人av在线播放| 91好色先生tv| 黑人狂躁日本妞一区二区三区| 精品在线观看一区| 99久久99久久精品免费观看| 性生生活大片免费看视频| 亚洲毛片播放| 天堂av免费看| 精品久久影视| 国产精品久久久久久久小唯西川 | 中文欧美日韩| 色乱码一区二区三区熟女| 欧美变态挠脚心| 成人欧美在线视频| 韩漫成人漫画| 久久久久久久久电影| 在线视频婷婷| 国产视频欧美视频| 性中国xxx极品hd| 欧美日韩中文国产| 久久国产精品免费看| 亚洲老妇xxxxxx| 亚洲女人毛茸茸高潮| 91首页免费视频| 亚洲乱妇老熟女爽到高潮的片| 美女视频一区二区| 免费高清在线观看免费| 欧美色图首页| 久久久成人精品一区二区三区| 激情婷婷综合| 免费在线成人av| 欧美三级电影在线| 国产精品免费一区二区三区四区 | 97蜜桃久久| 久久国产精彩视频| 国产在线观看91| 最近中文字幕日韩精品 | 国产日韩欧美电影| 国产男男chinese网站| 成人福利视频在线| 亚洲美女精品视频| 国产成人精品三级| 免费网站在线观看黄| 精品一区二区三区影院在线午夜| 天天插天天操天天射| 日本va欧美va欧美va精品| 日本在线观看a| 麻豆91精品| 日韩一级在线免费观看| 亚洲在线成人| 欧美a在线视频| 亚洲一区网站| 北条麻妃在线一区| 久久亚洲二区| 亚洲免费av一区二区三区| 日韩在线观看一区二区| 8x8x最新地址| 韩国毛片一区二区三区| 手机免费看av网站| 国产一区二区视频在线播放| 激情文学亚洲色图| 国产精品一级在线| 中文字幕第六页| 成人亚洲一区二区一| 天天躁日日躁狠狠躁av麻豆男男 | 亚洲av综合一区二区| 久久久久久毛片| 粉嫩精品久久99综合一区| 中文字幕在线观看不卡视频| 青青草原在线免费观看| 亚洲国产精品精华液网站| 尤物视频在线观看国产| 色哟哟欧美精品| 亚洲图片视频小说| 日韩丝袜美女视频| 日本精品一二区| 亚洲网站视频福利| 免费大片黄在线观看视频网站| 久久影院中文字幕| sqte在线播放| 国产精品69av| 麻豆一二三区精品蜜桃| 国产精品视频免费观看| 综合亚洲自拍| 中文字幕av久久| 国产日本精品| 伊人国产在线视频| 国产91精品精华液一区二区三区| 精品国产av色一区二区深夜久久| 国产日韩在线不卡| 美女福利视频在线观看| 欧美日韩亚洲精品内裤| 91肉色超薄丝袜脚交一区二区| 精品国产网站在线观看| 成年人在线视频免费观看| 欧美成人全部免费| 成人影院网站| 91精品天堂| 九九综合九九| 男女激情免费视频| 日日夜夜免费精品| 亚洲美女高潮久久久| 国产三级精品视频| 日本少妇xxxx动漫| 在线不卡中文字幕| 免费在线黄色网址| 欧美精品国产精品日韩精品| 国产日韩另类视频一区| 国产精品中出一区二区三区| 日韩欧美视频在线播放| www.99热这里只有精品| 激情丁香综合五月| 精品无码一区二区三区| 亚洲一区免费在线观看| 中文字幕永久免费视频| 亚洲美女精品久久| heyzo一区| 成人福利在线观看| 国产伦精品一区二区三区视频| 奇米777四色影视在线看| 裸体在线国模精品偷拍| 国产精品1000部啪视频| 亚洲国产精品久久不卡毛片 | 老司机2019福利精品视频导航| 亚洲一区美女视频在线观看免费| 欧美精品一二| 欧美韩国日本在线| 成年人国产精品| 久久久久成人网站| 欧美精品aⅴ在线视频| 国产福利免费在线观看| 日本韩国在线不卡| 狼人天天伊人久久| 人人干视频在线| 国产91精品久久久久久久网曝门| 亚洲精品久久久久久国| 欧美唯美清纯偷拍| 久久视频www| 日本人成精品视频在线| 综合亚洲自拍| 97视频在线免费播放| 久久午夜免费电影| 800av免费在线观看| 亚洲精品国产电影| heyzo高清国产精品| 国产66精品久久久久999小说| 欧美a级在线| 人妻精油按摩bd高清中文字幕| 综合色天天鬼久久鬼色| 97精品人妻一区二区三区| 色系列之999| 国产免费区一区二区三视频免费| 一区二区三区欧美在线| 精品亚洲免费视频| 小早川怜子一区二区的演员表| 欧美日韩国产不卡| 成人ww免费完整版在线观看| 亚洲自拍高清视频网站| 欧美日韩ab| 国产xxxx视频| 精品免费在线观看| 国模吧精品人体gogo| 国产精品视频公开费视频| 999视频精品| 97免费公开视频| 亚洲综合色在线| 天天摸天天干天天操| 日本国产欧美一区二区三区| 红桃成人av在线播放| 成年人三级黄色片| 亚洲精品日产精品乱码不卡| 亚洲av无码专区在线| 性欧美激情精品| 精品久久美女| 天堂av.com| 精品人伦一区二区三区蜜桃免费| 黄网在线观看| 成人黄色在线观看| 在线观看日韩av电影| 黄色正能量网站| 欧美日韩亚洲综合一区二区三区 | 91精品国产色综合久久不卡98| 免费看成人哺乳视频网站| 91极品视频在线观看| 一区二区三区四区五区视频在线观看| 欧美一级做性受免费大片免费| 日本精品性网站在线观看| 久久网站免费观看| 97人人模人人爽人人澡| 午夜精品久久久久久久久久| 国产剧情在线观看| 91成人在线看| 日日夜夜免费精品| 久久久久久久久久久久久女过产乱| 亚洲国产精品电影| 日韩电影精品| 日韩在线综合网| 亚洲乱码国产乱码精品精98午夜| 韩国av永久免费| 国产精品偷伦一区二区| 在线日韩中文| 一起操在线播放| 亚洲欧美精品一区| 精品国产不卡一区二区| 日本精品久久久久中文字幕| 亚洲精品视频在线看| av播放在线观看| 精品国产一区二区三区麻豆小说| 国产综合色视频| 波多野结衣 久久|