SpringMVC結(jié)合模板模式實(shí)現(xiàn)MyBatisPlus傳遞嵌套JSON數(shù)據(jù)
引出
我們經(jīng)常會(huì)遇到需要傳遞對(duì)象的場(chǎng)景。有時(shí)候,我們需要將一個(gè)對(duì)象的數(shù)據(jù)傳遞給另一個(gè)對(duì)象進(jìn)行處理,但是又不希望直接暴露對(duì)象的內(nèi)部結(jié)構(gòu)和實(shí)現(xiàn)細(xì)節(jié)。這時(shí),我們可以使用模板模式來(lái)實(shí)現(xiàn)優(yōu)雅的對(duì)象傳遞。
為了實(shí)現(xiàn)這個(gè)場(chǎng)景,我們可以使用模板模式。
模板模式是一種行為設(shè)計(jì)模式,它定義了一個(gè)抽象類(lèi)或接口作為模板,其中包含了一個(gè)或多個(gè)抽象方法,用于定義算法的骨架。具體的子類(lèi)可以根據(jù)需要實(shí)現(xiàn)這些抽象方法,從而完成算法的定制化。
說(shuō)說(shuō)我這邊的起因
大概是這樣的 要做一個(gè)問(wèn)卷系統(tǒng) 這個(gè)問(wèn)卷里面包含各種各樣的標(biāo)簽和因子 就使得 屬性里面又包含屬性 對(duì)象里面又嵌套數(shù)組 數(shù)組里面又有對(duì)象 遇到這種情況相信大家都會(huì)很頭疼吧 那這種時(shí)候很多人就要開(kāi)始寫(xiě)Mapper了 這里我提出一個(gè)大大節(jié)約時(shí)間的方法 類(lèi)型構(gòu)造器
設(shè)計(jì)模式的引入
我們知道 每一個(gè)屬性需要引入一個(gè)新的類(lèi)型構(gòu)造器 那就要根據(jù)他的具體情況重寫(xiě)一個(gè) 那豈不是代碼量指數(shù)級(jí)上漲?


還有很多...各種嵌套 于是我想 有沒(méi)有一種辦法能規(guī)定好所有的嵌套方法的邏輯 然后他們只需要說(shuō)明自己是什么類(lèi)型 就能套進(jìn)去?
有,就是今天要說(shuō)的模板方法
先定義一個(gè)通用的模板
public class JsonArrayHandler<T> extends BaseTypeHandler<List<T>> {
private Class<T> type;
public JsonArrayHandler() {
// 添加無(wú)參構(gòu)造函數(shù)
}
public JsonArrayHandler(Class<T> type) {
if (type == null) {
throw new IllegalArgumentException("Type argument cannot be null");
}
this.type = type;
}
@Override
public void setNonNullParameter(PreparedStatement ps, int i, List<T> parameter, JdbcType jdbcType) throws SQLException {
ps.setString(i, JSONArray.toJSONString(parameter));
}
@Override
public List<T> getNullableResult(ResultSet rs, String columnName) throws SQLException {
String json = rs.getString(columnName);
return parseJsonArray(json);
}
@Override
public List<T> getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
String json = rs.getString(columnIndex);
return parseJsonArray(json);
}
@Override
public List<T> getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
String json = cs.getString(columnIndex);
return parseJsonArray(json);
}
private List<T> parseJsonArray(String json) {
JSONArray jsonArray = JSONArray.parseArray(json);
return jsonArray.toJavaList(type);
}
}讓我逐點(diǎn)解釋其妙處:
泛型支持:
public class JsonArrayHandler<T> extends BaseTypeHandler<List<T>>中的<T>表示這是一個(gè)泛型類(lèi),可以適用于不同類(lèi)型的 JSON 數(shù)組字段。通過(guò)使用泛型,可以在運(yùn)行時(shí)指定具體的類(lèi)型,使得處理不同類(lèi)型的 JSON 數(shù)組變得更加靈活和通用。構(gòu)造函數(shù)重載:
public JsonArrayHandler()是一個(gè)無(wú)參構(gòu)造函數(shù),而public JsonArrayHandler(Class<T> type)是一個(gè)有參構(gòu)造函數(shù)。通過(guò)提供兩個(gè)構(gòu)造函數(shù),可以靈活地創(chuàng)建JsonArrayHandler的實(shí)例。無(wú)參構(gòu)造函數(shù)用于在不知道具體類(lèi)型時(shí)創(chuàng)建實(shí)例,而有參構(gòu)造函數(shù)用于在已知類(lèi)型時(shí)創(chuàng)建實(shí)例。參數(shù)設(shè)置:
setNonNullParameter方法用于將 Java 對(duì)象轉(zhuǎn)換為存儲(chǔ)在數(shù)據(jù)庫(kù)中的 JSON 字符串。在這里,使用了阿里巴巴的 FastJSON 庫(kù)將 List<T> 對(duì)象轉(zhuǎn)換為 JSON 字符串,并將其設(shè)置到 PreparedStatement 對(duì)象中。結(jié)果獲?。?code>getNullableResult 方法用于從數(shù)據(jù)庫(kù)中獲取 JSON 字符串,并將其轉(zhuǎn)換回 List<T> 對(duì)象。在這里,使用了 FastJSON 庫(kù)將 JSON 字符串解析為 JSONArray,然后將其轉(zhuǎn)換為 List<T> 對(duì)象。
有了這一個(gè)模板 那么剩下來(lái)的就是 直接使用他!
這里淺淺給出我業(yè)務(wù)中的6個(gè)例子
- 商品分類(lèi):數(shù)據(jù)庫(kù)中的
category_ids字段存儲(chǔ)了商品所屬的分類(lèi)列表。使用自定義 TypeHandler,可以將 Java 對(duì)象的 List<Category> 直接映射到數(shù)據(jù)庫(kù)的 JSON 字符串,并在讀取時(shí)將 JSON 字符串轉(zhuǎn)換回 List<Category>。
public class CategoryHandler extends JsonArrayHandler<Category> {
public CategoryHandler() {
super(Category.class);
}
}- 用戶(hù)角色:數(shù)據(jù)庫(kù)中的
role_ids字段存儲(chǔ)了用戶(hù)所擁有的角色列表。使用自定義 TypeHandler,可以將 Java 對(duì)象的 List<Role> 直接映射到數(shù)據(jù)庫(kù)的 JSON 字符串,并在讀取時(shí)將 JSON 字符串轉(zhuǎn)換回 List<Role>。
public class RoleHandler extends JsonArrayHandler<Role> {
public RoleHandler() {
super(Role.class);
}
}- 訂單商品列表:數(shù)據(jù)庫(kù)中的
order_items字段存儲(chǔ)了訂單中的商品列表。使用自定義 TypeHandler,可以將 Java 對(duì)象的 List<OrderItem> 直接映射到數(shù)據(jù)庫(kù)的 JSON 字符串,并在讀取時(shí)將 JSON 字符串轉(zhuǎn)換回 List<OrderItem>。
public class OrderItemHandler extends JsonArrayHandler<OrderItem> {
public OrderItemHandler() {
super(OrderItem.class);
}
}- 圖片列表:數(shù)據(jù)庫(kù)中的
image_urls字段存儲(chǔ)了一組圖片的 URL 列表。使用自定義 TypeHandler,可以將 Java 對(duì)象的 List<String> 直接映射到數(shù)據(jù)庫(kù)的 JSON 字符串,并在讀取時(shí)將 JSON 字符串轉(zhuǎn)換回 List<String>。
public class ImageHandler extends JsonArrayHandler<String> {
public ImageHandler() {
super(String.class);
}
}- 標(biāo)簽列表:數(shù)據(jù)庫(kù)中的
tags字段存儲(chǔ)了一組標(biāo)簽。使用自定義 TypeHandler,可以將 Java 對(duì)象的 List<Tag> 直接映射到數(shù)據(jù)庫(kù)的 JSON 字符串,并在讀取時(shí)將 JSON 字符串轉(zhuǎn)換回 List<Tag>。
public class TagHandler extends JsonArrayHandler<Tag> {
public TagHandler() {
super(Tag.class);
}
}Answer類(lèi)是一個(gè)答案類(lèi),包含了答案內(nèi)容answer和分?jǐn)?shù)score兩個(gè)字段。Questionnaire類(lèi)是一個(gè)問(wèn)卷調(diào)查類(lèi),其中包含了一些字段,包括主鍵id、問(wèn)題編號(hào)qid、答案answer、問(wèn)題名稱(chēng)qname、問(wèn)題描述question、標(biāo)簽tab、ans。在ans字段上,使用了@TableField注解,并設(shè)置了typeHandler = AnswerHandler.class,指定了使用AnswerHandler這個(gè)自定義的 TypeHandler 來(lái)處理該字段。
public AnswerHandler(Class<Answer> type) {
super(Answer.class);
}@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
@TableName("tb_questionnaire")
public class Questionnaire {
/**
* 主鍵
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
private int qid;
private String answer;
private String qname;
private String question;
private String tab;
@TableField(exist = false,typeHandler = AnswerHandler.class)
private List<Answer> ans;
public void setAnswer() {
this.answer = JSONUtil.toJsonStr(ans);
}
public void setAnswerList() {
this.ans = JSONUtil.toList(answer,Answer.class);
answer=null;
}
}查詢(xún)
這樣就不用寫(xiě)復(fù)雜的Mapper 和sql語(yǔ)句 也能輕松查詢(xún)嵌套的復(fù)雜的JSON數(shù)據(jù)啦

實(shí)現(xiàn)效果

這樣就形成了復(fù)雜的嵌套的數(shù)據(jù)的自動(dòng)構(gòu)造
以上就是SpringMVC結(jié)合模板模式實(shí)現(xiàn)MyBatisPlus傳遞嵌套JSON數(shù)據(jù)的詳細(xì)內(nèi)容,更多關(guān)于SpringMVC傳遞嵌套JSON數(shù)據(jù)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java詳細(xì)講解堆排序與時(shí)間復(fù)雜度的概念
本文主要介紹了java實(shí)現(xiàn)堆排序以及時(shí)間復(fù)雜度,堆排序這種排序算法是我們經(jīng)常用到的,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-04-04
eclipse/IDEA配置javafx項(xiàng)目步驟(圖文教程)
這篇文章主要介紹了eclipse/IDEA配置javafx項(xiàng)目步驟(圖文教程),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03
java web在高并發(fā)和分布式下實(shí)現(xiàn)訂單號(hào)生成唯一的解決方案
這篇文章主要介紹了java web在高并發(fā)和分布式下實(shí)現(xiàn)訂單號(hào)生成唯一的解決方案,需要的朋友可以參考下2017-11-11
Java并發(fā)編程進(jìn)階之線(xiàn)程控制篇
在使用Java實(shí)際編程中,多線(xiàn)程可以說(shuō)是無(wú)所不在,凡是需要并發(fā)執(zhí)行的都可以用到它,一個(gè)應(yīng)用程序中不用多線(xiàn)程將會(huì)是很糟糕的事情,所以掌握線(xiàn)程以及它的控制操作是非常重要的。通過(guò)本篇文章來(lái)今天帶大家一文掌握線(xiàn)程控制操作,感謝您的觀看2022-07-07
Mybatis多數(shù)據(jù)源切換實(shí)現(xiàn)代碼
這篇文章主要介紹了Mybatis多數(shù)據(jù)源切換實(shí)現(xiàn)代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-10-10
SpringBoot接口或方法進(jìn)行失敗重試的實(shí)現(xiàn)方式
為了防止網(wǎng)絡(luò)抖動(dòng),影響我們核心接口或方法的成功率,通常我們會(huì)對(duì)核心方法進(jìn)行失敗重試,如果我們自己通過(guò)for循環(huán)實(shí)現(xiàn),會(huì)使代碼顯得比較臃腫,所以本文給大家介紹了SpringBoot接口或方法進(jìn)行失敗重試的實(shí)現(xiàn)方式,需要的朋友可以參考下2024-07-07
SpringMVC 上傳文件 MultipartFile 轉(zhuǎn)為 File的方法
這篇文章主要介紹了SpringMVC 上傳文件 MultipartFile 轉(zhuǎn)為 File的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02

