0


SpringBoot_mybatis-plus使用json字段

mybatis-plus使用json字段

1.前言

在springboot项目开发中,一般使用关系型数据库作为主库存储数据,有时候业务场景需要在既有的表结构上,扩展自定义业务信息. 这种场景下一般使用json类型存储。本文总结springboot项目中,借助mybatis-plus操作json实践方案

2.方案分析

2.1 为什么是json

JSON类型相对于传统的关系型结构,其具有数据本身对结构描述、动态扩展和嵌套等特性,能够更加自由地表示和存储数据

2.2 数据库的选择

json字段的存储依赖于底层选择的数据库, 有的关系型数据库已经支持json,比如MySQL5.7版本中,引入了JSON类型。如果没有特殊的json类型, 我们可以使用text类型存储json文本。因此要分两种情况分析. 这两种模式区别:

  1. 提供json类型数据库,在查询灵活程度上更高,比如可以针对json指定key的value进行查询。text之恶能作为普通文本匹配
  2. 提供json类型数据库,查询会部分依赖底层特殊查询语法. text则是通用的数据类型不存在该情况。

3. 实战

无论底层数据库使用text类型还是json类型。持久层使用mybatis-plus都要处理json与对象的映射问题。创建一个Account账号对象为例,增加一个extendJson作为存储扩展数据的json对象

@TableName(value ="account", autoResultMap =true)publicclassAccount{@TableId(type =IdType.AUTO)privateLong id;privateString name;privateString username;/**
     * 注意!! 必须开启映射注解
     *
     * @TableName(autoResultMap = true)
     * <p>
     * 以下两种类型处理器,二选一 也可以同时存在
     * <p>
     * 注意!!选择对应的 JSON 处理器也必须存在对应 JSON 解析依赖包
     *///@TableField(typeHandler = JacksonTypeHandler.class)@TableField(typeHandler =FastjsonTypeHandler.class)privateJSONObject extendJson;//setter/getter忽略

以上部分主要参考mp官网:https://baomidou.com/ >>字段类型处理器

3.1 使用text字段(h2数据库)

使用text字段测试json字段我们使用h2数据库进行测试

  • h2版本: 1.4.200(该版本不支持原生的json字段)

3.1.1 建表语句

使用liquibase管理建表语句

<?xml version="1.1" encoding="UTF-8" standalone="no"?><databaseChangeLogxmlns="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"><changeSetauthor="demo"id="account.createTable"><createTabletableName="account"remarks="账号表"><!--设置id自增 起始位置从10000 每次加1--><columnname="id"remarks="账户ID"type="bigint"autoIncrement="true"incrementBy="1"startWith="10000"><constraintsprimaryKey="true"nullable="false"/></column><!--用户名增加唯一索引--><columnname="username"remarks="用户名"type="VARCHAR(32)"><constraintsnullable="false"unique="true"uniqueConstraintName="uniq_username"/></column><columnname="password"remarks="密码"type="VARCHAR(32)"/><columnname="name"remarks="姓名"type="VARCHAR(20)"/><columnname="sex"remarks="性别"type="CHAR(1)"/><columnname="phone"remarks="手机"type="VARCHAR(100)"/><columnname="email"remarks="邮件"type="VARCHAR(100)"/><columnname="create_time"remarks="创建时间"type="datetime(0)"/><columnname="update_time"remarks="修改时间"type="datetime(0)"/><!--            <column name="extend_json" remarks="拓展字段使用" type="json"/>--><columnname="extend_json"remarks="拓展字段使用"type="text"/></createTable></changeSet><!--loadData:加载 csv 文件到已存在的表中--><changeSetauthor="easy-log-demo"id="account.loadData"><loadDatatableName="account"file="db/liquibase/csv/account.csv"></loadData></changeSet></databaseChangeLog>

3.1.2 数据操作与查询

text存储json的数据操作与查询与普通text操作无差别

@ServicepublicclassAccountServiceImplimplementsAccountService{@AutowiredprivateAccountMapper accountMapper;publicvoidcreateAccount(Account account){
        account.setUsername(UUID.randomUUID().toString().replace("-",""));this.accountMapper.insert(account);}publicAccountupdateAccount(Account account){this.accountMapper.updateById(account);returnthis.accountMapper.selectById(account.getId());}@OverridepublicList<Account>listAll(){returnthis.accountMapper.selectList(Wrappers.emptyWrapper());}}

效果:
在这里插入图片描述

3.2 使用json字段(mysql数据库)

3.2.1 建表语句

使用liquibase管理建表语句

  • MySQL使用版本: 大于等于5.7
<?xml version="1.1" encoding="UTF-8" standalone="no"?><databaseChangeLogxmlns="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"><changeSetauthor="demo"id="account.createTable"><createTabletableName="account"remarks="账号表"><!--设置id自增 起始位置从10000 每次加1--><columnname="id"remarks="账户ID"type="bigint"autoIncrement="true"incrementBy="1"startWith="10000"><constraintsprimaryKey="true"nullable="false"/></column><!--用户名增加唯一索引--><columnname="username"remarks="用户名"type="VARCHAR(32)"><constraintsnullable="false"unique="true"uniqueConstraintName="uniq_username"/></column><columnname="password"remarks="密码"type="VARCHAR(32)"/><columnname="name"remarks="姓名"type="VARCHAR(20)"/><columnname="sex"remarks="性别"type="CHAR(1)"/><columnname="phone"remarks="手机"type="VARCHAR(100)"/><columnname="email"remarks="邮件"type="VARCHAR(100)"/><columnname="create_time"remarks="创建时间"type="datetime(0)"/><columnname="update_time"remarks="修改时间"type="datetime(0)"/><columnname="extend_json"remarks="拓展字段使用"type="json"/></createTable></changeSet><!--loadData:加载 csv 文件到已存在的表中--><changeSetauthor="easy-log-demo"id="account.loadData"><loadDatatableName="account"file="db/liquibase/csv/account.csv"></loadData></changeSet></databaseChangeLog>

3.2.2 数据操作与查询

mysql支持json类型因此借助特定的语法可以实现json精确查询及模糊查询

@ServicepublicclassAccountServiceImplimplementsAccountService{@AutowiredprivateAccountMapper accountMapper;publicvoidcreateAccount(Account account){
        account.setUsername(UUID.randomUUID().toString().replace("-",""));this.accountMapper.insert(account);}publicAccountupdateAccount(Account account){this.accountMapper.updateById(account);returnthis.accountMapper.selectById(account.getId());}/**
     * json 数据模糊查询
     * @param key extend_json 中的json的key
     * @param value extend_json 中的json的key对应value
     * @return
     */publicList<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);returnthis.accountMapper.selectList(queryWrapper);}/**
     * json 数据精确查询
     * @param key extend_json 中的json的key
     * @param value extend_json 中的json的key对应value
     * @return
     */publicList<Account>listByJsonEquals(String key,String value){LambdaQueryWrapper<Account> queryWrapper =Wrappers.<Account>lambdaQuery();//json字段精确查询
        queryWrapper.apply("JSON_EXTRACT(extend_json, '$."+ key +"') = {0}", value);returnthis.accountMapper.selectList(queryWrapper);}@OverridepublicList<Account>listAll(){returnthis.accountMapper.selectList(Wrappers.emptyWrapper());}}
  • 效果:测试json内部字段模糊查询在这里插入图片描述

4. 附录

4.1 MySQL JSON索引用法

TODO MySQLJSON索引用法介绍

4.2 mybatis-plus json查询用法

publicclassYourService{@AutowiredprivateYourMapper yourMapper;publicYourEntitygetByJsonKey(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} 将会被 MyBatis-Plus 自动处理为预编译参数,保证了 SQL 的安全性。

请确保你的 MyBatis-Plus 版本支持 .apply() 方法,该方法可以用于执行自定义的 SQL 查询条件。

5. 参考文档

  1. mybatis-plus字段类型处理器
  2. mybatis-plus

本文转载自: https://blog.csdn.net/Myron_007/article/details/134153954
版权归原作者 张三疯不疯 所有, 如有侵权,请联系我们删除。

“SpringBoot_mybatis-plus使用json字段”的评论:

还没有评论