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

news2025/2/24 20:12:21

文章目录

  • Mybatis自动映射Java对象 与 MySQL8后的JSON数据
    • 1.转化成为正常Json类型
      • 1.1 JsonTypeHander
      • 1.2 ListJsonTypeHandler 负责List<T> 类型
      • 1.3 实体类
      • 1.4 mapper
      • 1.5 测试类
    • 2. 存储为携带类型的Json

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);

    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1031239.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

OPTEE Ftrace函数跟踪

安全之安全(security)博客目录导读 OPTEE调试技术汇总 目录 一、序言 二、Ftrace配置 三、Ftrace使用 四、Ftrace典型输出 一、序言 本节描述如何使用ftrace为TA生成函数调用图。该名称来自具有类似目的的Linux框架&#xff0c;但是OP-TEE ftrace非常具体…

前端代码统计工具之cloc介绍

目录 一、安装 二 使用命令cloc path&#xff1a; 使用cloc工具可以很好的统计出前端的代码量&#xff0c;经过亲身实践真的很棒。 一、安装 安装命令 pnpm add cloc -g 二 使用命令cloc path&#xff1a; cloc ./ 如果报错&#xff1a; perl 不是内部或外部命令的问…

风靡全国的真人猫抓老鼠是什么?

某音上这个词条2.6亿&#xff0c;小某书上1.2亿。据说已经风靡全国50多个城市了。各大新闻网站和自媒体人争相报道&#xff0c;热度直接拉满&#xff01; 现在的年轻人真会玩&#xff01; 仔细了解过后发现&#xff0c;它火是有内在原因的&#xff0c;现在都市工作后没有可以…

近年来国内室内定位领域硕士论文选题的现状与趋势

目录 一、前言 二、选题的目的和意义 三、选题现状分析 四、选题趋势分析 一、前言 本博文采用了图表统计法分析了近5年来100余篇高被引室内定位领域硕士论文选题的现状&#xff0c;并从选题现状中得出了该领域选题的大致趋势。本文还通过分析该领域硕士毕业论文选题的现…

只需100GB内存,让Falcon 180B在你的电脑上起飞

一、前言 自2023年5月&#xff0c;阿布扎比技术创新研究所&#xff08;TII&#xff09;发布了两个预训练的LLM&#xff1a;Falcon 7B和Falcon-40B&#xff0c;这两个模型的表现十分优异&#xff0c;在OpenLLM排行榜上高居榜首。然而&#xff0c;在短短不到几个月的时间&#x…

Sftp服务安全评估

1 认识SFTP FTP&#xff08;SSH文件传输协议&#xff09;和FTP&#xff08;文件传输协议&#xff09;是两种用于文件传输的协议&#xff0c;它们在工作原理、安全性和配置方面有很大的差异。 1&#xff09;工作原理&#xff1a; FTP&#xff1a;FTP使用两个独立的连接&#…

【MySql】1- 基础篇(上)

文章目录 1.1 前言1.2 基础架构1.2.1 MySql基本架构示意图1.2.2 SQL语句执行顺序 1.3 日志系统&#xff1a;一条SQL更新语句如何执行1.3.1 两阶段提交 1.4 事务隔离1.4.1 隔离性与隔离级别1.4.2 事务隔离的实现-展开说明“可重复读”1.4.3 事务的启动方式 1.5 深入浅出索引1.5.…

什么是实时操作系统(UCOS简介)

uC/OS-III官网&#xff1a;Home Page - Weston Embedded Solutions 一、裸机与RTOS介绍 下面我将从不同方面阐述裸机与试试操作系统的区别&#xff0c;从而进一步介绍裸机和实时操作系统 定义&#xff1a; 裸机&#xff1a;裸机指的是没有任何操作系统或软件层的硬件系统。在…

Linux C 网络基础

为什么需要网络通信&#xff1f; 进程间通信解决的是本机内通信 网络通信解决的是任意不同机器的通信 实现网络通信需要哪些支持 1.通信设备&#xff1a;网卡&#xff08;PC机自带&#xff09;&#xff1b; 路由器和交换机&#xff1b; 光纤…

Android:ListView在Fragment中的使用

一、前言&#xff1a; 因为工作一直在用mvvm框架&#xff0c;因此这篇文章是基于mvvm框架写的。在Fragment复制之前一定要谨记项目可以跑起来。确保能跑起来之后直接复制就行。 二、代码展示&#xff1a; 页面布局 ?xml version"1.0" encoding"utf-8"…

Cortex-M3/M4基础

一、Cortex-M3/M4 通用寄存器 1、我们首先来了解一下M3/M4的寄存器&#xff0c;M4比M3多了一个浮点单元FPU。其他的部分基本和M3是一样的。 2、Cortex-M3/M4系列处理器拥有通用寄存器R0-R15以及一些特殊功能的寄存器。 3、R0‐ R12 是最“通用目的”的。 4、但是绝大多数的…

UEFI 安装 Debian12 Linux 物理机虚拟机VMware通用

文章目录 前言⭐前置虚拟机物理机 安装流程选择安装方式语言及键盘选择网络选择创建用户系统磁盘分区新旧磁盘分区方式BOOT分区SWAP分区根分区 安装过程中其他选项选择软件包安装流程末 前言⭐ 物理机和虚拟机安装仅有设置UFFI引导的差别、这里前置为设置UEFI引导。安装步骤大…

干货 | 中国石化化工高端新材料价格体系模型构建

以下内容整理自2023年夏季学期大数据能力提升项目《大数据实践课》同学们所做的期末答辩汇报。 随着石化行业市场日趋饱和&#xff0c;市场竞争日益激烈&#xff0c;企业利润空间不断被压缩&#xff0c;大多数石化企业急需转型开拓新市场&#xff0c;化工原料价格的波动对于石化…

数据结构 - 线性表(顺序表)

线性表是什么 线性表是包含若干数据元素的一个线性序列&#xff0c;记为&#xff1a; L (a0&#xff0c;…ai-1&#xff0c;ai,ai1,…an-1) L为表名&#xff0c;ai&#xff08;0≤ i ≤n-1&#xff09;为数据元素&#xff1b;n为表长&#xff0c;n>0时&#xff0c;线性表…

Vue的详细教程--用Vue-cli搭建SPA项目

Vue的详细教程--用Vue-cli搭建SPA项目 1.Vue-cli是什么2.什么是SPA项目1.vue init webpack spa2.一问一答模式2&#xff1a;运行完上面的命令后&#xff0c;我们需要将当前路径改变到SPA这个文件夹内&#xff0c;然后安装需要的模块此步骤可理解成&#xff1a;maven的web项目创…

PY32F003F18之ADC问题

普然单片机PY32F003F18的内部有一个LDO&#xff0c;其电压固定为1.2V。我在用官方程序测试时&#xff0c;若接上USB转串口的RX导线&#xff0c;向PC发送数据&#xff0c;读内部参考电压比较正确&#xff0c;但是&#xff0c;当接上USB转串口的TX导线时&#xff0c;发现读到内部…

【从0学习Solidity】15. 异常

【从0学习Solidity】15. 异常 博主简介&#xff1a;不写代码没饭吃&#xff0c;一名全栈领域的创作者&#xff0c;专注于研究互联网产品的解决方案和技术。熟悉云原生、微服务架构&#xff0c;分享一些项目实战经验以及前沿技术的见解。关注我们的主页&#xff0c;探索全栈开发…

ruoyi框架开发LOT项目

背景 最近闲着就用ruoyi的框架写了一个LOT项目&#xff0c;个人觉得效果还可以。 1、首页 2、企业管理 3、用户管理 4、设备列表 5、设备列表标签展示 6、设备详情页面 7、大屏展示界面 8、结束 -----华丽的分割线&#xff0c;以下是凑字数&#xff0c;大家不用花时间看&…

2023年中国研究生数学建模竞赛D题解题思路

为了更好的帮助大家第一天选题&#xff0c;这里首先为大家带来D题解题思路&#xff0c;分析对应赛题之后做题阶段可能会遇到的各种难点。 稍后会带来D题的详细解析思路&#xff0c;以及相关的其他版本解题思路 成品论文等资料。 赛题难度评估&#xff1a;A、B>C>E、F&g…

分享demo:Vue3 使用element plus + vue-i18实现国际化

&#x1f447;面是demo展示 PS&#xff1a;点赞关注私信获取demo