如果要实现实体类中属性的类型和数据库表中字段的类型相互转化,则需要使用 @Convert 注解

package javax.persistence;

import java.lang.annotation.Repeatable;
import java.lang.annotation.Target;
import java.lang.annotation.Retention;
import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.RetentionPolicy.RUNTIME; @Repeatable(Converts.class)
@Target({METHOD, FIELD, TYPE})
@Retention(RUNTIME)
public @interface Convert { /**
* 指定要使用的转换器
*/
Class converter() default void.class; /**
* 当注解 Convert 应用在基本类型的属性或基本类型的元素集合上,不能指定attributeName元素。
*/
String attributeName() default ""; /**
* 用于禁用自动应用或继承的转换器。如果 disableConversion 为真,则不应指定converter元素
*/
boolean disableConversion() default false;
}

由 Convert 源码可知:使用 @Convert 注解需要一个转换器,

自定义转换器需要实现 AttributeConverter 接口

1、AttributeConverter 接口

package javax.persistence;

/**
*
* 把实体类中属性的类型与数据库表中字段的类型相互转换.
*
* @param <X> 实体类中的属性类型
* @param <Y> 数据库表中的字段类型
*/
public interface AttributeConverter<X,Y> { /**
* 实体类中属性的类型转换为数据库表中字段的类型
*
* @param 实体类中属性的类型
* @return 数据库表中字段的类型
*
*/
public Y convertToDatabaseColumn (X attribute); /**
* 数据库表中字段的类型转换为实体类中属性的类型
*
* @param 数据库表中字段的类型
* @return 实体类中属性的类型
*
*/
public X convertToEntityAttribute (Y dbData);
}

2、自定义的实现类

package com.chayiges;

import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
import java.time.YearMonth; /**
* 使用 JPA 将 YearMonth 持久化为整数
*
* @author chayiges
*/
// 标识该类是转换器
@Converter
public class YearMonthIntegerAttributeConverter
implements AttributeConverter<YearMonth, Integer> { /**
* 实体类 -> 数据库
* 向数据库中保存时调用
*/
@Override
public Integer convertToDatabaseColumn(YearMonth attribute) {
if (attribute != null) {
return (attribute.getYear() * 100) + attribute.getMonth().getValue();
}
return null;
} /**
* 数据库 -> 实体类
* 向数据库中查询时调用
*/
@Override
public YearMonth convertToEntityAttribute(Integer dbData) {
if (dbData != null) {
int year = dbData / 100;
int month = dbData % 100;
return YearMonth.of(year, month);
}
return null;
}
}

1.2、创建数据库对应的实体类

package com.chayiges;

import jp.co.isid.cas3.commons.api.jpa.AbstractAggregateRoot;
import jp.co.isid.cas3.onecas.core.YearMonthIntegerAttributeConverter;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor; import javax.persistence.Column;
import javax.persistence.Convert;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.Table;
import java.io.Serializable;
import java.time.YearMonth;
import java.util.UUID; /**
* 学生表对应的实体类
*
* @author chayiges
*/
@Entity
@Getter
@Table
@NoArgsConstructor(access = AccessLevel.PROTECTED, force = true)
@AllArgsConstructor
public class Student extends AbstractAggregateRoot<Student, UUID> implements Serializable { /** ID */
@EmbeddedId
private UUID id; /** 姓名 */
@Column(name = "user_name", length = 100, nullable = false)
private String userName; /** 年月 */
@Convert(converter = YearMonthIntegerAttributeConverter.class)
@Column(name = "year_month")
private YearMonth yearMonth; }

1.3、创建 jpa 查询

package com.chayiges;

import org.springframework.data.jpa.repository.JpaRepository;

import java.time.YearMonth;
import java.util.UUID; /**
* 学生表的jap查询
*
* @author chayiges
*/
public interface Students extends JpaRepository<Student, UUID> { /**
* 根据年月查询学生表
* @param yearMonth 年月
* @return 学生表
*/
List<Student> findByYearMonth(YearMonth yearMonth); }

1.4、测试

package jp.chayiges;

import lombok.RequiredArgsConstructor;
import org.junit.jupiter.api.Test; import java.time.YearMonth;
import java.util.UUID;
import java.util.List; /**
* jap查询测试
*
* @author chayiges
*/
@RequiredArgsConstructor
public class StudentJPAUnitTests { /** 实体类到数据库表的转换器 */
final YearMonthIntegerAttributeConverterauto yearMonthIntegerAttributeConverterauto; /** 学生表 jpa */
final Students students;   /**
* テスト
*/
@Test
void findByYearMonthTest() { YearMonth yearMonth = YearMonth.of(2022, 7);
// 创建学生对象
Student stu = new Student("a57988c3-1711-4288-9623-9e7c177ff078",
"孙汐", yearMonth);
// 调用 jpa 方法进行保存,保存的时候会进入自定义的Convert实现类中进行实体类属性值到数据
// 库中对应字段值的转换
this.students.save(stu); // 调用 jpa 方法查询
List<Student> studentList = this.students.findByYearMonth(yearMonth); }
}

1.5、创建了错误的 jpa 方法

package com.chayiges;

import org.springframework.data.jpa.repository.JpaRepository;

import java.time.YearMonth;
import java.util.UUID; /**
* 学生表的jap查询
*
* @author chayiges
*/
public interface Students extends JpaRepository<Student, UUID> { /**
* 根据年月查询学生表
* @param yearMonth 年月
* @return 学生表
*/
List<Student> findByYearMonth(Integer integer); }

1.6、错误的 jpa 方法的测试

package jp.chayiges;

import lombok.RequiredArgsConstructor;
import org.junit.jupiter.api.Test; import java.time.YearMonth;
import java.util.UUID;
import java.util.List; /**
* jap查询测试
*
* @author chayiges
*/
@RequiredArgsConstructor
public class StudentJPAUnitTests { /** 实体类到数据库表的转换器 */
final YearMonthIntegerAttributeConverterauto yearMonthIntegerAttributeConverterauto; /** 学生表jpa */
final Students students; /**
* テスト
*/
@Test
void findByYearMonthTest() { YearMonth yearMonth = YearMonth.of(2022, 7);
// 创建学生对象
Student stu = new Student("a57988c3-1711-4288-9623-9e7c177ff078",
"孙汐", yearMonth);
// 调用 jpa 方法进行保存,保存的时候会进入自定义的Convert实现类中进行实体类属性值到数据
// 库中对应字段值的转换
this.students.save(stu); // 调用 jpa 方法查询,会抛出 InvalidDataAccessApiUsageException 异常
List<Student> studentList = this.students.findByYearMonth(this
.yearMonthIntegerAttributeConverterauto
.convertToDatabaseColumn(yearmonth));
}
}

注意:此处查询年月的时候用的是实体类中 YearMonth 类型,并不是转换到数据库中的 Integer 类型

至于数据保存到数据库中确实是 Integer 类型,但是查询的时候依然要使用实体类中属性的类型这个问题,本人也不知其中缘由,有懂的大佬麻烦指出

对应到本人CSDN的博客

@Convert 注解在jpa中进行查询的注意事项的更多相关文章

  1. JPA 中注解的作用

    JPA全称Java Persistence API.JPA通过JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中.        JPA由EJB 3.0软件专家 ...

  2. 使用JPA中@Query 注解实现update 操作

    spring使用jpa进行update操作主要有两种方式: 1.调用保存实体的方法 1)保存一个实体:repository.save(T entity) 2)保存多个实体:repository.sav ...

  3. JPA中EntityListeners注解的使用

    使用场景 EntityListeners在jpa中使用,如果你是mybatis是不可以用的 它的意义 对实体属性变化的跟踪,它提供了保存前,保存后,更新前,更新后,删除前,删除后等状态,就像是拦截器一 ...

  4. Spring data JPA中使用Specifications动态构建查询

    有时我们在查询某个实体的时候,给定的条件是不固定的,这是我们就需要动态 构建相应的查询语句,在JPA2.0中我们可以通过Criteria接口查询,JPA criteria查询.相比JPQL,其优势是类 ...

  5. Spring Data JPA中的动态查询 时间日期

    功能:Spring Data JPA中的动态查询 实现日期查询 页面对应的dto类private String modifiedDate; //实体类 @LastModifiedDate protec ...

  6. spring boot JPA中实体类常用注解

    spring boot jpa中的注解很多,参数也比较多.没必要全部记住,但是经常查看官方文档也比较麻烦,记录一下一些常用的注解.通过一些具体的例子来帮助记忆. @Entity @Table(name ...

  7. 【hql】spring data jpa中 @Query使用hql查询 问题

    spring data jpa中 @Query使用hql查询 问题 使用hql查询, 1.from后面跟的是实体类 不是数据表名 2.字段应该用实体类中的字段 而不是数据表中的属性 实体如下 hql使 ...

  8. jpa中使用Query判断条件查询

    jpa中使用Query判断条件查询 @Query(value = " select m.* from mining_area as m " + " where 1 = 1 ...

  9. JPA中建立数据库表和实体间映射小结

    在JPA中,映射数据库表和实体的时候,需要注意一些细节如下, 实体类要用@Entity的注解: 要用 @Id 来注解一个主键: 如果跟数据库相关联,要用@Table注解相关数据库表: 实体类中字段需要 ...

随机推荐

  1. 批量上传文件或者上传大文件时 gateWay报错DataBufferLimitException: Exceeded limit on max bytes to buffer : 262144

    一.描述 最近在批量上传文件时网关出现了异常,后面发现上传大文件也会出现文件超过256发生异常,异常信息如下: org.springframework.core.io.buffer.DataBuffe ...

  2. django的下载安装,目录结构的介绍,简单的django应用

    1.django的下载安装 pip3 install django==1.11.9 2.django的创建 1.在windows的cmd窗口下 1.1创建django项目 django-admin s ...

  3. 论文解读(GMIM)《Deep Graph Clustering via Mutual Information Maximization and Mixture Model》

    论文信息 论文标题:Deep Graph Clustering via Mutual Information Maximization and Mixture Model论文作者:Maedeh Ahm ...

  4. 嵌入:CAN

    说下我的学习过程.刚到公司的时候我根本不知道什么是CAN,甚至连以太网和串口通讯都不懂.领导把USBCAN分析仪拿给我,把铜线短接上,用软件在CAN1窗口点下发送,CAN2窗口马上接收到了发送出来的数 ...

  5. 118_Power Pivo周维度度同比、环比相关

    博客:www.jiaopengzi.com 焦棚子的文章目录 请点击下载附件 一.背景 在群里看到有人在交流周维度同环比,同时又好多天都没有更新文章了,最近没有什么好的素材,就硬生生的写一个吧. 先来 ...

  6. 理解RESTful Api设计

    REST REST(REpresentational State Transfer)是 Roy Fielding 博士于 2000 年在他的博士论文中提出来的一种软件架构风格(一组架构约束条件和原则) ...

  7. 类型转换——JavaSE基础

    类型转换 类型判断 可以通过Instanceof关键字判断左操作数是否是右操作数的父类或本身 强制类型转换 不能对布尔值进行转换 不能将对象类型转换为不相关的类型 把高容量转向低容量时,需要进行强制类 ...

  8. React简单教程-6-单元测试

    前言 我想大部分人的前端测试,都是运行项目,直接在浏览器上操作,看看功能正不正常.虽然明明有测试库可以使用,但是因为"要快"的原因,让好好做测试变成了一件影响效率的事. 因为这种无 ...

  9. numpy中shape的部分解释

    转载自:https://blog.csdn.net/qq_28618765/article/details/78081959和https://www.jianshu.com/p/e083512e4f4 ...

  10. C语言- 基础数据结构和算法 - 09 栈的应用_中缀表达式转后缀表达式20220611

    09 栈的应用_中缀表达式转后缀表达式20220611 听黑马程序员教程<基础数据结构和算法 (C版本)>, 照着老师所讲抄的, 视频地址https://www.bilibili.com/ ...