如何使用JPA的@Formula注解?
背景描述
我们经常会在项目中用到一些数据字典,在存储和传输时使用Code,在前端展示时使用Name,这样做的好处是便于系统维护,比如项目中用到了"医院"这个名称,如果后期需求发生变化不叫"医院"了,改成"医疗机构",假如不使用数据字典,那么我们代码中、数据库中所有用到"医院"的地方都要修改,麻烦不说,漏掉一个就是一个小Bug。在处理这个Code/Name的转化的时候,我思考了几种处理方式,第一种,使用@ManyToOne注解关联字典查询,这样是最容易想到的方式,但是这种方式得到的结果是字典对象整体包含在查询到的实体中,我们所需要的只是字典里的name,所以我尝试寻找一种直接将字典表里的name映射到实体对象上的方式。第二种,使用HQL关联查询映射到自定义对象,这种方式可以达到我的预期,但是HQL写起来很麻烦,尤其是当需要关联查询的字典特别多的时候。并且我的项目中动态用的是JPA的Specification,如果使用这种方式,那么项目中的动态查询需要改写,也是不小的工作量。第三种,使用@Formula注解的方式,下面重点说说这种方式。
使用介绍
@Formula的作用是计算出一个临时的属性值,我们可以利用它,去关联查询其他表中的某个字段为对象的属性赋值,而这个属性是不持久化到数据库中的。
用代码描述一下会比较直观:
建立两个实体类
班级字典
@Data
@Entity
public class DictClass {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String classCode;//班级编号
private String className;//班级名称
}
学生类
@Data
@Entity
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String name; //名字
@Column(name = "CLASS_CODE")
private String classCode;//班级编号
@Formula("(select d.class_name from dict_class as d where d.class_code = class_code)")
private String className;//班级名称
}
@Formula("(select d.class_name from dict_class as d where d.class_code = class_code)")意思就是从数据库的dict_class表中查询到class_name字段的数据,赋值到className属性上。"="后面的class_code对应的时@Column里的class_code
持久层
public interface StudentRepo extends JpaRepository<Student, Long> {
//很持久
}
控制层
@RestController
@RequestMapping("/formula")
@Api(tags = "formula测试接口")
public class FormulaController {
@Autowired
StudentRepo studentRepo;
@GetMapping
public List<Student> findAll(){
return studentRepo.findAll();
}
}
测试一下,获取成功

注意事项
虽然看起来很简单,不过还是有好些个需要注意的地方,一言不合就失效。
1.网上好多人说@Formula必须用在属性上,其实不是的,@Formula 要与@Id注解同时用在属性上,或者同时用在在get方法上,否则@Formula失效。
2.如果查询中用到了where,那么需要给表起一个别名,否则@Formula失效。
3.@Formula与@Transient不能同时使用,否则@Formula失效。
4.使用@Formula注解的属性不需要在数据库表中建立与之对应的字段,并且即使建立了也没有作用,加上@Column注解也不行。
使用过程中遇到的坑
当持久层使用原生sql查询时,会造成NPE异常。
在持久层添加
@Query(nativeQuery = true,value = "select * from student")
List<Student> findByNative();
测试一下

这似乎是因为@Formula屏蔽了className字段,框架获取@Column对应的name时拿到null导致的,我未能找到具体原因,所以用起来还是很不随心,不知道大家是否有好的处理方案,欢迎指教!
如何使用JPA的@Formula注解?的更多相关文章
- Hibernate @Formula 注解方式
1.Formula的作用 Formula的作用就是用一个查询语句动态的生成一个类的属性 就是一条select count(*)...构成的虚拟列,而不是存储在数据库里的一个字段.用比较标准的说法就是: ...
- JPA学习(2)注解
上一篇学习了JPA的helloworld,也初略的使用了一些注解,接下来就细细的了解一下有哪些注解,和这些注解的作用 JPA的基本注解: ①@Entity,@Table,@Id,@GeneratedV ...
- 利用Eclipse的JPA自动生成注解实体
新公司用的SSH(springmvc)框架,看代码的时候,发现没有hbm.xml文件,全部使用的注解形式.在一次闲聊的时候问同事,这么多entity 写起来不麻烦么.同事说根据数据库自动生成的.于是 ...
- 使用JPA中@Query 注解实现update 操作
spring使用jpa进行update操作主要有两种方式: 1.调用保存实体的方法 1)保存一个实体:repository.save(T entity) 2)保存多个实体:repository.sav ...
- JPA之@GeneratedValue注解(转)
JPA的@GeneratedValue注解,在JPA中,@GeneratedValue注解存在的意义主要就是为一个实体生成一个唯一标识的主键(JPA要求每一个实体Entity,必须有且只有一个主键), ...
- 二十、springboot之jpa开发@MappedSuperclass 注解说明
@MappedSuperclass使用条件: 当我们进行开发项目时,我们经常会用到实体映射到数据库表的操作,此时我们经常会发现在我们需要映射的几个实体类中,有几个共同的属性,例如编号ID,创建者,创建 ...
- JPA之@GeneratedValue注解
JPA的@GeneratedValue注解,在JPA中,@GeneratedValue注解存在的意义主要就是为一个实体生成一个唯一标识的主键(JPA要求每一个实体Entity,必须有且只有一个主键), ...
- jpa和hibernate注解
http://www.objectdb.com/api/java/jpa/JoinColumns 用hibernate和jpa annotation 大概一年多了,今天闲来无事,对他们关联关系元数据写 ...
- JPA的事务注解@Transactional使用总结
在项目开发过程中,如果您的项目中使用了Spring的@Transactional注解,有时候会出现一些奇怪的问题,例如: 明明抛了异常却不回滚? 嵌套事务执行报错? ...等等 很多的问题都是没有全面 ...
随机推荐
- Github作为Maven仓库
新建发布构件项目 新建一个普通的maven项目,坐标为 创建一个类: 接着在pom文件中添加: <distributionManagement> <repository> &l ...
- Linux 上搭建 Snort+BASE 入侵检测系统
配置实验环境 由于本人电脑的存储空间不足,无法再承担安装一个虚拟机的开销,因此在阿里云上申请了一个云服务器进行本次实验.服务器配置如下: 1 核 - 2GB 内存 - 40GB 系统盘 操作系统:Ub ...
- linux进程管理相关命令
ps ps aux ps -ef | grep -E "supervisor|PPID" top 可以按一定规则对top的结果进行排序 # 监控单一进程 top -p pid ...
- C. Coffee Break 贪心 思维 有点难 有意思
C. Coffee Break 这个贪心之前好像写过,还是感觉挺难的,有点不会写. 这个题目大意是:给你一个数列n个元素,然后给你一天的时间,给你一个间隔时间d, 问你最少要用多少天可以把这个数列的所 ...
- uniapp自定义简单弹窗组件
2.0(2019-08-31) 船新版本的信息弹窗组件 插件市场地址:http://ext.dcloud.net.cn/plugin?id=672 可以弹出很多条信息,并单独控制消失时间.点击消失. ...
- 【Scala】什么是隐式转换?它又能用来干嘛?该怎么用
文章目录 定义 隐式参数 隐式转换 隐式值:给方法提供参数 隐式视图 将Int和Double类型转换为String 狗狗学技能(使用别的类中的方法) 使用规则 定义 隐式参数 隐式参数指在函数或者方法 ...
- 【Hadoop离线基础总结】MapReduce 社交粉丝数据分析 求出哪些人两两之间有共同好友,及他俩的共同好友都有谁?
MapReduce 社交粉丝数据分析 求出哪些人两两之间有共同好友,及他俩的共同好友都有谁? 用户及好友数据 A:B,C,D,F,E,O B:A,C,E,K C:F,A,D,I D:A,E,F,L E ...
- STM32 Bootloader基于ymodem传输协议串口IAP升级详解
硬件:stm32f103cbt6 软件:STM32F10x_StdPeriph_Lib_V3.5.0 文章目录 1 预备知识 2 Bootloader 2.1 启动流程 2.2 校验跳转地址是否有效 ...
- 【HDU4990】递推式
题目大意:给定序列 1, 2, 5, 10, 21, 42, 85, 170, 341 …… 求第n项 模 m的结果 递推式 f[i] = f[i - 2] + 2 ^ (i - 1); 方法一: ...
- PMS学习
一,PMS的adb相关重要指令 1,adb shell dumpsys package(dump所有的系统内apk信息) 2,adb shell dumpsys package “com.androi ...