SpringBoot?mybatis-plus使用json字段實(shí)戰(zhàn)指南
1.前言
在springboot項(xiàng)目開發(fā)中,一般使用關(guān)系型數(shù)據(jù)庫(kù)作為主庫(kù)存儲(chǔ)數(shù)據(jù),有時(shí)候業(yè)務(wù)場(chǎng)景需要在既有的表結(jié)構(gòu)上,擴(kuò)展自定義業(yè)務(wù)信息. 這種場(chǎng)景下一般使用json類型存儲(chǔ)。本文總結(jié)springboot項(xiàng)目中,借助mybatis-plus操作json實(shí)踐方案
2.方案分析
2.1 為什么是json
JSON類型相對(duì)于傳統(tǒng)的關(guān)系型結(jié)構(gòu),其具有數(shù)據(jù)本身對(duì)結(jié)構(gòu)描述、動(dòng)態(tài)擴(kuò)展和嵌套等特性,能夠更加自由地表示和存儲(chǔ)數(shù)據(jù)
2.2 數(shù)據(jù)庫(kù)的選擇
json字段的存儲(chǔ)依賴于底層選擇的數(shù)據(jù)庫(kù), 有的關(guān)系型數(shù)據(jù)庫(kù)已經(jīng)支持json,比如MySQL5.7版本中,引入了JSON類型。如果沒(méi)有特殊的json類型, 我們可以使用text類型存儲(chǔ)json文本。因此要分兩種情況分析. 這兩種模式區(qū)別:
- 提供json類型數(shù)據(jù)庫(kù),在查詢靈活程度上更高,比如可以針對(duì)json指定key的value進(jìn)行查詢。text之惡能作為普通文本匹配
- 提供json類型數(shù)據(jù)庫(kù),查詢會(huì)部分依賴底層特殊查詢語(yǔ)法. text則是通用的數(shù)據(jù)類型不存在該情況。
3. 實(shí)戰(zhàn)
無(wú)論底層數(shù)據(jù)庫(kù)使用text類型還是json類型。持久層使用mybatis-plus都要處理json與對(duì)象的映射問(wèn)題。創(chuàng)建一個(gè)Account賬號(hào)對(duì)象為例,增加一個(gè)extendJson作為存儲(chǔ)擴(kuò)展數(shù)據(jù)的json對(duì)象
@TableName(value = "account", autoResultMap = true) public class Account { @TableId(type = IdType.AUTO) private Long id; private String name; private String username; /** * 注意??! 必須開啟映射注解 * * @TableName(autoResultMap = true) * <p> * 以下兩種類型處理器,二選一 也可以同時(shí)存在 * <p> * 注意??!選擇對(duì)應(yīng)的 JSON 處理器也必須存在對(duì)應(yīng) JSON 解析依賴包 */ //@TableField(typeHandler = JacksonTypeHandler.class) @TableField(typeHandler = FastjsonTypeHandler.class) private JSONObject extendJson; //setter/getter忽略
以上部分主要參考mp官網(wǎng):https://baomidou.com/ >>字段類型處理器
3.1 使用text字段(h2數(shù)據(jù)庫(kù))
使用text字段測(cè)試json字段我們使用h2數(shù)據(jù)庫(kù)進(jìn)行測(cè)試
- h2版本: 1.4.200(該版本不支持原生的json字段)
3.1.1 建表語(yǔ)句
使用liquibase管理建表語(yǔ)句
<?xml version="1.1" encoding="UTF-8" standalone="no"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd"> <changeSet author="demo" id="account.createTable"> <createTable tableName="account" remarks="賬號(hào)表"> <!--設(shè)置id自增 起始位置從10000 每次加1--> <column name="id" remarks="賬戶ID" type="bigint" autoIncrement="true" incrementBy="1" startWith="10000"> <constraints primaryKey="true" nullable="false"/> </column> <!--用戶名增加唯一索引--> <column name="username" remarks="用戶名" type="VARCHAR(32)"> <constraints nullable="false" unique="true" uniqueConstraintName="uniq_username"/> </column> <column name="password" remarks="密碼" type="VARCHAR(32)"/> <column name="name" remarks="姓名" type="VARCHAR(20)"/> <column name="sex" remarks="性別" type="CHAR(1)"/> <column name="phone" remarks="手機(jī)" type="VARCHAR(100)"/> <column name="email" remarks="郵件" type="VARCHAR(100)"/> <column name="create_time" remarks="創(chuàng)建時(shí)間" type="datetime(0)"/> <column name="update_time" remarks="修改時(shí)間" type="datetime(0)"/> <!-- <column name="extend_json" remarks="拓展字段使用" type="json"/>--> <column name="extend_json" remarks="拓展字段使用" type="text"/> </createTable> </changeSet> <!--loadData:加載 csv 文件到已存在的表中--> <changeSet author="easy-log-demo" id="account.loadData" > <loadData tableName="account" file="db/liquibase/csv/account.csv" > </loadData> </changeSet> </databaseChangeLog>
3.1.2 數(shù)據(jù)操作與查詢
text存儲(chǔ)json的數(shù)據(jù)操作與查詢與普通text操作無(wú)差別
@Service public class AccountServiceImpl implements AccountService { @Autowired private AccountMapper accountMapper; public void createAccount(Account account) { account.setUsername(UUID.randomUUID().toString().replace("-", "")); this.accountMapper.insert(account); } public Account updateAccount(Account account) { this.accountMapper.updateById(account); return this.accountMapper.selectById(account.getId()); } @Override public List<Account> listAll() { return this.accountMapper.selectList(Wrappers.emptyWrapper()); } }
效果:
3.2 使用json字段(mysql數(shù)據(jù)庫(kù))
3.2.1 建表語(yǔ)句
使用liquibase管理建表語(yǔ)句
- MySQL使用版本: 大于等于5.7
<?xml version="1.1" encoding="UTF-8" standalone="no"?> <databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.5.xsd"> <changeSet author="demo" id="account.createTable"> <createTable tableName="account" remarks="賬號(hào)表"> <!--設(shè)置id自增 起始位置從10000 每次加1--> <column name="id" remarks="賬戶ID" type="bigint" autoIncrement="true" incrementBy="1" startWith="10000"> <constraints primaryKey="true" nullable="false"/> </column> <!--用戶名增加唯一索引--> <column name="username" remarks="用戶名" type="VARCHAR(32)"> <constraints nullable="false" unique="true" uniqueConstraintName="uniq_username"/> </column> <column name="password" remarks="密碼" type="VARCHAR(32)"/> <column name="name" remarks="姓名" type="VARCHAR(20)"/> <column name="sex" remarks="性別" type="CHAR(1)"/> <column name="phone" remarks="手機(jī)" type="VARCHAR(100)"/> <column name="email" remarks="郵件" type="VARCHAR(100)"/> <column name="create_time" remarks="創(chuàng)建時(shí)間" type="datetime(0)"/> <column name="update_time" remarks="修改時(shí)間" type="datetime(0)"/> <column name="extend_json" remarks="拓展字段使用" type="json"/> </createTable> </changeSet> <!--loadData:加載 csv 文件到已存在的表中--> <changeSet author="easy-log-demo" id="account.loadData" > <loadData tableName="account" file="db/liquibase/csv/account.csv" > </loadData> </changeSet> </databaseChangeLog>
3.2.2 數(shù)據(jù)操作與查詢
mysql支持json類型因此借助特定的語(yǔ)法可以實(shí)現(xiàn)json精確查詢及模糊查詢
@Service public class AccountServiceImpl implements AccountService { @Autowired private AccountMapper accountMapper; public void createAccount(Account account) { account.setUsername(UUID.randomUUID().toString().replace("-", "")); this.accountMapper.insert(account); } public Account updateAccount(Account account) { this.accountMapper.updateById(account); return this.accountMapper.selectById(account.getId()); } /** * json 數(shù)據(jù)模糊查詢 * @param key extend_json 中的json的key * @param value extend_json 中的json的key對(duì)應(yīng)value * @return */ public List<Account> listByJsonLike(String key, String value) { // QueryChainWrapper<Account> queryWrapper = new QueryChainWrapper<>(this.accountMapper); LambdaQueryWrapper<Account> queryWrapper = Wrappers.<Account>lambdaQuery(); //json字段模式查詢 queryWrapper.apply("JSON_EXTRACT(extend_json, '$." + key + "') LIKE {0}", "%" + value + "%") .ge(Account::getId, 10000); return this.accountMapper.selectList(queryWrapper); } /** * json 數(shù)據(jù)精確查詢 * @param key extend_json 中的json的key * @param value extend_json 中的json的key對(duì)應(yīng)value * @return */ public List<Account> listByJsonEquals(String key, String value) { LambdaQueryWrapper<Account> queryWrapper = Wrappers.<Account>lambdaQuery(); //json字段精確查詢 queryWrapper.apply("JSON_EXTRACT(extend_json, '$." + key + "') = {0}", value); return this.accountMapper.selectList(queryWrapper); } @Override public List<Account> listAll() { return this.accountMapper.selectList(Wrappers.emptyWrapper()); } }
- 效果:測(cè)試json內(nèi)部字段模糊查詢
4. 附錄
4.1 MySQL JSON索引用法
TODO MySQLJSON索引用法介紹
4.2 mybatis-plus json查詢用法
public class YourService { @Autowired private YourMapper yourMapper; public YourEntity getByJsonKey(String key, String value) { QueryWrapper<YourEntity> queryWrapper = Wrappers.<YourEntity>lambdaQuery() .apply("json_data->'$.key' = {0}", value); return yourMapper.selectOne(queryWrapper); } }
在上述示例中,.apply(“json_data->‘$.key’ = {0}”, value) 中的 {0} 將會(huì)被 MyBatis-Plus 自動(dòng)處理為預(yù)編譯參數(shù),保證了 SQL 的安全性。
請(qǐng)確保你的 MyBatis-Plus 版本支持 .apply() 方法,該方法可以用于執(zhí)行自定義的 SQL 查詢條件。
5. 參考文檔
總結(jié)
到此這篇關(guān)于SpringBoot mybatis-plus使用json字段的文章就介紹到這了,更多相關(guān)mybatis-plus使用json字段內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- SpringBoot同時(shí)集成Mybatis和Mybatis-plus框架
- SpringBoot+MyBatis-Plus實(shí)現(xiàn)分頁(yè)示例
- Springboot整合mybatis-plus使用pageHelper進(jìn)行分頁(yè)(使用步驟)
- SpringBoot+MyBatis-Plus實(shí)現(xiàn)分頁(yè)的項(xiàng)目實(shí)踐
- springboot集成mybatis-plus全過(guò)程
- Springboot集成Mybatis-plus、ClickHouse實(shí)現(xiàn)增加數(shù)據(jù)、查詢數(shù)據(jù)功能
- springboot項(xiàng)目中mybatis-plus@Mapper注入失敗問(wèn)題
- springboot+mybatis-plus實(shí)現(xiàn)自動(dòng)建表的示例
- SpringBoot中使用MyBatis-Plus實(shí)現(xiàn)分頁(yè)接口的詳細(xì)教程
- springboot3.2整合mybatis-plus詳細(xì)代碼示例
- 全網(wǎng)最新springboot整合mybatis-plus的過(guò)程
相關(guān)文章
Spring+Quartz實(shí)現(xiàn)動(dòng)態(tài)任務(wù)調(diào)度詳解
這篇文章主要介紹了Spring+Quartz實(shí)現(xiàn)動(dòng)態(tài)任務(wù)調(diào)度詳解,最近經(jīng)常基于spring?boot寫定時(shí)任務(wù),并且是使用注解的方式進(jìn)行實(shí)現(xiàn),分成的方便將自己的類注入spring容器,需要的朋友可以參考下2024-01-01Java concurrency之AtomicLongFieldUpdater原子類_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理
AtomicLongFieldUpdater可以對(duì)指定"類的 'volatile long'類型的成員"進(jìn)行原子更新。它是基于反射原理實(shí)現(xiàn)的。下面通過(guò)本文給大家分享Java concurrency之AtomicLongFieldUpdater原子類的相關(guān)知識(shí),感興趣的朋友一起看看吧2017-06-06Java程序執(zhí)行過(guò)程及內(nèi)存機(jī)制詳解
本講將介紹Java代碼是如何一步步運(yùn)行起來(lái)的,還會(huì)介紹Java程序所占用的內(nèi)存是被如何管理的:堆、棧和方法區(qū)都各自負(fù)責(zé)存儲(chǔ)哪些內(nèi)容,感興趣的朋友跟隨小編一起看看吧2020-12-12Spring Data Jpa實(shí)現(xiàn)自定義repository轉(zhuǎn)DTO
這篇文章主要介紹了Spring Data Jpa實(shí)現(xiàn)自定義repository轉(zhuǎn)DTO,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08spring?boot教程之建立第一個(gè)HelloWorld
這篇文章主要介紹了spring?boot教程之建立第一個(gè)HelloWorld的相關(guān)資料,需要的朋友可以參考下2022-08-08java讀取properties文件的方法實(shí)例分析
這篇文章主要介紹了java讀取properties文件的方法,實(shí)例分析了java讀取在項(xiàng)目中與不在項(xiàng)目中properties文件的相關(guān)技巧,需要的朋友可以參考下2015-06-06詳解JDK自帶javap命令反編譯class文件和Jad反編譯class文件(推薦使用jad)
這篇文章主要介紹了JDK自帶javap命令反編譯class文件和Jad反編譯class文件(推薦使用jad),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-09-09IDEA的spring項(xiàng)目使用@Qualifier飄紅問(wèn)題及解決
這篇文章主要介紹了IDEA的spring項(xiàng)目使用@Qualifier飄紅問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11