Spring JPA的实体属性类型转换器并反序列化工具类详解

目录
  • 一、JPA单体JSON与Map的映射
    • 创建一个转换类
    • 只需在模型类上加个注解就能完成自动转换
  • 二、封装反序列化工具类
    • 利用JPA的AttributeConverter接口实现属性转换过于局限
    • 如何调用自定义的转换器

一、JPA 单体JSON与Map的映射

数据库中test字段为json类型

{"key": "颜色", "value": "深白色", "key_id": 1, "value_id": 3}

模型中test字段为Map类型

private Map<String,Object> test;

问题:如何将数据库字段的值映射到模型中,要用到JPA的属性转换

创建一个转换类

实现AttributeConverter接口

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.lin.missyou.exception.http.ServerErrorException;
import org.springframework.beans.factory.annotation.Autowired;
import javax.persistence.AttributeConverter;
import javax.persistence.Convert;
import javax.persistence.Converter;
import java.util.HashMap;
import java.util.Map;
// 第一个泛型类型就是  entity字段的类型
// json没有类型,对应在JAVA中就是String类型
// 第二个泛型类型就是  数据库字段的类型
@Converter
public class MapAndJson implements AttributeConverter<Map<String, Object>, String> {
    /*
    ObjectMapper类是Jackson库的主要类,它提供一些功能将数据集或对象转换的实现。
    它将使用JsonParser和JsonGenerator实例来实现JSON的实际读/写。
    */
    @Autowired
    private ObjectMapper mapper;
    @Override
    public String convertToDatabaseColumn(Map<String, Object> map) {
        try {
            return mapper.writeValueAsString(map);
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServerErrorException(99999);
        }
    }
    @Override
    @SuppressWarnings("unchecked")
    public Map<String, Object> convertToEntityAttribute(String s) {
        try {
        	if (s == null) return null;
            return mapper.readValue(s, HashMap.class);
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServerErrorException(9999);
        }
    }
}

看到接口的方法名,就知道能做什么了。

具体转换需要自己实现,调用SpringBoot提供的Jackson的内置库。

ObjectMapper类是Jackson库的主要类,它提供一些功能将数据集或对象转换的实现。

在类上打上注解@Converter,做为转换类的标识。

只需在模型类上加个注解就能完成自动转换

指明转换类

@Convert(converter = MapAndJson.class)
private Map<String,Object> test;

其他类型转换的操作基本一致,只需要修改类型等局部代码。

二、封装反序列化工具类

数据库中specs字段为json类型

[{"key": "颜色", "value": "深白色", "key_id": 1, "value_id": 3}, {"key": "尺寸", "value": "4.3英寸", "key_id": 2, "value_id": 7}]

模型中specs字段为String类型

建立Spec实体类

@Getter
@Setter
public class Spec {
    private Long keyId;
    private String key;
    private Long valueId;
    private String value;
}

利用JPA的AttributeConverter接口实现属性转换过于局限

模仿JPA的AttributeConverter接口封装两个方法。

希望转换为实体类的本类型,因为默认将json数据转换为LinkHashMap类型。

通用的转换类,转换为本类。

//反序列化工具类
@Component
public class GenericAndJson {
    private static ObjectMapper mapper;
//将ObjectMapper注入到方法里,再通过方法赋值到成员变量上
    @Autowired
    public void setMapper(ObjectMapper mapper) {
        GenericAndJson.mapper = mapper;
    }
    public static <T> String objectToJson(T o) {
        try {
            return GenericAndJson.mapper.writeValueAsString(o);
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServerErrorException(99999);
        }
    }
    public static <T> T jsonToObject(String s, TypeReference<T> typeReference) {
        if (s == null) return null;
        try {
            return GenericAndJson.mapper.readValue(s, typeReference);
        } catch (Exception e) {
            e.printStackTrace();
            throw new ServerErrorException(9999);
        }
    }
}

如何调用自定义的转换器

在实体类中,可以通过重写getter、setter方法,自己实现想要转换的数据结构(List),本且能够得到本类(Spec)。

private String specs;
public List<Spec> getSpecs() {
    if (specs == null) return Collections.emptyList();
    return GenericAndJson.jsonToObject(this.specs, new TypeReference<List<Spec>>() {});
}
public void setSpecs(List<Spec> specs) {
    if (specs.isEmpty()) return;
    this.specs = GenericAndJson.objectToJson(specs);
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 使用JPA自定义VO类型转换(EntityUtils工具类)

    目录 JPA自定义VO类型转换(EntityUtils工具类) dto,vo,po,bo等实体转换工具类 下面宣布这次的主角:dozer JPA自定义VO类型转换(EntityUtils工具类) 在JPA查询中,如果需要返回自定义的类,可以使用EntityUtils工具类,该类源码: import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.lang.reflect.Constructor; import java.

  • SpringBoot中时间类型 序列化、反序列化、格式处理示例代码

    [SpringBoot] 中时间类型 序列化.反序列化.格式处理 Date yml全局配置 spring: jackson: time-zone: GMT+8 date-format: yyyy-MM-dd HH:mm:ss #配置POST请求Body中Date时间类型序列化格式处理,并返回 请求参数类型转换 /** * 时间Date转换 * 配置GET请求,Query查询Date时间类型参数转换 */ @Component public class DateConverter implemen

  • spring data jpa 查询自定义字段,转换为自定义实体方式

    目标:查询数据库中的字段,然后转换成 JSON 格式的数据,返回前台. 环境:idea 2016.3.4, jdk 1.8, mysql 5.6, spring-boot 1.5.2 背景:首先建立 entity 映射数据库(非专业 java 不知道这怎么说) @Entity @Table(name = "user") public class User { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Long

  • Spring JPA的实体属性类型转换器并反序列化工具类详解

    目录 一.JPA单体JSON与Map的映射 创建一个转换类 只需在模型类上加个注解就能完成自动转换 二.封装反序列化工具类 利用JPA的AttributeConverter接口实现属性转换过于局限 如何调用自定义的转换器 一.JPA 单体JSON与Map的映射 数据库中test字段为json类型 {"key": "颜色", "value": "深白色", "key_id": 1, "value_i

  • Spring框架JavaMailSender发送邮件工具类详解

    本文实例为大家分享了Spring框架JavaMailSender发送邮件工具类,供大家参考,具体内容如下 需要用到的jar包: 下面是发送工具类代码: package com.test.email; import org.springframework.core.io.FileSystemResource; import org.springframework.mail.SimpleMailMessage; import org.springframework.mail.javamail.Jav

  • Spring中属性文件properties的读取与使用详解

    Spring中属性文件properties的读取与使用详解 实际项目中,通常将一些可配置的定制信息放到属性文件中(如数据库连接信息,邮件发送配置信息等),便于统一配置管理.例中将需配置的属性信息放在属性文件/WEB-INF/configInfo.properties中. 其中部分配置信息(邮件发送相关): #邮件发送的相关配置 email.host = smtp.163.com email.port = xxx email.username = xxx email.password = xxx

  • Spring中bean的初始化和销毁几种实现方式详解

    Bean的生命周期 : 创建bean对象 – 属性赋值 – 初始化方法调用前的操作 – 初始化方法 – 初始化方法调用后的操作 – --- 销毁前操作 – 销毁方法的调用. [1]init-method和destroy-method 自定义初始化方法和销毁方法两种方式:xml配置和注解. ① xml配置 <bean id="person" class="com.core.Person" scope="singleton" init-meth

  • Spring处理@Async导致的循环依赖失败问题的方案详解

    目录 简介 问题复现 原因分析 解决方案 方案1:懒加载 方案2:不让@Async的类有循环依赖 方案3:allowRawInjectionDespiteWrapping设置为true 为什么@Transactional不会导致失败 简介 说明 本文介绍SpringBoot中的@Async导致循环依赖失败的原因及其解决方案. 概述 我们知道,Spring解决了循环依赖问题,但Spring的异步(@Async)会使得循环依赖失败.本文将用实例来介绍其原因和解决方案. 问题复现 启动类 启动类添加@

  • C# 6.0的属性(Property)的语法与初始值详解

    昨晚有学点新知识,是有关C# 6.0的. 在数据库创建有一张表: CREATE TABLE [dbo].[ToolLocation] ( [ToolLocation_nbr] SMALLINT IDENTITY(1,1) NOT NULL PRIMARY KEY, [LocationName] NVARCHAR(20) NOT NULL, [Description] NVARCHAR(50) NULL, [IsActive] BIT NOT NULL DEFAULT(1) ) GO Source

  • Spring Boot 定制与优化内置的Tomcat容器实例详解

    1.Spring Boot 定制与优化内置Tomcat容器. > 内置的容器有三个分别是Undertow.Jetty.Tomcat,Spring Boot 对这三个容器分别进行了实现,它们上层接口都是EmbeddedServletContainerFactory,该接口也是本文的主要核心. 对于内置容器的定制与优化主要有两种方式,第一种方式是通过配置文件来配置,另外一种是通过码代码的方式.接下来主要对上述两种方式进行实现. 2.通过配置文件来定制与优化Tomcat > 配置的核心内容参考org

  • Java Spring循环依赖原理与bean的生命周期图文案例详解

    前言 Spring是如何处理循环依赖的,又是怎么做到,互相注入对方的proxy bean而不是raw bean的?现在就分析一下 一.循环依赖是什么 Spring中放入两个Service,分别是C1和C2,然后C1和C2又互为对方的成员变量.这种情况C1和C2就可以说是相互循环依赖了 二.源码图解 1. bean的主要生命周期图解 上图是一个没有循坏依赖的bean的主要生命周期节点,下图的循坏依赖可以结合该图解一起看 2.循环依赖图解 可以看到里面有一个很重要的逻辑: 当一个bean经过所有的步

  • 在Spring Boot应用程序中使用Apache Kafka的方法步骤详解

    第1步:生成我们的项目: Spring Initializr来生成我们的项目.我们的项目将提供Spring MVC / Web支持和Apache Kafka支持. 第2步:发布/读取Kafka主题中的消息: <b>public</b> <b>class</b> User { <b>private</b> String name; <b>private</b> <b>int</b> age

  • Vue 使用Props属性实现父子组件的动态传值详解

    如下所示: <!DOCTYPE html> <html lang="en" xmlns:v-on="http://www.w3.org/1999/xhtml"> <head> <meta charset="UTF-8"> <title>Title</title> <script src="https://cdn.jsdelivr.net/npm/vue&quo

随机推荐