Mybatis存储数据将数据转为json

news2024/11/20 8:29:10

第一种方法

  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.coloradmin.cn/o/1657169.html

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

相关文章

在数据分析中所需要运用到的概率论知识

数据分析 前言一、总体二、样本三、统计抽样抽取的基本准则 四、随机抽样抽签法随机数法 五、分层抽样六、整群抽样七、系统抽样八、统计参数常用的分布函数参数 九、样本统计量十、样本均值和样本方差十一、描述样本集中位置的统计量样本均值样本中位数样本众数 十二、描述样本…

计算机发展史故事【5】

电脑创世纪 全世界在隆隆的炮火声中迎来了1943 年。硝烟密布&#xff0c;战鼓催春&#xff0c;战争的迫切需要&#xff0c;像一只有力的巨手&#xff0c;为电脑的诞生扫清障碍&#xff0c;铺平道路。 4 月9 日&#xff0c;美国马里兰州阿贝丁&#xff0c;陆军军械部召集的一次会…

深度学习论文代码研读系列(1)Transformer:Attention Is All You Need

目录 摘要 1 引言 2背景 3模型架构 3.1编码器和解码器堆栈编码器&#xff1a; 3.2 Attention 3.2.1 Scaled Dot-Product Attention 3.2.2多头注意力 3.2.3注意力在我们的模型中的应用 3.3位置前馈网络 3.4嵌入和Softmax 3.5位置编码 4为什么自注意力 5 Training 6…

小红书释放被封手机号 无限注册

前几年抖音也可以释放被封手机号 那时候都不重视 导致现在被封手机号想释放 基本不可能的 或者就是最少几百块 有专业的人帮你通过某些信息差释放 本教程是拆解 小红书被封手机号怎么释放&#xff0c;从今年开始&#xff0c;被封的手机号无法注销了 所以很困扰 那么本教程来…

AI绘画Stable Diffusion 插件篇:智能标签提示词插件sd-danbooru-tags-upsampler

大家好&#xff0c;我是向阳。 关于智能标签提示词插件&#xff0c;在很早之前就介绍过很多款了&#xff0c;今天再给大家介绍一款智能标签提示词插件sd-danbooru-tags-upsampler。该智能提示词插件是今年2月23号才发布的第一版V0.1.0&#xff0c;算是比较新的智能提示词插件。…

Semi-decentralized Federated Ego Graph Learning for Recommendation

论文概况 本文是2023年WWW的一篇联邦推荐论文&#xff0c;提出了一个半去中心化的联合自我图学习框架。 Introduction 作者提出问题 现有的推荐方法收集所有用户的自我图来组成一个全局图&#xff0c;导致隐私风险。联合推荐系统已被提出来缓解隐私问题&#xff0c;但在客户…

【半夜学习MySQL】数据库概念详解探索数据库到底是如何存储的?

&#x1f3e0;关于专栏&#xff1a;半夜学习MySQL专栏用于记录MySQL数据相关内容。 &#x1f3af;每天努力一点点&#xff0c;技术变化看得见 文章目录 什么是数据库主流数据库与数据库分类数据库的基本使用数据库的启动及关闭查看配置文件与数据库存储位置连接数据库服务器服务…

Linux进程——Linux环境变量

前言&#xff1a;在结束完上一篇的命令行参数时&#xff0c;我们简单的了解了一下Linux中的环境变量PATH&#xff0c;而环境变量不只有PATH&#xff0c;关于更多环境变量的知识我们将在本篇展开&#xff01; 本篇主要内容&#xff1a; 常见的环境变量 获取环境变量的三种方式 本…

[性能优化] ScrollView视图优化为循环列表

问题描述&#xff1a; 原先商城的物品栏中的item 是load在一个scrollView 下&#xff0c;用于滑动查看。仅仅在父级panel下是使用了NGUI原生的scrollview 组件&#xff0c;随着商场物品列表中新物品的增多。panel下加载的实例也非常庞大。而大部分的实例用户也无法看到&#x…

YOLOv5,YOLOv7改进之结合​SOCA

1.SOCA moudle结构图 2,YOLOv5,YOLOv7改进之结合​SOCA 1.配置common.py文件 #SOCA moudle 单幅图像超分辨率 class Covpool(Function):@staticmethoddef forward(ctx, input):x = inputbatchSize = x.data.shape[0]dim = x.data.shape[1]h = x.data.shape[2]w = x.data.sha…

上位机图像处理和嵌入式模块部署(树莓派4b和c++新版本的问题)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 自己读书的时候是03年&#xff0c;学习c也是差不多04年开始&#xff0c;到现在基本上20年了。这20年过程当中&#xff0c;其实c的语言版本一直是在…

队列 (Queue)

今日励志语句&#xff1a;别总听悲伤的歌&#xff0c;别总想从前的事&#xff0c;别让过去拖住脚&#xff0c;别让未来被辜负。 前言&#xff1a;前面写了一篇 栈的实现&#xff0c;接下来学习一下它的"兄弟" 一、队列的概念&#xff1a; 队列&#xff1a; 也是数据…

nginx代理原理(端口复用)探究

前言&#xff1a;对于一些常用的插件&#xff0c;我们应该学会如何使用。同时&#xff0c;其实现原理也要进行深究&#xff0c;可以为其他的项目开发做借鉴。 探究方案&#xff1a; 一、发布两个不同的服务&#xff0c;这两个服务的端口不致 二、配置nginx&#xff0c;让这两…

JavaScript百炼成仙自学笔记——13

函数七重关之六&#xff08;“new”一个函数&#xff09; 看个代码&#xff1a; function hello(){console.log(this); } 1、this&#xff1a;也是JavaScript中的一个关键字&#xff0c;永远指向当前函数的调用者 解释一下,有两层意思&#xff1a; ①this要嘛不出现&#…

从心理学角度看,GPT 对人有什么影响?

开启个性化AI体验&#xff1a;深入了解GPT的无限可能 导言 GPT 与我们日常生活的融合标志着技术进步的重大飞跃&#xff0c;为提高效率和创新提供了前所未有的机遇。然而&#xff0c;当我们与这些智能系统日益紧密地交织在一起时&#xff0c;探索它们对个人产生的细微的心理影响…

康姿百德集团公司官网价格统一,产品编码可查真伪售后有保障

康姿百德床垫&#xff0c;静音设计让你享受安静睡眠环境 随着越来越多的人睡眠质量差&#xff0c;夜间难以入睡&#xff0c;人们开始意识到睡眠问题已经不仅仅是健康问题&#xff0c;更上升为一种社会问题&#xff0c;急需得到解决。作为寝具行业中的优质品牌&#xff0c;康姿…

【Linux】如何定位客户端程序的问题

文章目录 1 客户端程序和服务端程序的差别2 问题类型2.1 崩溃(crash)2.2 CPU高2.3 内存高2.4 线程卡死 3 总结 1 客户端程序和服务端程序的差别 客户端程序是运行在终端上&#xff0c;通常都会与业务系统共存&#xff0c;而服务端程序通常会运行在单独的节点上&#xff0c;或者…

Leetcode—394. 字符串解码【中等】

2024每日刷题&#xff08;131&#xff09; Leetcode—394. 字符串解码 实现代码 class Solution { public:string decodeString(string s) {string curstr;int curNum 0;stack<pair<string, int>> st; for(char c: s) {if(isdigit(c)) {curNum curNum * 10 (c…

污水处理设备集中管理

在环境保护日益成为社会发展重中之重的今天&#xff0c;污水处理设备的有效管理显得尤为关键。传统的管理方式往往存在效率低下、响应不及时等问题&#xff0c;难以满足现代污水处理的需求。而HiWoo Cloud平台的污水处理设备集中管理系统&#xff0c;以其高效、智能的特点&…