<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
mysql從5.7.8版本開始原生支援了JSON型別資料,同時可以對JSON型別欄位中的特定的值進行查詢和更新等操作,通過增加JSON型別的屬性可以大大的提高我們在mysql表中儲存的資料的拓展性,無需每次新增欄位時都進行表結構的調整,下面我們不深入講解底層的實現原理,我們主要來梳理一下我們在日常工作中使用實踐
mysql版本:8.0.28
springboot版本: 2.2.2
測試表結構:
CREATE TABLE `t_json` ( `id` int unsigned NOT NULL AUTO_INCREMENT, `name` varchar(100) DEFAULT NULL, `json_obj` json DEFAULT NULL, `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
表結構對應的實體類:
@Data public class JsonTest { private Integer id; private String name; private JsonObj jsonObj; }
JsonObj類
@Data @Builder @NoArgsConstructor @AllArgsConstructor public class JsonObj { private String data; private int age; }
自定義格式轉換類:轉換過程通過fastjson來進行,需依賴fastjson對應的pom檔案
import com.alibaba.fastjson.JSON; import lombok.extern.slf4j.Slf4j; import org.apache.ibatis.type.BaseTypeHandler; import org.apache.ibatis.type.JdbcType; import org.apache.ibatis.type.MappedTypes; import java.sql.CallableStatement; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; @MappedTypes(String.class) @Slf4j public class JsonTypeHandler<T extends Object> extends BaseTypeHandler<T> { private Class<T> clazz; public JsonTypeHandler(Class<T> clazz) { if (clazz == null) { throw new IllegalArgumentException("Type argument cannot be null"); } this.clazz = clazz; } @Override public void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException { ps.setString(i, this.toJson(parameter)); } @Override public T getNullableResult(ResultSet rs, String columnName) throws SQLException { return this.toObject(rs.getString(columnName), clazz); } @Override public T getNullableResult(ResultSet rs, int columnIndex) throws SQLException { return this.toObject(rs.getString(columnIndex), clazz); } @Override public T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { return this.toObject(cs.getString(columnIndex), clazz); } private String toJson(T object) { return JSON.toJSONString(object); } private T toObject(String content, Class<?> clazz) { if (content != null && !content.isEmpty()) { return (T) JSON.parseObject(content, clazz); } else { return null; } } }
在專案開發中,表結構中的json欄位可以用JSONObject這樣的比較靈活的方式來傳遞,但是這樣的方式有一個比較大的問題就是我們在獲得這個結構後無法很直觀的確定json欄位中儲存的資料,比較好的一種方式是我們將表結構中的json型別的欄位以自定義的類來儲存,這樣我們再存取這個類對應的物件的時候,就可以明確的知道資料庫中對應的json欄位到底儲存的是一些什麼樣的key,如果需要進行調整的話,我們只需要在該類中新增新的欄位即可,完全無需對資料庫進行任何的調整。這樣的儲存方式我們再插入和查詢該欄位的時候需要指定一個指定的資料型別轉換的類來對資料庫中的JSON格式資料和我們在專案中的自定義類進行轉換的類,具體如下圖所示:
@Mapper public interface JsonMapper { @Insert({ "insert into t_json set name= #{name}, json_obj = #{jsonObj ,jdbcType=OTHER, typeHandler=cn.example.eureka.service.one.config.JsonTypeHandler}" }) int insert(JsonTest json); }
在進行查詢時,由於也需要進行json格式資料和自定義類的轉換,所以我們需要指定對應的json欄位和轉換的工具類,通過@Result註解來進行指定
@Mapper public interface JsonMapper { @Select({"<script>", "select * from t_json where id = #{id}", "</script>"}) @Results( @Result(column = "json_obj", property = "jsonObj", typeHandler = JsonTypeHandler.class) ) JsonTest getById(Integer id); }
進行指定欄位的更新的話,有兩種方式可以採用,一種方式是先將該json格式欄位中的所有資料都取出,然後通過修改當前物件的值,然後整個json格式欄位set進去;第二種方式直接通過json格式的特定SQL語法來進行指定key的更新;下面的例子裡面我們分別根據這兩種不同的模式進行更新操作
//模式一:整體更新整個json欄位 @Update({ "update t_json set json_obj = #{jsonObj ,jdbcType=OTHER, typeHandler=cn.example.eureka.service.one.config.JsonTypeHandler} where id = #{id}" }) int update(JsonTest jsonTest); //模式二:只更新json欄位中的特定key @Update({ "update t_json set json_obj = JSON_SET(json_obj, '$.data', #{data}) where id = #{id}" }) int updateData(@Param("id") Integer id, @Param("data") String data);
說明
和上面的JSON_SET同樣可以用於修改的操作函數還有:JSON_INSERT、 JSON_REPLACE 、 JSON_REMOVE等,下面簡單說一下這幾個函數的不同
如下所示JSON_REMOVE的用法:
@Update({ "update t_json set json_obj = JSON_REMOVE(json_obj, '$.age') where id = #{id}" }) int removeAge(@Param("id") Integer id);
//模式一 @Select({ "select * from t_json where json_obj -> '$.age' = #{age}" }) @Results( @Result(column = "json_obj", property = "jsonObj", typeHandler = JsonTypeHandler.class) ) List<JsonTest> getByAge(int age); //模式二 @Select({ "select * from t_json where JSON_EXTRACT(json_obj , '$.data') = #{data}" }) @Results( @Result(column = "json_obj", property = "jsonObj", typeHandler = JsonTypeHandler.class) ) List<JsonTest> getByData(String data);
到此這篇關於mysql中json型別欄位的基本用法的文章就介紹到這了,更多相關mysql json型別欄位用法內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45