SpringBoot
作者:mmseoamin日期:2023-12-21

mybatis-plus使用json字段

  • 1.前言
  • 2.方案分析
    • 2.1 为什么是json
    • 2.2 数据库的选择
    • 3. 实战
      • 3.1 使用text字段(h2数据库)
        • 3.1.1 建表语句
        • 3.1.2 数据操作与查询
        • 3.2 使用json字段(mysql数据库)
          • 3.2.1 建表语句
          • 3.2.2 数据操作与查询
          • 4. 附录
            • 4.1 MySQL JSON索引用法
            • 4.2 mybatis-plus json查询用法
            • 5. 参考文档

              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)
              public class Account {
                  @TableId(type = IdType.AUTO)
                  private Long id;
                  private String name;
                  private String username;
                  /**
                   * 注意!! 必须开启映射注解
                   *
                   * @TableName(autoResultMap = true)
                   * 

              * 以下两种类型处理器,二选一 也可以同时存在 *

              * 注意!!选择对应的 JSON 处理器也必须存在对应 JSON 解析依赖包 */ //@TableField(typeHandler = JacksonTypeHandler.class) @TableField(typeHandler = FastjsonTypeHandler.class) private JSONObject extendJson; //setter/getter忽略

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

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

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

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

                3.1.1 建表语句

                使用liquibase管理建表语

                
                
                    
                        
                            
                            
                                
                            
                            
                            
                                
                            
                            
                            
                            
                            
                            
                            
                            
                
                            
                        
                    
                    
                    
                        
                        
                    
                
                

                3.1.2 数据操作与查询

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

                @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 listAll() {
                        return this.accountMapper.selectList(Wrappers.emptyWrapper());
                    }
                }
                

                效果:

                SpringBoot,在这里插入图片描述,第1张

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

                3.2.1 建表语句

                使用liquibase管理建表语句

                • MySQL使用版本: 大于等于5.7
                  
                  
                      
                          
                              
                              
                                  
                              
                              
                              
                                  
                              
                              
                              
                              
                              
                              
                              
                              
                              
                          
                      
                      
                      
                          
                          
                      
                  
                  

                  3.2.2 数据操作与查询

                  mysql支持json类型因此借助特定的语法可以实现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 数据模糊查询
                       * @param key extend_json 中的json的key
                       * @param value extend_json 中的json的key对应value
                       * @return
                       */
                      public List listByJsonLike(String key, String value) {
                  //        QueryChainWrapper queryWrapper = new QueryChainWrapper<>(this.accountMapper);
                          LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery();
                          //json字段模式查询
                          queryWrapper.apply("JSON_EXTRACT(extend_json, '$." + key + "') LIKE {0}", "%" + value + "%")
                                  .ge(Account::getId, 10000);
                          return this.accountMapper.selectList(queryWrapper);
                      }
                      /**
                       * json 数据精确查询
                       * @param key extend_json 中的json的key
                       * @param value extend_json 中的json的key对应value
                       * @return
                       */
                      public List listByJsonEquals(String key, String value) {
                          LambdaQueryWrapper queryWrapper = Wrappers.lambdaQuery();
                          //json字段精确查询
                          queryWrapper.apply("JSON_EXTRACT(extend_json, '$." + key + "') = {0}", value);
                          return this.accountMapper.selectList(queryWrapper);
                      }
                      @Override
                      public List listAll() {
                          return this.accountMapper.selectList(Wrappers.emptyWrapper());
                      }
                  }
                  
                  • 效果:测试json内部字段模糊查询

                    SpringBoot,在这里插入图片描述,第2张

                    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 queryWrapper = Wrappers.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