前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Springboot+Mybatis+MySql下,mysql使用json类型字段存取的处理

Springboot+Mybatis+MySql下,mysql使用json类型字段存取的处理

作者头像
stys35
发布2020-06-22 14:47:05
17.3K3
发布2020-06-22 14:47:05
举报
文章被收录于专栏:工作笔记精华工作笔记精华

1、mysql5.7开始支持json类型字段; 2、mybatis暂不支持json类型字段的处理,需要自己做处理

项目使用到了这个,网上查了一些资料,实践成功,做记录。 第一步:建表

代码语言:javascript
复制
CREATE TABLE rules_test(
id INT PRIMARY KEY AUTO_INCREMENT,
sys_name VARCHAR(16) NOT NULL unique,
rules JSON,
date TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

第二步:使用generator自动生成xml文件,entity(实体)文件,mapper文件

代码语言:javascript
复制
RulesTestMapper.xml
RulesTest.java
RulesTestMapper.java

第三步:建包com.xxx.xxx.handler,新建MySqlJsonHandler.java,内容如下:

代码语言:javascript
复制
package com.xxx.xxx.handler;

import com.alibaba.fastjson.JSONObject;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
 * @Project 
 * @Autor 
 * @Create 2019/7/16 1:32 PM
 * @Description
 */
@MappedTypes(JSONObject.class)
@MappedJdbcTypes(JdbcType.VARCHAR)
public class MySqlJsonHandler extends BaseTypeHandler<JSONObject>{
    /**
     * 设置非空参数
     * @param ps
     * @param i
     * @param parameter
     * @param jdbcType
     * @throws SQLException
     */
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, JSONObject parameter, JdbcType jdbcType) throws SQLException {
        ps.setString(i,String.valueOf(parameter.toJSONString()));
    }
    /**
     * 根据列名,获取可以为空的结果
     * @param rs
     * @param columnName
     * @return
     * @throws SQLException
     */
    @Override
    public JSONObject getNullableResult(ResultSet rs, String columnName) throws SQLException {
        String sqlJson = rs.getString(columnName);
        if (null != sqlJson) {
            return JSONObject.parseObject(sqlJson);
        }
        return null;
    }
    /**
     * 根据列索引,获取可以为内控的接口
     * @param rs
     * @param columnIndex
     * @return
     * @throws SQLException
     */
    @Override
    public JSONObject getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        String sqlJson = rs.getString(columnIndex);
        if (null != sqlJson) {
            return JSONObject.parseObject(sqlJson);
        }
        return null;
    }
    /**
     *
     * @param cs
     * @param columnIndex
     * @return
     * @throws SQLException
     */
    @Override
    public JSONObject getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        String sqlJson = cs.getNString(columnIndex);
        if (null != sqlJson) {
            return JSONObject.parseObject(sqlJson);
        }
        return null;
    }
}

第四步:在application.yml中增加对应配置

代码语言:javascript
复制
mybatis:
  mapper-locations: classpath:mapper/*.xml   
  type-aliases-package: com.xxx.xxx.entity   
  type-handlers-package: com.xxx.xxx.handler  #增加此项配置

第五步:修改RulesTestMappler.xml中对应部分 第一个地方---->

代码语言:javascript
复制
<resultMap id="BaseResultMap" type="com.xxx.xxxx.entity.RulesTest" >
    <!--
      WARNING - @mbggenerated
      This element is automatically generated by MyBatis Generator, do not modify.
    -->
    <id column="id" property="id" jdbcType="INTEGER" />
    <result column="sys_name" property="sysName" jdbcType="VARCHAR" />
    <!--将json类型的rules字段修改为如下形式-->
    <result column="rules" property="rules" typeHandler="com.xxx.xxx.handler.MySqlJsonHandler" />
    <result column="date" property="date" jdbcType="TIMESTAMP" />
  </resultMap>

其他地方----> PS:在xml中写sql语句时,需要将使用到rules的地方配置,以下以插入为例

代码语言:javascript
复制
<insert id="insertTest" parameterType="com.xxx.xxx.entity.RulesTest" >
    <!--
      WARNING - @mbggenerated
      This element is automatically generated by MyBatis Generator, do not modify.
    -->
    insert into rules_test (id, sys_name, rules,
    date)
    values (#{id,jdbcType=INTEGER}, #{sysName,jdbcType=VARCHAR}, #{rules,jdbcType=OTHER,typeHandler=com.xxx.xxx.handler.MySqlJsonHandler},
    #{date,jdbcType=TIMESTAMP})
  </insert>

第六步:修改RulesTest.java实体文件中,rules对应的属性修改为JSONObejct,以下仅摘取修改相关代码

代码语言:javascript
复制
import com.alibaba.fastjson.JSONObject;
//属性
private JSONObject rules;
//get方法
public JSONObject getRules() {
        return rules;
    }
//set方法
public void setRules(JSONObject rules) {
        this.rules = rules == null ? null : rules;
    }

至此,所有相关修改都已经修改完了,按照正常的步骤进行开发即可~

参考链接: 1、SpringBoot中MyBatis 处理 MySQL5.7 的json字段数据 2、MyBatis针对Mysql中json字段的类型处理

SpringBoot中MyBatis 处理 MySQL5.7 的json字段数据

最近学习过程中遇到一个需要将订单数据存入数据库需求,项目是使用 SpringBoot+MyBatis 框架,数据库是 MySQL,订单数据格式如下:

代码语言:javascript
复制

   { 
 
 
   
 
   all_price: 32 
 
 
   
 
   beizhu: "暂无" 
 
 
   
 
   store_id: "1" 
 
 
   
 
   goods: [ 
 
 
   
 
   {goods_id: 2,goods_name: "辣椒炒肉",goods_num: 2}, 
 
 
   
 
   {goods_id: 5,goods_name: "扬州炒饭",goods_num: 1}, 
 
 
   
 
   {goods_id: 6,goods_name: "蛋炒饭",goods_num: 1}] 
 
 
   
 
   usemessage: { 
 
 
   
 
   cityName: "广州市" 
 
 
   
 
   countyName: "海珠区" 
 
 
   
 
   detailInfo: "新港中路397号" 
 
 
   
 
   postalCode: "510000" 
 
 
   
 
   provinceName: "广东省" 
 
 
   
 
   telNumber: "020-81167888" 
 
 
   
 
   userName: "张三" 
 
 
   
 
   } 
 
 
   
 
   } 
 
 

而我想把 goodsusemessage 这两个比较复杂的数据当成分别一个字段去处理,不想拆分里面的字段,之前没有将 json 格式数据插入 MySQL 数据库的经验,插入的都是拆分后的一个一个字段,如果我想保留数据格式存入数据库又如何处理呢??脑壳疼!!

网上查询后,了解到 MySQL 5.7.8 以后版本居然加入了 json 字段,沃德天,好惊喜啊哈哈哈!!!这下有搞头了!

赶紧查了一下我的 MySQL 版本:是大于 V5.7.8 的,在支持范围内

 等等,我怎么在Navicat 上怎么找不到 json 字段类型   

,又是一番查找,原来 Navicat 版本太低不支持。。。所以我又升级到 Navicat Premium 12 版本了,这下 json 字段出来了,那这个 json 字段类型对应的 Java bean 属性又是什么呢?MyBatis 怎么写 sql 呢?

又是一番查找。。。

额,MyBatis 还不支持直接处理MySQL json字段。。。只能通过自定义 TypeHandler 来转化,行吧,那就写呗。不过之前要看看 goodsusemessage 这两个是有区别的,所以我分别转成了 JSONArray、JSONObject ( 选择 com.alibaba.fastjson 工具类下的)

代码语言:javascript
复制
   
 
   JSONArray goodslist=data.getJSONArray("goods"); 
 
 
   
 
   JSONObject usemessage= data.getJSONObject("usemessage"); 

 

所以对应的也要自定义两种不同 TypeHandler 来分别适配 ,在此之前,由于我使用的是  fastjson 这个工具类包,所以要在 pom.xml 中先引入:

代码语言:javascript
复制
 <!--添加fastjson依赖--> 
 
 
   
 
   <dependency> 
 
 
   
 
   <groupId>com.alibaba</groupId> 
 
 
   
 
   <artifactId>fastjson</artifactId> 
 
 
   
 
   <version>1.2.7</version> 
 
 
   
 
   </dependency> 
 

然后就是两个自定义 TypeHandler 了:首先是ArrayJsonHandler .java 

代码语言:javascript
复制

 
   package com.lxx.campusstore; 
 
 
   
 
   
 
 
   
 
   import com.alibaba.fastjson.JSONArray; 
 
 
   
 
   import org.apache.ibatis.type.BaseTypeHandler; 
 
 
   
 
   import org.apache.ibatis.type.JdbcType; 
 
 
   
 
   import org.apache.ibatis.type.MappedJdbcTypes; 
 
 
   
 
   import org.apache.ibatis.type.MappedTypes; 
 
 
   
 
   
 
 
   
 
   import java.sql.CallableStatement; 
 
 
   
 
   import java.sql.PreparedStatement; 
 
 
   
 
   import java.sql.ResultSet; 
 
 
   
 
   import java.sql.SQLException; 
 
 
   
 
   
 
 
   
 
   /** 
 
 
   
 
   * Created by lixio on 2019/3/28 20:51 
 
 
   
 
   * @description 用以mysql中json格式的字段,进行转换的自定义转换器,转换为实体类的JSONArray属性 
 
 
   
 
   * MappedTypes注解中的类代表此转换器可以自动转换为的java对象 
 
 
   
 
   * MappedJdbcTypes注解中设置的是对应的jdbctype 
 
 
   
 
   */ 
 
 
   
 
   @MappedTypes(JSONArray.class) 
 
 
   
 
   @MappedJdbcTypes(JdbcType.VARCHAR) 
 
 
   
 
   public class ArrayJsonHandler extends BaseTypeHandler<JSONArray> { 
 
 
   
 
   //设置非空参数 
 
 
   
 
   @Override 
 
 
   
 
   public void setNonNullParameter(PreparedStatement ps, int i, JSONArray parameter, JdbcType jdbcType) throws SQLException { 
 
 
   
 
   ps.setString(i, String.valueOf(parameter.toJSONString())); 
 
 
   
 
   } 
 
 
   
 
   //根据列名,获取可以为空的结果 
 
 
   
 
   @Override 
 
 
   
 
   public JSONArray getNullableResult(ResultSet rs, String columnName) throws SQLException { 
 
 
   
 
   String sqlJson = rs.getString(columnName); 
 
 
   
 
   if (null != sqlJson){ 
 
 
   
 
   return JSONArray.parseArray(sqlJson); 
 
 
   
 
   } 
 
 
   
 
   return null; 
 
 
   
 
   } 
 
 
   
 
   //根据列索引,获取可以为空的结果 
 
 
   
 
   @Override 
 
 
   
 
   public JSONArray getNullableResult(ResultSet rs, int columnIndex) throws SQLException { 
 
 
   
 
   String sqlJson = rs.getString(columnIndex); 
 
 
   
 
   if (null != sqlJson){ 
 
 
   
 
   return JSONArray.parseArray(sqlJson); 
 
 
   
 
   } 
 
 
   
 
   return null; 
 
 
   
 
   } 
 
 
   
 
   
 
 
   
 
   @Override 
 
 
   
 
   public JSONArray getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { 
 
 
   
 
   String sqlJson = cs.getString(columnIndex); 
 
 
   
 
   if (null != sqlJson){ 
 
 
   
 
   return JSONArray.parseArray(sqlJson); 
 
 
   
 
   } 
 
 
   
 
   return null; 
 
 
   
 
   } 
 
 
   
 
   
 
 
   
 
   } 
 
代码语言:javascript
复制
ObjectJsonHandler.java 如下
代码语言:javascript
复制
   
 
   package com.lxx.campusstore; 
 
 
   
 
   
 
 
   
 
   import com.alibaba.fastjson.JSONObject; 
 
 
   
 
   import org.apache.ibatis.type.BaseTypeHandler; 
 
 
   
 
   import org.apache.ibatis.type.JdbcType; 
 
 
   
 
   import org.apache.ibatis.type.MappedJdbcTypes; 
 
 
   
 
   import org.apache.ibatis.type.MappedTypes; 
 
 
   
 
   
 
 
   
 
   import java.sql.CallableStatement; 
 
 
   
 
   import java.sql.PreparedStatement; 
 
 
   
 
   import java.sql.ResultSet; 
 
 
   
 
   import java.sql.SQLException; 
 
 
   
 
   
 
 
   
 
   /** 
 
 
   
 
   * Created by lixio on 2019/3/28 15:44 
 
 
   
 
   * @description 用以mysql中json格式的字段,进行转换的自定义转换器,转换为实体类的JSONObject属性 
 
 
   
 
   * MappedTypes注解中的类代表此转换器可以自动转换为的java对象 
 
 
   
 
   * MappedJdbcTypes注解中设置的是对应的jdbctype 
 
 
   
 
   */ 
 
 
   
 
   
 
 
   
 
   @MappedTypes(JSONObject.class) 
 
 
   
 
   @MappedJdbcTypes(JdbcType.VARCHAR) 
 
 
   
 
   public class ObjectJsonHandler extends BaseTypeHandler<JSONObject>{ 
 
 
   
 
   
 
 
   
 
   //设置非空参数 
 
 
   
 
   @Override 
 
 
   
 
   public void setNonNullParameter(PreparedStatement ps, int i, JSONObject parameter, JdbcType jdbcType) throws SQLException { 
 
 
   
 
   ps.setString(i, String.valueOf(parameter.toJSONString())); 
 
 
   
 
   } 
 
 
   
 
   //根据列名,获取可以为空的结果 
 
 
   
 
   @Override 
 
 
   
 
   public JSONObject getNullableResult(ResultSet rs, String columnName) throws SQLException { 
 
 
   
 
   String sqlJson = rs.getString(columnName); 
 
 
   
 
   if (null != sqlJson){ 
 
 
   
 
   return JSONObject.parseObject(sqlJson); 
 
 
   
 
   } 
 
 
   
 
   return null; 
 
 
   
 
   } 
 
 
   
 
   //根据列索引,获取可以为空的结果 
 
 
   
 
   @Override 
 
 
   
 
   public JSONObject getNullableResult(ResultSet rs, int columnIndex) throws SQLException { 
 
 
   
 
   String sqlJson = rs.getString(columnIndex); 
 
 
   
 
   if (null != sqlJson){ 
 
 
   
 
   return JSONObject.parseObject(sqlJson); 
 
 
   
 
   } 
 
 
   
 
   return null; 
 
 
   
 
   } 
 
 
   
 
   
 
 
   
 
   @Override 
 
 
   
 
   public JSONObject getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { 
 
 
   
 
   String sqlJson = cs.getString(columnIndex); 
 
 
   
 
   if (null != sqlJson){ 
 
 
   
 
   return JSONObject.parseObject(sqlJson); 
 
 
   
 
   } 
 
 
   
 
   return null; 
 
 
   
 
   } 
 
 
   
 
   } 
 
 

 要想 mybatis 能直接使用,接下来还得在配置文件 application.properties 下加入这两个自定义转换类的所在路径:

代码语言:javascript
复制
   
 
   #配置mybaits自定义类型转换类所在的包 
 
 
   
 
   mybatis.type-handlers-package=com.lxx.campusstore 
 
 

到这里,MyBatis 就能向普通的字段一样 对MySQL 的 json 字段数据进行增删查改了,例子如下:

resultMap 中引用自定义转换

 插入语句如下:

代码语言:javascript
复制

 
   <insert id="insert" parameterType="com.lxx.campusstore.model.Orders"> 
 
 
   
 
   insert into orders ( order_num, userid,store_id, 
 
 
   
 
   usemessage, goodslist,beizhu, all_price) 
 
 
   
 
   values (#{orderNum,jdbcType=BIGINT}, #{userid,jdbcType=VARCHAR}, #{storeId,jdbcType=INTEGER}, 
 
 
   
 
   #{usemessage,jdbcType=OTHER,typeHandler=com.lxx.campusstore.ObjectJsonHandler}, 
 
 
   
 
   #{goodslist,jdbcType=OTHER,typeHandler=com.lxx.campusstore.ArrayJsonHandler},#{beizhu,jdbcType=VARCHAR},#{allPrice,jdbcType=DOUBLE}) 
 
 
   
 
   </insert> 
 
 

 插入结果如下:(还保留着 json 格式)

查询语句如下:

代码语言:javascript
复制
  
 
   <select id="selectAll" parameterType="com.lxx.campusstore.model.Orders" resultMap="BaseResultMap"> 
 
 
   
 
   select order_id, order_num, usemessage, goodslist, beizhu, all_price, create_time 
 
 
   
 
   from orders  
 
 
   
 
   where userid = #{userid,jdbcType=VARCHAR} ORDER by create_time desc 
 
 
   
 
   </select> 
 
 

查询结果如下:(还保留着 json 格式,不用手动再转化)

到此为止,MyBatis 自定义转化类后就能自如的对 MySQL 的 json 字段进行处理了。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 MySQL
腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档