背景描述

我们经常会在项目中用到一些数据字典,在存储和传输时使用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注解?的更多相关文章

  1. Hibernate @Formula 注解方式

    1.Formula的作用 Formula的作用就是用一个查询语句动态的生成一个类的属性 就是一条select count(*)...构成的虚拟列,而不是存储在数据库里的一个字段.用比较标准的说法就是: ...

  2. JPA学习(2)注解

    上一篇学习了JPA的helloworld,也初略的使用了一些注解,接下来就细细的了解一下有哪些注解,和这些注解的作用 JPA的基本注解: ①@Entity,@Table,@Id,@GeneratedV ...

  3. 利用Eclipse的JPA自动生成注解实体

    新公司用的SSH(springmvc)框架,看代码的时候,发现没有hbm.xml文件,全部使用的注解形式.在一次闲聊的时候问同事,这么多entity  写起来不麻烦么.同事说根据数据库自动生成的.于是 ...

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

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

  5. JPA之@GeneratedValue注解(转)

    JPA的@GeneratedValue注解,在JPA中,@GeneratedValue注解存在的意义主要就是为一个实体生成一个唯一标识的主键(JPA要求每一个实体Entity,必须有且只有一个主键), ...

  6. 二十、springboot之jpa开发@MappedSuperclass 注解说明

    @MappedSuperclass使用条件: 当我们进行开发项目时,我们经常会用到实体映射到数据库表的操作,此时我们经常会发现在我们需要映射的几个实体类中,有几个共同的属性,例如编号ID,创建者,创建 ...

  7. JPA之@GeneratedValue注解

    JPA的@GeneratedValue注解,在JPA中,@GeneratedValue注解存在的意义主要就是为一个实体生成一个唯一标识的主键(JPA要求每一个实体Entity,必须有且只有一个主键), ...

  8. jpa和hibernate注解

    http://www.objectdb.com/api/java/jpa/JoinColumns 用hibernate和jpa annotation 大概一年多了,今天闲来无事,对他们关联关系元数据写 ...

  9. JPA的事务注解@Transactional使用总结

    在项目开发过程中,如果您的项目中使用了Spring的@Transactional注解,有时候会出现一些奇怪的问题,例如: 明明抛了异常却不回滚? 嵌套事务执行报错? ...等等 很多的问题都是没有全面 ...

随机推荐

  1. Github作为Maven仓库

    新建发布构件项目 新建一个普通的maven项目,坐标为 创建一个类: 接着在pom文件中添加: <distributionManagement> <repository> &l ...

  2. Linux 上搭建 Snort+BASE 入侵检测系统

    配置实验环境 由于本人电脑的存储空间不足,无法再承担安装一个虚拟机的开销,因此在阿里云上申请了一个云服务器进行本次实验.服务器配置如下: 1 核 - 2GB 内存 - 40GB 系统盘 操作系统:Ub ...

  3. linux进程管理相关命令

    ps ps aux ps -ef | grep -E "supervisor|PPID"  top 可以按一定规则对top的结果进行排序 # 监控单一进程 top -p pid  ...

  4. C. Coffee Break 贪心 思维 有点难 有意思

    C. Coffee Break 这个贪心之前好像写过,还是感觉挺难的,有点不会写. 这个题目大意是:给你一个数列n个元素,然后给你一天的时间,给你一个间隔时间d, 问你最少要用多少天可以把这个数列的所 ...

  5. uniapp自定义简单弹窗组件

    2.0(2019-08-31) 船新版本的信息弹窗组件 插件市场地址:http://ext.dcloud.net.cn/plugin?id=672 可以弹出很多条信息,并单独控制消失时间.点击消失. ...

  6. 【Scala】什么是隐式转换?它又能用来干嘛?该怎么用

    文章目录 定义 隐式参数 隐式转换 隐式值:给方法提供参数 隐式视图 将Int和Double类型转换为String 狗狗学技能(使用别的类中的方法) 使用规则 定义 隐式参数 隐式参数指在函数或者方法 ...

  7. 【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 ...

  8. STM32 Bootloader基于ymodem传输协议串口IAP升级详解

    硬件:stm32f103cbt6 软件:STM32F10x_StdPeriph_Lib_V3.5.0 文章目录 1 预备知识 2 Bootloader 2.1 启动流程 2.2 校验跳转地址是否有效 ...

  9. 【HDU4990】递推式

    题目大意:给定序列 1, 2, 5, 10, 21, 42, 85, 170, 341 …… 求第n项 模 m的结果 递推式 f[i]  = f[i - 2] + 2 ^ (i - 1); 方法一:  ...

  10. PMS学习

    一,PMS的adb相关重要指令 1,adb shell dumpsys package(dump所有的系统内apk信息) 2,adb shell dumpsys package “com.androi ...