Mybatis存储数据将数据转为json

第一种方法

  1. 先创建一个表类型如下
    在这里插入图片描述
  2. 创建一个项目,写一个接口 ,
    在这里插入图片描述
  3. 写一个JsonTypeHandler类继承BaseTypeHandler
public class JsonTypeHandler<T> extends BaseTypeHandler<T> {
    private Class<T> clazz;
    //构造函数 --- >接收一个 Class 对象作为参数,用于指定处理的数据类型。
    public JsonTypeHandler(Class<T> clazz) {
        this.clazz = clazz;
    }
    public JsonTypeHandler() {
    }

    //插入数据将任何类型转换为json
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {
        ps.setString(i, JSON.toJSONString(parameter));
    }

    //获取数据json转换类型
    @Override
    public T getNullableResult(ResultSet rs, String columnName) throws SQLException {
        return JSON.parseObject(rs.getString(columnName), clazz);
    }

    @Override
    public T getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        return null;
    }

    @Override
    public T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return null;
    }
}
实体类
@Data
public class User {
    private Integer id;
    private String name;
    private Map<String,String> addressBook;
    private Adderss friendAddress;
    private List<Animal> pet;    
}
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Animal {
    public String name;
    public String category;

}
@Data
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Adderss{
    private String province;
    private String city;
    private String area;
}
Controller
@RestController
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping("/api/add")
    public void add(){
        User user = new User();
        user.setName("小明");

        Map map = new HashMap();
        map.put("张三","123123132");
        map.put("李四","789789798");
        map.put("王五","456456464");
        // String s = JSONUtil.toJsonStr(map);
        user.setAddressBook(map);


        Adderss adderss = Adderss.builder().province("河南省").city("郑州市").area("高新区").build();
        user.setFriendAddress(adderss);

        List<Animal> list = new ArrayList<>();
        list.add(Animal.builder().name("喵喵").category("哺乳类").build());
        list.add(Animal.builder().name("汪汪").category("哺乳类").build());
        list.add(Animal.builder().name("鹦鹉").category("鸟类").build());
        //String s1 = JSONUtil.toJsonStr(list);
        user.setPet(list);
        userService.add(user);
    }

    @GetMapping("/api/select")
    public List<User> select(){
        List<User> select = userService.select();
        return null;
    }

}
Service
@Service
public class UserService {

    @Autowired
    private UserDao userDao;

    public  List<User> select() {
        return userDao.select();
    }
    
    public void add(User user){
     userDao.add(user);
    }
}
Dao
@Mapper
public interface UserDao {
     
     void add(User user);
     List<User> select();
}
Mapper.xml 主要使用是在xml中配置类型 typeHandler=“com.by.config.JsonTypeHandler”
<?xml version="1.0" encoding="UTF-8" ?>
           <!DOCTYPE mapper
                   PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                   "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
   <-- -->
   <mapper namespace="com.by.dao.UserDao">
    <resultMap id="UserMap" type="com.by.moder.User">
       <result property="id" column="id"/>
       <result property="addressBook" column="addressBook" typeHandler="com.by.config.JsonTypeHandler"/>
       <result property="friendAddress" column="friendAddress" typeHandler="com.by.config.JsonTypeHandler"/>
       <result property="pet" column="pet" typeHandler="com.by.config.JsonTypeHandler"/>
    </resultMap>

    <insert id="add">
        insert into user2 (name, addressBook, friendAddress,pet)
        values (#{name}, #{addressBook,typeHandler=com.by.config.JsonTypeHandler}, #{friendAddress,typeHandler=com.by.config.JsonTypeHandler},#{pet,typeHandler=com.by.config.JsonTypeHandler})
    </insert>
    <select id="select" resultMap="UserMap">
        select * from user2
    </select>
   </mapper>

添加结果
在这里插入图片描述
查询结果
在这里插入图片描述
虽然结果可以的出来但是pet类型不对,list中本来该存放的是Animal对象,但存储的确实json类型。
有没有什么办法可以将全类名和这个对象都存储到数据库(以json类型形式),取得时候就可以得到与它对应的的类型

第二种方法:根据redis配置文件进行改进

使用Jackson2JsonRedisSerializer ,它 Spring Data Redis 提供的一个序列化器,用于将 Java 对象序列化为 JSON 字符串存储到 Redis 中,以及从 Redis 中读取 JSON 字符串反序列化回 Java 对象

  1. 添加依赖
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

2.改进

public class JsonTypeHandler02<T> extends BaseTypeHandler<T> {
    private Class<T> clazz;
    Jackson2JsonRedisSerializer<Object> serializer;
    public JsonTypeHandler02(Class<T> clazz) {
        this.clazz = clazz;
       serializer = new Jackson2JsonRedisSerializer<>(Object.class);

        //定义一个对象映射器
        ObjectMapper objectMapper = new ObjectMapper();
        //JsonAutoDetect.Visibility.ANY 代表所有属性或字段都可以序列化
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        //新版用法
        //以数组的方式存放到Redis,Class Type 全类名作为为第一个元素,Json字符串为第二个元素。
        objectMapper.activateDefaultTyping(objectMapper.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.NON_FINAL);
        //老版用法,已弃用
        //objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        serializer.setObjectMapper(objectMapper);
    }

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {
        ps.setString(i,new String( serializer.serialize(parameter)));
    }

    @Override
    public T getNullableResult(ResultSet rs, String columnName) throws SQLException {
        return (T) serializer.deserialize(rs.getString(columnName).getBytes(StandardCharsets.UTF_8));
    }

    @Override
    public T getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        return null;
    }

    @Override
    public T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return null;
    }

}
  1. 更改Mapper.xml中的类型typeHandler=“com.by.config.JsonTypeHandler02”
    <resultMap id="UserMap" type="com.by.moder.User">
        <result property="id" column="id"/>
        <result property="addressBook" column="addressBook" typeHandler="com.by.config.JsonTypeHandler02"/>
        <result property="friendAddress" column="friendAddress" typeHandler="com.by.config.JsonTypeHandler02"/>
        <result property="pet" column="pet" typeHandler="com.by.config.JsonTypeHandler02"/>
    </resultMap>
   <insert id="add">
        insert into user2 (name, addressBook, friendAddress,pet)
        values (#{name}, #{addressBook,typeHandler=com.by.config.JsonTypeHandler02}, #{friendAddress,typeHandler=com.by.config.JsonTypeHandler02},#{pet,typeHandler=com.by.config.JsonTypeHandler02})
    </insert>
     <select id="select" resultMap="UserMap">
        select * from user2
    </select>

最后
添加结果:在这里插入图片描述
查询结果在这里插入图片描述
但这种方法

第三种方法

  1. 写一个MybatisToJsonConfig
public class MybatisToJsonConfig<T> {
    public static final Charset DEFAULT_CHARSET;
    private final JavaType javaType;

    private ObjectMapper objectMapper = new ObjectMapper();

    public MybatisToJsonConfig(Class<T> type) {
        this.javaType = this.getJavaType(type);
    }

    public MybatisToJsonConfig(JavaType javaType) {
        this.javaType = javaType;
    }

    public T deserialize(@Nullable byte[] bytes) throws Exception {

            try {
                return this.objectMapper.readValue(bytes, 0, bytes.length, this.javaType);
            } catch (Exception var3) {
                throw new Exception("Could not read JSON: " + var3.getMessage(), var3);
            }
    }

    public byte[] serialize(@Nullable Object t) throws Exception {

            try {
                return this.objectMapper.writeValueAsBytes(t);
            } catch (Exception var3) {
                throw new Exception("Could not write JSON: " + var3.getMessage(), var3);
            }
    }

    public void setObjectMapper(ObjectMapper objectMapper) {
        Assert.notNull(objectMapper, "'objectMapper' must not be null");
        this.objectMapper = objectMapper;
    }

    protected JavaType getJavaType(Class<?> clazz) {
        return TypeFactory.defaultInstance().constructType(clazz);
    }

    static {
        DEFAULT_CHARSET = StandardCharsets.UTF_8;
    }

}
  1. 在改进JsonTypeHandler03
public class JsonTypeHandler03<T> extends BaseTypeHandler<T> {

    private static MybatisToJsonConfig<Object> serializer = null;
    static {
        serializer = new MybatisToJsonConfig<>(Object.class);

        //创建对象映射器
        ObjectMapper objectMapper = new ObjectMapper();
        //JsonAutoDetect.Visibility.ANY 代表所有属性或字段都可以序列化
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        //新版用法
        //以数组的方式存放到Redis,Class Type 全类名作为为第一个元素,Json字符串为第二个元素。
        objectMapper.activateDefaultTyping(objectMapper.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.NON_FINAL);
        //老版用法,已弃用
        //objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        serializer.setObjectMapper(objectMapper);

    }
    public JsonTypeHandler03(Class<T> clazz) {


    }

    //插入数据将任何类型转换为json
    @Override
    @SneakyThrows
    //@SneakyThrows 是 Lombok 提供的一个注解,用于在方法上自动抛出异常。
    // 使用 @SneakyThrows 注解可以使方法在遇到异常时,自动将异常转换为 java.lang.RuntimeException 并抛出,
    // 而无需显式地在方法中编写异常处理代码
    public void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {
        ps.setString(i,new String(serializer.serialize(parameter)));
    }

    //获取数据json转换类型
    @Override
    public T getNullableResult(ResultSet rs, String columnName) throws SQLException {
        try {
            return (T) serializer.deserialize(rs.getString(columnName).getBytes(StandardCharsets.UTF_8));
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public T getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        return null;
    }

    @Override
    public T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        return null;
    }
}

最后更改mapper.xml类型typeHandler=“com.by.config.JsonTypeHandler03”

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

大数据Scala教程从入门到精通第五篇:Scala环境搭建

一&#xff1a;安装步骤 1&#xff1a;scala安装 1&#xff1a;首先确保 JDK1.8 安装成功: 2&#xff1a;下载对应的 Scala 安装文件 scala-2.12.11.zip 3&#xff1a;解压 scala-2.12.11.zip 4&#xff1a;配置 Scala 的环境变量 在Windows上安装Scala_windows安装scala…

多线程三种实现

多线程 线程 线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中&#xff0c;是进程中的实际运作单位。 &#xff08;理解&#xff1a;应用软件中互相独立&#xff0c;可以同时运行的功能&#xff09; 进程 进程是程序的基本执行实体。&#xff08;理解&#…

【动态规划】:路径问题_地下城游戏

朋友们、伙计们&#xff0c;我们又见面了&#xff0c;本专栏是关于各种算法的解析&#xff0c;如果看完之后对你有一定的启发&#xff0c;那么请留下你的三连&#xff0c;祝大家心想事成&#xff01; C 语 言 专 栏&#xff1a;C语言&#xff1a;从入门到精通 数据结构专栏&…

【LLM 论文】Least-to-Most Prompting 让 LLM 实现复杂推理

论文&#xff1a;Least-to-Most Prompting Enables Complex Reasoning in Large Language Models ⭐⭐⭐ Google Research, ICLR 2023 论文速读 Chain-of-Thought&#xff08;CoT&#xff09; prompting 的方法通过结合 few-show prompt 的思路&#xff0c;让 LLM 能够挑战更具…

MySQL#MySql表的操作

目录 一、创建表 二、查看表结构 三、修改表 1.修改表的名字 2.新增一个列 3.修改列 4.删除列 5.修改列的名称 四、删除表 一、创建表 语法&#xff1a; CREATE TABLE table_name (field1 datatype,field2 datatype,field3 datatype ) character set 字符集 collate 校…

2042193-77-9,BDP FL甲基四嗪可用于标记细胞和组织样本

1.基本信息&#xff1a; BDP FL甲基四嗪是一种具有独特化学和光学性质的化合物。 2.化学结构&#xff1a; BDP FL甲基四嗪是含有甲基四嗪基团的BDP染料连接体。BDP FL部分是指附着在甲基四嗪上的荧光标记&#xff0c;使其在暴露于特定波长的光时能够发光。 甲基四嗪是一种具有…

C语言【文件操作 2】

文章目录 前言顺序读写函数的介绍fputc && fgetcfputcfgetc fputs && fgetsfputsfgets fprintf && fscanffprintffscanf fwrite && freadfwritefread 文件的随机读写fseek函数偏移量ftell函数rewind函数 文件的结束判断被错误使用的feof 结语 …

鸿蒙开发接口Ability框架:【(StaticSubscriberExtensionAbility)】

StaticSubscriberExtensionAbility StaticSubscriberExtensionAbility模块提供静态订阅者扩展能力的类别的能力。 说明&#xff1a; 本模块首批接口从API version 9 开始支持。后续版本的新增接口&#xff0c;采用上角标单独标记接口的起始版本。 本模块接口仅可在Stage模型下…

多线程学习D10 收尾了应该

线程安全集合类概述 重点介绍java.util.concurrent.* 下的线程安全集合类&#xff0c;可以发现它们有规律&#xff0c;里面包含三类关键词&#xff1a;Blocking、CopyOnWrite、Concurrent Blocking 大部分实现基于锁&#xff0c;并提供用来阻塞的方法 CopyOnWrite 之类容器修改…

iOS 17 / iPad OS 17屏蔽更新

iOS 17 / iPad OS 17屏蔽更新 1&#xff0c;进入屏蔽iOS更新的描述文件下载链接 下载链接 wx 搜索 Geek 前端发送屏蔽更新进行获取 2&#xff0c;复制这段链接&#xff0c;在Safari浏览器中打开&#xff0c;注意打开后别点击下载&#xff01;要先改时间&#xff01; 3&#…

69、oak和华为atlas 200dk A2进行编解码测试

基本思想:将oak深度相机与atlas 200dk A2进行结合,测试其dvpp的编解码能力 cmakelist.txt cmake_minimum_required(VERSION 3.16) project(untitled10) set(CMAKE_CXX_FLAGS "-std=c++11") set(CMAKE_CXX_STANDARD 11) add_definitions(-DENABLE_DVPP_INTERFACE)i…

数据的输入和输出

早期的总线系统 为了解决通信的问题、主板上铺设了一条公共线路、各个设备都连接到这条线路上、不管谁要和谁通信、都能使用它来传输、这条线路就是总线。 总线上有CPU、内存、鼠标、键盘、硬盘、网卡、声卡、显卡等… 说是一条总线、实际上是包含了传输数据的数据总线、传输…

保研面试408复习 4——操作系统、计网

文章目录 1、操作系统一、文件系统中文件是如何组织的&#xff1f;二、文件的整体概述三、UNIX外存空闲空间管理 2、计算机网络一、CSMA/CD 协议&#xff08;数据链路层协议&#xff09;二、以太网MAC帧MTU 标记文字记忆&#xff0c;加粗文字注意&#xff0c;普通文字理解。 1、…

「C++ 内存管理篇 00」指针

目录 一、变量&#xff0c;变量名和指针 1. 什么是变量&#xff1f; 2. 变量名和指针 3. 使用指针获取数据 二、指针变量和数组变量 三、编译器对指针的等级有着严格的检查 四、指针的加减 1. 存放指针的变量的加减 2. 存放指针的变量的自增自减 3. 两个指针相减 一、变量&…

融知财经:期货交易的规则和操作方法

期货交易是指在未来的某一特定时期&#xff0c;买卖双方通过签订合约的方式&#xff0c;约定以某种价格买卖一定数量的某种商品或资产的行为。期货交易的规则和操作方法如下&#xff1a; 期货交易的规则和操作方法 1、双向交易&#xff1a; 期货市场允许投资者进行多头&#xf…

数据结构_栈和队列(Stack Queue)

✨✨所属专栏&#xff1a;数据结构✨✨ ✨✨作者主页&#xff1a;嶔某✨✨ 栈&#xff1a; 代码&#xff1a;function/数据结构_栈/stack.c 钦某/c-language-learning - 码云 - 开源中国 (gitee.com)https://gitee.com/wang-qin928/c-language-learning/blob/master/function/…

实战教程:个性化生鲜超市小程序制作与运营全解析

生鲜电商行业一直以来都备受关注&#xff0c;而如今&#xff0c;小程序商城成为了这个行业的新潮流。乔拓云平台提供了一个便捷的平台&#xff0c;让我们可以轻松地进入商城后台管理页面。 浏览器搜索【乔拓云】并登陆平台后&#xff0c;我们可以点击【小程序商城】模块&#x…

Redis学习汇总

目录 1.Linux环境下安装redis 2.redis的数据结构及命令 3.redis.conf配置文件常用配置 3.redis的事务操作 4.redis实现乐观锁 5.通过jedis操作redis 6.Springboot集成redis 7.自定义一个RedisTemplate 8.持久化策略 RDB和AOF 9.redis集群环境搭建 10.哨兵模式 11.缓…

Langchain实战

感谢阅读 LangChain介绍百度文心API申请申请百度智能云创建应用 LLMChain demo以及伪幻觉问题多轮对话的实现Sequential ChainsSimpleSequentialChainSequentialChainRouter Chain Documents ChainStuffDocumentsChainRefineDocumentsChainMapReduceDocumentsChainMapRerankDoc…

第09章 局域网技术(拓扑结构设计+FDDI工作机制)

9.1 本章目标 了解IEEE 802局域网标准掌握局域网拓扑结构了解10Base以太网了解快速以太网熟悉交换式以太网了解千兆位以太网了解其它种类的局域网局域网中的常用技术 9.2 局域网概述 罗伯特梅特卡夫个人简介 罗伯特梅特卡夫&#xff08;Robert Metcalfe&#xff0c;1…
最新文章