Spring Data JPA持久层中的一对一和一对多
目录
- `JPA` 中的一对一
- `JPA` 中的一对多
- 测试
- 一对一的添加测试
- 一对多的添加测试
- 查询测试
JPA
中的一对一
比如说一个学校有一个地址,一个地址对应的只有一个学校,Address
类
@Data
@Entity
@Table(name = "t_address")
public class Address {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Integer aid;private String province;private String city;private String area;private String phone;@OneToOne(cascade = CascadeType.ALL)private School school;
}
School
类
@Data
@Entity
@Table(name = "t_school")
public class School {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Integer sid;private String name;@OneToOne(cascade = CascadeType.ALL)private Address address;
}
如上的一对一的关系中,可以只在 School
类中维护,也可以只在 Address
类中维护,也可以两者都维护,具体哪种,那就看需求了。在 School
和 Address
类中都通过 @OneToOne
注解来维护了一对一的关系,cascade
用来配置级联操作,有如下取值
ALL
:所有操作PERSIST
:级联添加MERGE
:级联更新REMOVE
:级联删除REFRESH
:级联刷新
这样,最终创建出来的 t_school
表和 t_address
表中,会分别多出来一个字段 address_aid
和 school_sid
,这两个字段都是外键,正是通过外键,将两张表中不同的记录关联起来
有的人可能不习惯这种自动添加的字段,那也可以自定义该字段,反正该字段总是要有的,自定义的方式如下
@Data
@Entity
@Table(name = "t_address")
public class Address {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Integer aid;private String province;private String city;private String area;private String phone;@OneToOne(cascade = CascadeType.ALL)@JoinColumn(name = "sid",referencedColumnName = "sid")private School school;@Column(insertable = false,updatable = false)private Integer sid;
}
@Data
@Entity
@Table(name = "t_school")
public class School {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Integer sid;private String name;@OneToOne(cascade = CascadeType.ALL)@JoinColumn(name = "aid",referencedColumnName = "aid")private Address address;@Column(insertable = false,updatable = false)private Integer aid;
}
在 Address
中自定义一个 sid
,并设置该字段不可添加和修改,然后通过 @JoinColumn
注解去指定关联关系,@JoinColumn
注解中的 name
表示的是当前类中的属性名,referencedColumnName
表示的则是 School
类中对应的属性名
在 School
类中做相似的操作
JPA
中的一对多
一个班级中有多个学生,而一个学生只属于一个班级,我们可以这样来定义实体类
@Data
@Table(name = "t_student")
@Entity
public class Student {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Integer sid;private String name;@ManyToOne(cascade = CascadeType.ALL)private Clazz clazz;
}
@Data
@Table(name = "t_clazz")
@Entity
public class Clazz {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Integer cid;private String name;@OneToMany(cascade = CascadeType.ALL,fetch = FetchType.EAGER)private List<Student> students;
}
Student
和Clazz
的关系是多对一,用@ManyToOne
注解,Clazz
和Student
的关系是一对多,用@OneToMany
注解Student
和Clazz
的关系是多对一,将来的t_student
表中会多出来一个属性clazz_cid
,通过这个外键将Student
和Clazz
关联起来。如果我们不想要自动生成的clazz_cid
,那么也可以自定义,方式如下
@Data
@Table(name = "t_student")
@Entity
public class Student {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Integer sid;private String name;@ManyToOne(cascade = CascadeType.ALL)@JoinColumn(name = "cid")private Clazz clazz;@Column(insertable = false,updatable = false)private Integer cid;
}
- 定义一个
cid
属性,并设置为不可编辑和不可添加,然后通过@JoinColumn
注解配置cid
属性为外键 Clazz
和Student
的关系是一对多,这个是通过一个自动生成的第三张表来实现的,如下
测试
一对一的添加测试
public interface SchoolRepository extends JpaRepository<School,Integer> {}@SpringBootTest
public class JpaOneToOneApplicationTests {@AutowiredSchoolRepository schoolRepository;@Testvoid contextLoads() {School school = new School();school.setSid(1);school.setName("哈佛大学");Address address = new Address();address.setAid(1);address.setProvince("黑龙江");address.setCity("哈尔滨");address.setArea("某地");address.setPhone("123456");school.setAddress(address);schoolRepository.save(school);}
}
在这个测试过程中,关联关系是由 t_school
一方来维护的,因此将来填充的外键是 t_school
中的 aid
。添加结果如下图
这是一个简单的添加案例。更新也是调用 save()
方法,更新的时候会先判断这个 id
是否存在,存在的话就更新,不存在就添加
一对多的添加测试
public interface ClazzRepository extends JpaRepository<Clazz,Integer> {}@SpringBootTest
public class JpaOneToManyApplicationTests {@AutowiredClazzRepository clazzRepository;@Testvoid test02() {Clazz c = new Clazz();c.setCid(1);c.setName("三年级二班");List<Student> students = new ArrayList<>();Student s1 = new Student();s1.setSid(1);s1.setName("javaboy");students.add(s1);Student s2 = new Student();s2.setSid(2);s2.setName("张三");students.add(s2);c.setStudents(students);clazzRepository.save(c);}
}
注意,添加的是班级,所以班级和学生之间关系就由第三张表来维护,而不是由学生来维护
查询测试
再来一个简单的查询,假设我们现在想根据省份来搜索学校
public interface SchoolRepository extends JpaRepository<School,Integer> {List<School> findSchoolByAddressProvince(String province);
}@SpringBootTest
public class JpaApplicationTests {@AutowiredSchoolRepository schoolRepository;@Testvoid test01() {List<School> list = schoolRepository.findSchoolByAddressProvince("黑龙江");System.out.println("list = " + list);}
}
捋一下 Spring Data JPA
如何解析上面自定义的查询方法
- 首先截取掉
findSchoolByAddressProvince
的前缀,剩下AddressProvince
- 检查
School
是否有addressProvince
属性,有就按照该属性查询,对于我们的案例,并没有addressProvince
属性,所以继续下一步 - 从右侧驼峰开始拆分,拆掉第一个驼峰后面的内容,我们这里拆分之后只剩下
Address
了,判断School
是否存在Address
属性,不存在就继续重复该步骤,继续切掉右侧第一个驼峰 - 在上文案例中,
School
中有address
属性,所以接下来就去检查address
中是否有province
属性,因为我们这里只剩下一个province
了,如果剩下的字符串类似于provinceAaaBbb
这种,那么继续按照第三步去解析
上面这个写法有一个小小的风险,假设 School
中刚好就有一个属性叫做 addressProvince
,那么此时的分析就会出错。所以,对于上面的查询,我们也可以定义成如下方式
public interface SchoolRepository extends JpaRepository<School,Integer> {List<School> findSchoolByAddress_Province(String province);
}
此时就不会产生歧义了,系统就知道 province
是 address
的属性了。再来一个班级的查询,如下
public interface ClazzRepository extends JpaRepository<Clazz,Integer> {}@SpringBootTest
public class JpaApplicationTests {@AutowiredClazzRepository clazzRepository;@Testvoid test03() {List<Clazz> list = clazzRepository.findAll();System.out.println("list = " + list);}
}
如果在查询的过程中,需要对学生进行排序,可以添加如下属性
@Data
@Table(name = "t_clazz")
@Entity
public class Clazz {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Integer cid;private String name;@OneToMany(cascade = CascadeType.ALL,fetch = FetchType.EAGER)@OrderBy("sid desc")private List<Student> students;
}
通过 @OrderBy(“sid desc”)
可以设置查询的 student
排序
转载:https://blog.csdn.net/u012702547/article/details/123004809
Spring Data JPA持久层中的一对一和一对多相关推荐
- 关于spring data jpa 仓储层自动实现
Spring Data JPA: Spring提供的一个用于简化JPA开发的框架 Spring Data JPA不需要过多的关心Dao层的实现,只需关注我们继承的接口,按照一定的规则去编写我们的接口即 ...
- Spring Data JPA的持久层
1.概述 本文将重点介绍Spring 3.1,JPA和Spring Data的持久层的配置和实现. 有关使用基于Java的配置和项目的基本Maven pom设置Spring上下文的分步介绍,请参阅本文 ...
- Spring Data JPA 原理与实战第十一天 Session相关、CompletableFuture、LazyInitializationException
22 Session 的 open-in-view 对事务的影响是什么? 你好,欢迎来到第 22 讲,今天我们来学习 Session 的相关内容. 当我们使用 Spring Boot 加 JPA 的时 ...
- Spring Boot中使用Spring Data JPA示例
JPA是Java Persistence API的简称,是sun公司早期推出的Java持久层规范,目前实现JPA规范的主流框架有Hibernate.OpenJPA等.Hibernate框架是当前较为流 ...
- hql 查询关联对象_在spring data jpa中如何做报表统计查询?
问题描述 之前有个简单的报表统计需求,如果用sql的话是比较简单的,但是基于spring data jpa还没有遇到好的解决方案,折腾半天用spring data提供的几种方式都不能解决,spring ...
- Spring Data Jpa中的save和saveAndFlush方法
Spring Data Jpa中save和saveAndFlush的区别,首先直接看图: save是CurdRepository接口下的方法 saveAndFlush是JpaRepository接口下 ...
- 对Spring Data JPA中的page对象下的content属性里的实体类对象转换为dto对象
对Spring Data JPA中的page对象下的content属性里的实体类对象转换为dto对象. 刚开始试遍历content,进行转换,添加到新的list中,再set进去page.后来发现pag ...
- mysql jpa缓存,如何在Spring Data JPA CRUDRepository中添加缓存功能
I want to add "Cacheable" annotation in findOne method, and evict the cache when delete or ...
- Spring Boot 、Spring Data JPA、Hibernate集成
###什么是JPA JPA是用于管理Java EE 和Java SE环境中的持久化,以及对象/关系映射的JAVA API 最新规范为"JSR 338:Java Persistence 2.1 ...
- springdatajpa命名规则_简单了解下spring data jpa
公司准备搭建一个通用框架,以后项目就用统一一套框架了 以前只是听过jpa,但是没有实际用过 今天就来学习下一些简单的知识 什么是JPA 全称Java Persistence API,可以通过注解或者X ...
最新文章
- python selenium 文件上传_Python+Selenium学习--上传文件
- 自学python可以做什么兼职-一行生财:毕业100天,通过副业赚(挣)到我的第一个10w...
- nginx 学习笔记(6) nginx配置文件中的度量单位
- BLE 配对流程(转自襄坤在线)
- java char字符转编码_一、java基础-数据类型_数据类型转化_字符编码_转义字符
- 『中级篇』Docker Cloud自动构建 Docker image(55)
- Python在使用pip安装某个库时报错 Could not find a version that satisfies the requirement numpy
- MIT6.830 lab4 SimpleDB Transactions 实验报告
- BiLSTM+CRF命名实体识别:达观杯败走记(下篇)
- MATLAB 语言基础知识 矩阵和数组 从矩阵中删除行或列
- win10计算机的数字小键盘,Win10开机默认开启数字小键盘的方法
- datagrid的deleteRow使用
- python 读词向量文件
- Android WiFi only配置
- 刻意练习 Elasticsearch 10000 个小时,鬼知道经历了什么?!
- 点集拓扑学思维导图(附pdf源文档)
- 【C语言编程】简单密码
- 编程之路永无止境,想要与众不同你得这样做
- ESP01S CH340 一键下载电路设计
- W5500作为服务器突然断线
热门文章
- 算法:24.两两交换链表中的节点
- 易筋SpringBoot 2.1 | 第廿篇:SpringBoot的复杂JPA以及源码解析
- 计算机软件跨考教育学优点,2021教育学考研优势院校分析之:华南师范大学
- python字节码解析_简单入门python字节码混淆
- 四数之和 leetcode
- Fizz Buzz @leetcode Math
- JSTL简介以及简单示例
- linux的abrt目录满了,linux:abrt-cli list
- 2篇word文档比较重复率_【软件】PDF转word黑科技 快来get!
- module 'bit' not found:No LuaRocks module found for bit