成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Jpa 中怎么玩一對多?

開發(fā) 前端
Jpa 中的一對一、一對多沒搞明白的話,總會覺得有點繞,今天咱們來簡單聊聊這個話題。

Jpa 中的一對一、一對多沒搞明白的話,總會覺得有點繞,今天咱們來簡單聊聊這個話題。

1. 一對一

比如說一個學(xué)校有一個地址,一個地址只有一個學(xué)校。

那么我們可以按照如下方式來設(shè)計類:

@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;
}
@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;
}

一對一的關(guān)系,可以只在 School 中維護,也可以只在 Address 中維護,也可以兩者都維護,具體哪種,那就看需求了。

在上面的例子中,我們在 School 和 Address 中都通過 @OneToOne 注解來維護了一對一的關(guān)系。

cascade 用來配置級聯(lián)操作,有如下取值:

  • ALL:所有操作
  • PERSIST:級聯(lián)添加
  • MERGE:級聯(lián)更新
  • REMOVE:級聯(lián)刪除
  • REFRESH:級聯(lián)刷新

根據(jù)自己需求選擇合適的就行。

這樣,最終創(chuàng)建出來的 t_school 表和 t_address 表中,會分別多出來一個字段 address_aid 和 school_sid,這兩個字段都是外鍵,正是通過外鍵,將兩張表中不同的記錄關(guān)聯(lián)起來。

有的人可能不習(xí)慣這種自動添加的字段,那也可以自定義該字段,反正該字段總是要有的,自定義的方式如下:

@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,并設(shè)置該字段不可添加和修改,然后通過 @JoinColumn 注解去指定關(guān)聯(lián)關(guān)系,@JoinColumn 注解中的 name 表示的是當(dāng)前類中的屬性名,referencedColumnName 表示的則是 School 類中對應(yīng)的屬性名。

在 School 類中做相似的操作。

最后啟動項目去觀察 MySQL 中生成的表。

2. 一對多

一個班級中有多個學(xué)生,而一個學(xué)生只屬于一個班級,我們可以這樣來定義實體類:

@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 的關(guān)系是多對一,用 @ManyToOne 注解,Clazz 和 Student 的關(guān)系是一對多,用 @OneToMany 注解。

Student 和 Clazz 的關(guān)系是多對一,將來的 t_student 表中會多出來一個屬性 clazz_cid,通過這個外鍵將 Student 和 Clazz 關(guān)聯(lián)起來。如果我們不想要自動生成的 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 屬性,并設(shè)置為不可編輯和不可添加,然后通過 @JoinColumn 注解配置 cid 屬性為外鍵。

Clazz 和 Student 的關(guān)系是一對多,這個是通過一個自動生成的第三張表來實現(xiàn)的,如下:

3. 測試

3.1 添加測試

先來個一對一的添加測試,如下:

public interface SchoolRepository extends JpaRepository<School,Integer> {
}
@SpringBootTest
class JpaOneToManyApplicationTests {

@Autowired
SchoolRepository schoolRepository;
@Test
void contextLoads() {
School school = new School();
school.setSid(1);
school.setName("哈佛大學(xué)");
Address address = new Address();
address.setAid(1);
address.setProvince("黑龍江");
address.setCity("哈爾濱");
address.setArea("某地");
address.setPhone("123456");
school.setAddress(address);
schoolRepository.save(school);
}

}

在這個測試過程中,關(guān)聯(lián)關(guān)系是由 t_school 一方來維護了,因此將來填充的外鍵是 t_school 中的 aid。添加結(jié)果如下圖:

t_school

t_address

這是一個簡單的添加案例。

更新也是調(diào)用 save 方法,更新的時候會先判斷這個 id 是否存在,存在的話就更新,不存在就添加。

再來看班級的添加,如下:

public interface ClazzRepository extends JpaRepository<Clazz,Integer> {
}
@Autowired
ClazzRepository clazzRepository;
@Test
void 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);
}

注意,添加的是班級,所以班級和學(xué)生之間關(guān)系就由第三張表來維護,而不是由學(xué)生來維護。

3.2 查詢測試

再來一個簡單的查詢,假設(shè)我們現(xiàn)在想根據(jù)省份來搜索學(xué)校,如下:

public interface SchoolRepository extends JpaRepository<School,Integer> {
List<School> findSchoolByAddressProvince(String province);
}
@Autowired
SchoolRepository schoolRepository;
@Test
void test01() {
List<School> list = schoolRepository.findSchoolByAddressProvince("黑龍江");
System.out.println("list = " + list);
}

松哥給大家捋一下 Spring Data 如何解析上面自定義的查詢方法:

  • 首先截取掉 findSchoolByAddressProvince 的前綴,剩下 AddressProvince。
  • 檢查 School 是否有 addressProvince 屬性,有就按照該屬性查詢,對于我們的案例,并沒有 addressProvince 屬性,所以繼續(xù)下一步。
  • 從右側(cè)駝峰開始拆分,拆掉第一個駝峰后面的內(nèi)容,我們這里拆分之后只剩下 Address 了,判斷 School 是否存在 Address 屬性,不存在就繼續(xù)重復(fù)該步驟,繼續(xù)切掉右側(cè)第一個駝峰。
  • 在上文案例中,School 中有 address 屬性,所以接下來就去檢查 address 中是否有 province 屬性,因為我們這里只剩下一個 province 了,如果剩下的字符串類似于 provinceAaaBbb 這種,那么繼續(xù)按照第三步去解析。

上面這個寫法有一個小小的風(fēng)險,假設(shè) School 中剛好就有一個屬性叫做 addressProvince,那么此時的分析就會出錯。所以,對于上面的查詢,我們也可以定義成如下方式:

public interface SchoolRepository extends JpaRepository<School,Integer> {
List<School> findSchoolByAddress_Province(String province);
}

此時就不會產(chǎn)生歧義了,系統(tǒng)就知道 province 是 address 的屬性了。

再來一個班級的查詢,如下:

public interface ClazzRepository extends JpaRepository<Clazz,Integer> {
}
@Test
void test03() {
List<Clazz> list = clazzRepository.findAll();
System.out.println("list = " + list);
}

如果在查詢的過程中,需要對學(xué)生進行排序,可以添加如下屬性:

@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") 可以設(shè)置查詢的 student 排序。


責(zé)任編輯:武曉燕 來源: 江南一點雨
相關(guān)推薦

2009-06-04 16:14:22

Hibernate一對Hibernate一對Hibernate多對

2009-09-22 09:55:58

Hibernate實例

2009-07-21 17:31:39

iBATIS一對多映射

2010-04-15 09:09:02

Hibernate

2023-06-12 08:09:01

FlaskSQLAlchemy

2020-02-12 11:34:56

架構(gòu)平滑上云機房遷移

2011-03-25 10:49:30

Join一對多

2010-07-07 08:33:09

SQL Server學(xué)

2020-06-23 14:28:24

MySQL商品數(shù)據(jù)

2009-06-24 15:51:47

Entity Bean一對多映射

2012-03-21 11:43:41

JavaHibernate

2022-10-08 11:40:18

Receive阻塞Trigger

2009-06-04 10:34:19

Hibernate一對一對多關(guān)系配置

2009-06-03 16:27:27

Hibernate一對一關(guān)系

2009-06-03 16:18:16

Hibernate關(guān)系代碼實例

2019-05-12 14:10:07

物聯(lián)網(wǎng)DDOS網(wǎng)絡(luò)攻擊

2012-02-08 13:34:08

HibernateJava

2009-08-17 10:34:51

NHibernate一

2009-09-23 10:37:50

Hibernate一對

2009-06-26 10:15:54

面試HR
點贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 国产精品中文字幕在线 | 91精品中文字幕一区二区三区 | 日韩av一区二区在线 | 久久在线免费 | 91精品国产综合久久久久久 | 91视频麻豆 | 日韩精品av | 男女视频在线观看 | 色婷婷一区二区三区四区 | 51ⅴ精品国产91久久久久久 | 福利色导航 | 久久国产视频网 | 中文字幕日韩一区二区 | 亚洲精品一二区 | 在线视频中文字幕 | 国产精品美女久久久久aⅴ国产馆 | 欧美精品一区二区在线观看 | 日韩欧美在 | 99亚洲综合 | 澳门永久av免费网站 | 亚洲精品久久久蜜桃网站 | 爱爱视频在线观看 | 精品视频亚洲 | 久久久久久成人 | heyzo在线 | 99久久免费精品 | 国产精品国产三级国产aⅴ中文 | 伊人久久综合影院 | 亚洲一区二区精品视频 | 久久精品亚洲精品 | 欧美一区二区精品 | 亚洲一区中文字幕在线观看 | 亚洲成人自拍 | 一二三在线视频 | 欧美一区二区三区 | 日本黄色免费大片 | 婷婷五月色综合 | 欧美一区二区三区的 | 亚洲精品久久久久久久久久久 | 亚洲a在线观看 | 九九热精品免费 |