Mybatis自动映射Java对象 与 MySQL8后的JSON数据

2023-09-18 14:26:02

Mybatis自动映射Java对象 与 MySQL8后的JSON数据

1.转化成为正常Json类型

自认为
优点:数据库存储为单纯的数据,不需要额外存储类型
缺点:不够通用 对于Map、Object、List<T>能用,但是对于List<List<T>>不太行
          需要写两个Typehander不够优雅

接下来,简单过一下流程(只有插入和查找)

1.1 JsonTypeHander

notice: 使用的转换JSON工具是hutool中的,如果自己有别的转换可以使用别的json转换工具

hutool工具包

<dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.11</version>
        </dependency>

JsonTypeHandler 这个负责非List,一般存储的都是Map,Object,和List

public class JsonTypeHandler<T> extends BaseTypeHandler<T>{
    private Class<T> clazz;
    //在Mybatis中将类型注入进来
    public JsonTypeHandler(Class<T> clazz) {
        this.clazz = clazz;
    }
        //写入数据
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException {
        ps.setString(i, JSONUtil.toJsonStr(parameter));
    }

    /**
     * 一般是根据列名字获取下方就不再详述“(因为我也不知道,还没用到)
     * @param rs  结果
     * @param colName 列名
     */
    @SneakyThrows
    @Override
    public  T getNullableResult(ResultSet rs, String colName) {
        String data = rs.getString(colName);
        return StrUtil.isBlank(data) ? null : JSONUtil.toBean(data, clazz);
    }

    @SneakyThrows
    @Override
    public T getNullableResult(ResultSet rs, int colIndex) {
        String data = rs.getString(colIndex);
        return StrUtil.isBlank(data) ? null : JSONUtil.toBean(data, clazz);
    }

    @SneakyThrows
    @Override
    public T getNullableResult(CallableStatement cs, int i) {
        String data = cs.getString(i);
        return StrUtil.isBlank(data) ? null : JSONUtil.toBean(data, clazz);
    }
    
}

1.2 ListJsonTypeHandler 负责List 类型

public class ListJsonTypeHandler<T> extends BaseTypeHandler<List<T>> implements InitializingBean {
    private Class<T> clazz;

    public ListJsonTypeHandler(Class<T> clazz) {
        this.clazz = clazz;
    }
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, List<T> parameter, JdbcType jdbcType) throws SQLException {
        ps.setString(i, JSONUtil.toJsonStr(parameter));
    }
    @Override
    public List<T> getNullableResult(ResultSet rs, String columnName) throws SQLException {
        String data = rs.getString(columnName);
        return StrUtil.isBlank(data) ? null : JSONUtil.parseArray(data).toList(clazz);
    }

    @SneakyThrows
    @Override
    public List<T> getNullableResult(ResultSet rs, int colIndex) {
        String data = rs.getString(colIndex);
        return StrUtil.isBlank(data) ? null : JSONUtil.parseArray(data).toList(clazz);
    }

    @SneakyThrows
    @Override
    public List<T> getNullableResult(CallableStatement cs, int i) {
        String data = cs.getString(i);
        return StrUtil.isBlank(data) ? null : JSONUtil.parseArray(data).toList(clazz);
    }

1.3 实体类

@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class Json {
    /**
     * 唯一标识
     */
    private Integer id;

    /**
     * map
     */
    private Map<String,Object> mapJson;

    /**
     * 对象
     * 这个对象自定义的放在下面
     */
    private Object objJson;

    /**
     * list集合
     * <? extends Object>这个我也不知道怎么设置  但是用这个没错
     */
    private List<? extends Object> listJson;
}

//测试的对象
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class JsonObj {
    /**
     * 唯一id
     */
    private Integer id;

    /**
     * 测试所用
     */
    private String str;
}

1.4 mapper

//查找 不建议用 * 代替 我是为啦偷工减料
    @Select(" SELECT * from json ")
    @Results(value = {
            @Result(property = "id", column = "id"),
            @Result(property = "mapJson", column = "mapJson", typeHandler = JsonTypeHandler.class,javaType = HashMap.class),
            @Result(property = "objJson", column = "objJson", typeHandler = JsonTypeHandler.class,javaType = JsonObj.class),
            @Result(property = "listJson", column = "listJson", typeHandler = ListJsonTypeHandler.class,javaType = JsonObj.class)
    })
    List<Json> select1();
// 增加
    @Insert("insert into json( mapJson, objJson, listJson) values (#{mapJson,typeHandler=com.hb.springredis.typeHandler.JsonTypeHandler}," +
            "#{objJson,typeHandler=com.hb.springredis.typeHandler.JsonTypeHandler}," +
            "#{listJson,typeHandler=com.hb.springredis.typeHandler.JsonTypeHandler})")
    int insert1(Json vo);

1.5 测试类

@SpringBootTest
public class ProductTest {
//这个就是刚才放sql的mapper
    @Autowired
    JsonMapper jsonMapper;
    @Test
    void test11() throws JsonProcessingException {

        JsonObj js = JsonObj.builder().str("这真的是一个简单的测试对象").build();
        Map<String,Object> map =  new HashMap<>();
        map.put("gaga","乱杀");
        List<JsonObj> jsonObjs = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            JsonObj js0 = JsonObj.builder().id(i).str("这真的是一个简单的测试对象").build();
            jsonObjs.add(js0);
        }
        Json build = Json.builder().mapJson(map).listJson(jsonObjs).objJson(js).build();
        jsonMapper.insert1(build);

    }
    @Test
    void test12(){

        List<Json> select = jsonMapper.select1();
        System.out.println(select);
    }
    }

在这里插入图片描述

2. 存储为携带类型的Json

因为在java在编译的时候是泛型擦除的,所以对于,List里面的类型无法确定,于是便可以把数据类型存入数据库之中,并且不需要再指出java类型
在这里插入图片描述
实体类还和上面一样,只需调整mapper中,对应的typeHandler即可

 @Select(" SELECT * from json ")
    @Results(value = {
            @Result(property = "id", column = "id"),
            @Result(property = "mapJson", column = "mapJson", typeHandler = JsonTypeHandler2.class),
            @Result(property = "objJson", column = "objJson", typeHandler = JsonTypeHandler2.class),
            @Result(property = "listJson", column = "listJson", typeHandler = JsonTypeHandler2.class)
    })
    List<Json> select();



    @Insert("insert into json( mapJson, objJson, listJson) values (#{mapJson,typeHandler=com.hb.springredis.typeHandler.JsonTypeHandler2}," +
            "#{objJson,typeHandler=com.hb.springredis.typeHandler.JsonTypeHandler2}," +
            "#{listJson,typeHandler=com.hb.springredis.typeHandler.JsonTypeHandler2})")
    int insert(Json vo);

在这里插入图片描述
ListJsonTypehander2

public class ListJsonTypeHandler<T> extends BaseTypeHandler<List<T>>{
    private Class<T> clazz;

    public ListJsonTypeHandler(Class<T> clazz) {
        this.clazz = clazz;
    }


    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, List<T> parameter, JdbcType jdbcType) throws SQLException {
        ps.setString(i, JSONUtil.toJsonStr(parameter));
    }
    @Override
    public List<T> getNullableResult(ResultSet rs, String columnName) throws SQLException {
        String data = rs.getString(columnName);
        return StrUtil.isBlank(data) ? null : JSONUtil.parseArray(data).toList(clazz);
    }

    @SneakyThrows
    @Override
    public List<T> getNullableResult(ResultSet rs, int colIndex) {
        String data = rs.getString(colIndex);
        return StrUtil.isBlank(data) ? null : JSONUtil.parseArray(data).toList(clazz);
    }

    @SneakyThrows
    @Override
    public List<T> getNullableResult(CallableStatement cs, int i) {
        String data = cs.getString(i);
        return StrUtil.isBlank(data) ? null : JSONUtil.parseArray(data).toList(clazz);
    }
}

测试类,和上面基本类似

  @Test
    void test() throws JsonProcessingException {

        JsonObj js = JsonObj.builder().str("这真的是一个简单的测试对象").build();
        Map<String,Object> map =  new HashMap<>();
        map.put("gaga","乱杀");
        List<JsonObj> jsonObjs = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            JsonObj js0 = JsonObj.builder().id(i).str("这真的是一个简单的测试对象").build();
            jsonObjs.add(js0);
        }
        Json build = Json.builder().mapJson(map).listJson(jsonObjs).objJson(js).build();
        jsonMapper.insert(build);

    }

    @Test
    void test1(){

        List<Json> select = jsonMapper.select();
        System.out.println(select);

    }
更多推荐

ruoyi框架修改左侧菜单样式

菜单效果ruoyi前端框架左侧的菜单很丑,我们需要修改一下样式,下面直接看效果。修改代码1、sidebar.scss.el-menu-item,.el-submenu__title{overflow:hidden!important;text-overflow:ellipsis!important;white-spac

Thymeleaf介绍及其在Spring Boot中的使用

📖Thymeleaf简介📚Thymeleaf的定义Thymeleaf是一款现代化的服务器端Java模板引擎,适用于Web和独立应用场景。它具备处理HTML、XML、JavaScript、CSS以及纯文本的能力。Thymeleaf的核心目标是为开发者提供一种优雅且自然的模板设计方式,从而使得开发者能够更加便捷地构建、

httpclient3.1跳过ssl验证

原来的老项目调用一个Http的服务,最近http的服务调整成了https,因此需要调整一下,网上大部分都是4.5以上版本,3.1版本处理方法比较少,因此记录一下一、实现两个类1.MyX509TrustManagerimportjava.security.cert.CertificateException;importj

SSL加速是什么,有什么优势?

SSL加速技术是一种专门用于加速HTTPS通信的技术,它可以在服务器和客户端之间提供高效的加密和解密处理,以提升网络通信的安全性和性能。以下是SSL加速技术的一些主要优势:提高网站的访问速度:SSL加速技术可以对SSL握手过程进行优化,加快SSL连接速度,从而减少响应时间和延迟,提高网站的访问速度。降低服务器负载:SS

Nacos注册中心

Nacos安装https://nacos.io/zh-cn/源码安装第一步:利用Gitee获取nacos在github上的代码到自己的gitee仓库中https://github.com/alibaba/nacos.git第二步:下载源码到本地。第三步:使用maven编译代码。#先切换到master分支gitcheck

git及dbc的学习

1)git的使用方法CommandlineinstructionsYoucanalsouploadexistingfilesfromyourcomputerusingtheinstructionsbelow.Gitglobalsetupgitconfig--globaluser.name"username"gitcon

redis分布式锁

用于用户重复注册,点击过快,有可能会注册相同的手机号问题。给用户手机号枷锁一分钟时间,判断相同的手机号。判断下面这块代码执行时间是否超过一分钟时间,不论超没超过都会释放锁,下个同样的手机号再次注册,都得等到代码执行完毕后(或者是一分钟后)才能进行注册,防止有两个相同的手机号,两个线程,查询数据库都没存在,而注册了两次,

竞赛选题 基于机器视觉的银行卡识别系统 - opencv python

1前言🔥优质竞赛项目系列,今天要分享的是基于深度学习的银行卡识别算法设计该项目较为新颖,适合作为竞赛课题方向,学长非常推荐!🧿更多资料,项目分享:https://gitee.com/dancheng-senior/postgraduate2算法设计流程银行卡卡号识别技术原理是先对银行卡图像定位,保障获取图像绝对位置

SpringSecurity---内存认证和数据库认证

目录一、内存认证二、认证逻辑三、数据库认证(也就是用户名和密码在数据库中寻找)(1)mapper层(2)启动类添加扫描注解(3)编写UserDetailsService实现类一、内存认证@ConfigurationpublicclassSecurityConfig{//定义认证逻辑@BeanpublicUserDeta

springboot整合mybatis

整合SpringBoot与MyBatis框架的步骤如下:步骤1:创建SpringBoot项目-在IDE中创建一个新的SpringBoot项目。步骤2:添加相关依赖-在项目的pom.xml文件中添加以下依赖:<dependencies><dependency><groupId>org.springframework.bo

基于PHP的短视频SEO矩阵系统源码开发

随着短视频市场的爆发式增长,越来越多的企业开始寻求在短视频领域建立自己的品牌形象,增加用户粘性和获取更多流量。为此,一套高效的短视频SEO矩阵系统源码显得尤为重要。本文将介绍基于PHP语言的短视频SEO矩阵系统源码开发,帮助读者更好地了解该系统的实现原理和开发过程。一、系统概述短视频SEO矩阵系统是一套基于PHP语言开

热文推荐