一、JPA的概述
JPA的全稱是Java Persisitence API,即JAVA持久化API,是sum公司退出的一套基于ORM的規(guī)范,內(nèi)部是由一些列的接口和抽象類構(gòu)成。JPA通過JDK5.0注解描述對(duì)象-關(guān)系表的映射關(guān)系,并將運(yùn)行期的實(shí)體對(duì)象持久化到數(shù)據(jù)庫中。
Spring Data的優(yōu)勢(shì):可以操作多種數(shù)據(jù)庫,關(guān)系型數(shù)據(jù)庫,非關(guān)系型數(shù)據(jù)庫都可以,他就是為數(shù)據(jù)訪問DAO提供熟悉且一致的基于spring的編程模板
1、JPA的優(yōu)勢(shì)
1、標(biāo)準(zhǔn)化
JPA是JCP組織發(fā)布的javaEE標(biāo)準(zhǔn)之一,因此任何聲稱符合JPA標(biāo)準(zhǔn)的框架都遵循同樣的架構(gòu),提供相同的訪問API,這保證了基于JPA開發(fā)的企業(yè)應(yīng)用能夠經(jīng)過少量的修改就能在不同的JPA框架下運(yùn)行。
2、容器級(jí)特性的支持
JPA框架中支持大數(shù)據(jù)集、事務(wù)、并發(fā)等容器級(jí)事務(wù),使得JPA超越了簡單持久化框架的局限,在企業(yè)應(yīng)用發(fā)揮更大的作用。
3、簡單方便
JPA主要目標(biāo)就是提供更加簡單的編程模型:在JPA框架下創(chuàng)建實(shí)體和創(chuàng)建Java類一樣簡單,沒有任何的約束和限制,只需要使用javax.persistence.Entity進(jìn)行注解,JPA框架和接口也非常簡單,沒太多特別的規(guī)則和設(shè)計(jì)要求,開發(fā)者可以很容易掌握,JPA基于非侵入式原則設(shè)計(jì),因此可以很容易和其他框架或容器集成?
4、查詢能力
JPA的查詢語言是面向?qū)ο蠖敲嫦驍?shù)據(jù)的,它3以3面向?qū)ο蟮淖匀徽Z法構(gòu)造查詢語句,可以看成是Hibernate HQL的等價(jià)物,JPA定義了獨(dú)特的JPQL,它是針對(duì)實(shí)體的一種查詢語言,操作對(duì)象是實(shí)體,而不是關(guān)系數(shù)據(jù)庫的表,而且能夠支持批量更新和修改、JOIN、GROUP BY、HAVING等通常只有SQL才能提供的高級(jí)查詢特性,甚至還能支持子查詢
5、高級(jí)特性
JPA支持面向?qū)ο蟮母呒?jí)特性,如類之間的繼承、多臺(tái)和類之間的復(fù)雜關(guān)系,這樣的支持能夠讓開發(fā)放著最大限制的使用面向?qū)ο蟮哪P驮O(shè)計(jì)企業(yè)應(yīng)用,而不需要自行處理這些特性在關(guān)系數(shù)據(jù)庫的持久化。
2、JPA和Hibernate關(guān)系
JPA規(guī)范本質(zhì)上就是一種ORM規(guī)范,注意不是ORM框架,因?yàn)锳PI并未提供ORM實(shí)現(xiàn),只是指定了一些規(guī)范,提供了一些編程API接口,但具實(shí)現(xiàn)則是服務(wù)廠商來實(shí)現(xiàn)
JPA和Hibernate的關(guān)系就像JDBC和JDBC驅(qū)動(dòng)的關(guān)系,JPA是規(guī)范,Hibernate除了作為ORM框架之外,他也是一種JPA實(shí)現(xiàn),JPA怎么取代Hibernate呢?Jdbc規(guī)范可以驅(qū)動(dòng)底層數(shù)據(jù)嗎?不行,如果使用jpa規(guī)范進(jìn)行數(shù)據(jù)庫操作,底層需要hibernate作為實(shí)現(xiàn)完成數(shù)據(jù)持久化工作。
二、快速入門
1、配置數(shù)據(jù)源
這里用的yml方式,里面的jpa就是數(shù)據(jù)庫的名稱,大家也可以寫其他的,前提是這個(gè)數(shù)據(jù)庫存在,用戶名和密碼寫自己的就好。
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/jpa?serverTimezone=UTC
username: root
password: 123456
2、導(dǎo)入依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
3、創(chuàng)建實(shí)體類
通過注解方式讓數(shù)據(jù)庫知道我們的表長什么樣
這里就可以知道表的名稱是users(當(dāng)然你可以任意取名),表的創(chuàng)建一般都有主鍵和自增操作,這里全部通過注解來完成。這里第一次創(chuàng)建表的時(shí)候表名會(huì)爆紅,我們需要給他手動(dòng)指定數(shù)據(jù)庫,也就是數(shù)據(jù)源配置時(shí)的數(shù)據(jù)庫
import lombok.Data;
import javax.persistence.*;
@Data
@Entity //這是實(shí)體類
@Table(name = "user") //對(duì)應(yīng)哪張表
public class User {
@Id //這是主鍵
@Column(name = "id")//數(shù)據(jù)庫中的id,對(duì)應(yīng)屬性中的id
@GeneratedValue(strategy = GenerationType.IDENTITY) //
int id;
@Column(name = "username")//數(shù)據(jù)庫中的username,對(duì)應(yīng)屬性中的username
String username;
@Column(name = "password")//數(shù)據(jù)庫中的password,對(duì)應(yīng)屬性中的password
String password;
}
這里我們還需要設(shè)置自動(dòng)表定義ddl-auto,可以自己生成表不用開發(fā)人員自己建表了
spring:
jpa:
show-sql: true #顯示sql
hibernate:
ddl-auto: create #自動(dòng)生成表
ddl-auto屬性用于設(shè)置自動(dòng)表定義,可以實(shí)現(xiàn)自動(dòng)在數(shù)據(jù)庫中為我們創(chuàng)建一個(gè)表,表的結(jié)構(gòu)會(huì)根據(jù)我們定義的實(shí)體類決定,它有4種
- create 啟動(dòng)時(shí)刪數(shù)據(jù)庫中的表,然后創(chuàng)建,退出時(shí)不刪除數(shù)據(jù)表
- create-drop 啟動(dòng)時(shí)刪數(shù)據(jù)庫中的表,然后創(chuàng)建,退出時(shí)刪除數(shù)據(jù)表 如果表不存在報(bào)錯(cuò)
- update 如果啟動(dòng)時(shí)表格式不一致則更新表,原有數(shù)據(jù)保留
- validate 項(xiàng)目啟動(dòng)表結(jié)構(gòu)進(jìn)行校驗(yàn) 如果不一致則報(bào)錯(cuò)
4、啟動(dòng)測(cè)試類完成表創(chuàng)建
這時(shí)候可以看到控制臺(tái)打印這兩句話,就會(huì)發(fā)現(xiàn)表已經(jīng)創(chuàng)建成功了(和我們自己去敲命令行十分類似,hibernate幫我們完成這些操作,是不是很方便) 刪表是因?yàn)檫x擇了create策略創(chuàng)建表,后面還會(huì)講其他的策略。?
5、訪問我們的表
第一個(gè)泛型填實(shí)體類,第二個(gè)是id的類型
@Repository
public interface UserRepository extends JpaRepository<User,Integer> {
}
?當(dāng)我們想用的時(shí)候:
@SpringBootTest
class YdljpaApplicationTests {
@Autowired
UserRepository userRepository;
@Test
public void testQuery(){
userRepository.findById(1).ifPresent(System.out::println);
}
}
這里需要注意把create策略改成update,因?yàn)閏reate策略會(huì)刪表中數(shù)據(jù)
增操作
@Test
public void testAdd(){
User user=new User();
//user.setId(2);
user.setUsername("itnanls");
user.setPassword("ydl666");
User saveUser = userRepository.save(user); //新增 返回的實(shí)體中帶著實(shí)體id
System.out.println(saveUser);
}
刪操作
@Test
public void testDel(){
userRepository.deleteById(3);
}
分頁操作
@Test
public void testPageable(){
userRepository.findAll(PageRequest.of(0,2)).forEach(System.out::println);
}
三、方法命名規(guī)則查詢
顧名思義,方法命名規(guī)則查詢就是根據(jù)方法的名字,就能創(chuàng)建查詢。只需要按照Spring Data JPA提供的方法命名規(guī)則定義方法的名稱,就可以完成查詢工作。Spring Data JPA在程序執(zhí)行的時(shí)候會(huì)根據(jù)方法名稱進(jìn)行解析,并自動(dòng)生成查詢語句進(jìn)行查詢.
按照Spring Data JPA 定義的規(guī)則,查詢方法以findBy開頭,涉及條件查詢時(shí),條件的屬性用條件關(guān)鍵字連接,要注意的是:條件屬性首字母需大寫。框架在進(jìn)行方法名解析時(shí),會(huì)先把方法名多余的前綴截取掉,然后對(duì)剩下部分進(jìn)行解析。
@Repository
public interface UserRepository extends JpaRepository<User,Integer> {
//根據(jù)username查詢
List<User> findAllByUsername(String str);
//根據(jù)用戶名和密碼查詢
List<User> findByUsernameAndPassword(String username,String password);
//根據(jù)用戶名模糊查詢
List<User> findByUsernameLike(String username);
}
具體的關(guān)鍵字,使用方法和生產(chǎn)成SQL如下表所示
Keyword | Sample | JPQL |
---|---|---|
And | findByLastnameAndFirstname | … where x.lastname = ?1 and x.firstname = ?2 |
Or | findByLastnameOrFirstname | … where x.lastname = ?1 or x.firstname = ?2 |
Is,Equals | findByFirstnameIs,findByFirstnameEquals | … where x.firstname = ?1 |
Between | findByStartDateBetween | … where x.startDate between ?1 and ?2 |
LessThan | findByAgeLessThan | … where x.age < ?1 |
LessThanEqual | findByAgeLessThanEqual | … where x.age ? ?1 |
GreaterThan | findByAgeGreaterThan | … where x.age > ?1 |
GreaterThanEqual | findByAgeGreaterThanEqual | … where x.age >= ?1 |
After | findByStartDateAfter | … where x.startDate > ?1 |
Before | findByStartDateBefore | … where x.startDate < ?1 |
IsNull | findByAgeIsNull | … where x.age is null |
IsNotNull,NotNull | findByAge(Is)NotNull | … where x.age not null |
Like | findByFirstnameLike | … where x.firstname like ?1 |
NotLike | findByFirstnameNotLike | … where x.firstname not like ?1 |
StartingWith | findByFirstnameStartingWith | … where x.firstname like ?1 (parameter bound with appended %) |
EndingWith | findByFirstnameEndingWith | … where x.firstname like ?1 (parameter bound with prepended %) |
Containing | findByFirstnameContaining | … where x.firstname like ?1 (parameter bound wrapped in %) |
OrderBy | findByAgeOrderByLastnameDesc | … where x.age = ?1 order by x.lastname desc |
Not | findByLastnameNot | … where x.lastname <> ?1 |
In | findByAgeIn(Collection ages) | … where x.age in ?1 |
NotIn | findByAgeNotIn(Collection age) | … where x.age not in ?1 |
TRUE | findByActiveTrue() | … where x.active = true |
FALSE | findByActiveFalse() | … where x.active = false |
IgnoreCase | findByFirstnameIgnoreCase | … where UPPER(x.firstame) = UPPER(?1) |
四、使用JPQL的方式查詢
使用Spring Data JPA提供的查詢方法已經(jīng)可以解決大部分的應(yīng)用場景,但是對(duì)于某些業(yè)務(wù)來說,我們還需要靈活的構(gòu)造查詢條件,這時(shí)就可以使用@Query注解,結(jié)合JPQL的語句方式完成查詢。
@Query 注解的使用非常簡單,只需在方法上面標(biāo)注該注解,同時(shí)提供一個(gè)JPQL查詢語句即可,注意:
- 大多數(shù)情況下將*替換為別名
- 表名改為類名
- 字段名改為屬性名
- 搭配注解@Query進(jìn)行使用
@Query("select 表別名 from 表名(實(shí)際為類名) 別名 where 別名.屬性='itlils'")
public List<User> findUsers();
最簡單的查詢
注意是面向?qū)ο蟮牟樵?,所以from的不是表,而且User對(duì)象
@Query("select u from User u")//從實(shí)體類,查詢,而不是表
List<User> findAllUser();
篩選條件
@Query("select u from User u where u.username='itlils'")//從實(shí)體類,查詢,而不是表。where不是列名,而是屬性名
List<User> findAllUserByUsername();
投影結(jié)果
@Query("select u.id from User u")//從實(shí)體類,查詢,而不是表
List<Integer> findAllUser2();
聚合查詢
@Query("select count(u) from User u")//從實(shí)體類,查詢,而不是表
List<Integer> findAllUser4();
傳參
//修改數(shù)據(jù) 一定加上@Modifying 注解
@Transactional
@Modifying
@Query("update User set username=?1 where id=?2")
int updateUsernameById2(String username,Integer id);
使用原生sql
使用原生的sql需要在sql語句后面加上 nativeQuery = true
//修改數(shù)據(jù) 一定加上@Modifying 注解
@Transactional
@Modifying
@Query(value = "update user u set u.username=?1 where u.id=?2",nativeQuery = true)
int updateUsernameById3(String username,Integer id);
五、一對(duì)一關(guān)系
我們用賬號(hào)表和賬號(hào)詳細(xì)表來舉例
@Data
@Entity //表示這個(gè)類是一個(gè)實(shí)體類
@Table(name = "account") //對(duì)應(yīng)的數(shù)據(jù)庫中表名稱
public class Account {
@GeneratedValue(strategy = GenerationType.IDENTITY) //生成策略,這里配置為自增
@Column(name = "id") //對(duì)應(yīng)表中id這一列
@Id //此屬性為主鍵
int id;
@Column(name = "username") //對(duì)應(yīng)表中username這一列
String username;
@Column(name = "password") //對(duì)應(yīng)表中password這一列
String password;
//一對(duì)一
@JoinColumn(name = "detail_id")
@OneToOne//聲明為一對(duì)一關(guān)系
AccountDetail detail;//對(duì)象類型,也可以理解這里寫哪個(gè)實(shí)體類,外鍵就指向哪個(gè)實(shí)體類的主鍵
}
@Data
@Entity
@Table(name = "account_details")
public class AccountDetail {
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)//還是設(shè)置一個(gè)自增主鍵
@Id
int id;
@Column(name = "address")
String address;
@Column(name = "email")
String email;
@Column(name = "phone")
String phone;
@Column(name = "real_name")
String realName;
}
這里從日志中可以看出hibernate幫我們完成外鍵的創(chuàng)建
但這還不能完成同時(shí)對(duì)兩張表進(jìn)行操作 設(shè)置懶加載完成想查什么就查什么功能,設(shè)置關(guān)聯(lián)級(jí)別完成同時(shí)操作兩張表
@JoinColumn(name = "detail_id")
@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) //設(shè)置關(guān)聯(lián)操作為ALL
AccountDetail detail;
這里的關(guān)聯(lián)級(jí)別也是有多個(gè),一般設(shè)置為all就行
- ALL:所有操作都進(jìn)行關(guān)聯(lián)操作
- PERSIST:插入操作時(shí)才進(jìn)行關(guān)聯(lián)操作
- REMOVE:刪除操作時(shí)才進(jìn)行關(guān)聯(lián)操作
- MERGE:修改操作時(shí)才進(jìn)行關(guān)聯(lián)操作
現(xiàn)在我們就可以同時(shí)添加數(shù)據(jù)和刪除了
@Autowired
AccountRepository accountRepository;
@Test
public void testFind11() {
Account account=new Account();
account.setUsername("itlils");
account.setPassword("ydl666");
AccountDetail accountDetail=new AccountDetail();
accountDetail.setPhone("13000000000");
accountDetail.setRealName("itlils");
accountDetail.setAddress("cn");
accountDetail.setEmail("123@qq.com");
account.setDetail(accountDetail);
Account save = accountRepository.save(account);
System.out.println("插入之后account id為:"+save.getId()+"|||accountDetail id"+save.getDetail().getId());
}
六、一對(duì)多的關(guān)系
我們用作者和文章來舉例,一對(duì)多的情況,肯定是在多的地方有個(gè)字段來標(biāo)識(shí)是那個(gè)作者
Author 和 Article 是一對(duì)多關(guān)系(雙向)。那么在JPA中,如何表示一對(duì)多的雙向關(guān)聯(lián)呢?
JPA用@OneToMany和@ManyToOne來標(biāo)識(shí)一對(duì)多的雙向關(guān)聯(lián)。一端(Author)使用@OneToMany,多端(Article)使用@ManyToOne。
在JPA規(guī)范中,一對(duì)多的雙向關(guān)系由多端(Article)來維護(hù)。就是說多端(Article)為關(guān)系維護(hù)端,負(fù)責(zé)關(guān)系的增刪改查。一端(Author)則為關(guān)系被維護(hù)端,不能維護(hù)關(guān)系。
一端(Author)使用@OneToMany注釋的mappedBy="author"屬性表明Author是關(guān)系被維護(hù)端。
多端(Article)使用@ManyToOne和@JoinColumn來注釋屬性 author,@ManyToOne表明Article是多端,@JoinColumn設(shè)置在article表中的關(guān)聯(lián)字段(外鍵)。
@Data
@Entity //表示這個(gè)類是一個(gè)實(shí)體類
@Table(name = "author") //對(duì)應(yīng)的數(shù)據(jù)庫中表名稱
public class Author {
@Column(name = "id")
@Id // 主鍵
@GeneratedValue(strategy = GenerationType.IDENTITY) // 自增長策略
private Long id; //id
@Column(nullable = false, length = 20,name = "name")
private String name;//姓名
@OneToMany(mappedBy = "author",cascade=CascadeType.ALL,fetch=FetchType.LAZY)
//級(jí)聯(lián)保存、更新、刪除、刷新;延遲加載。當(dāng)刪除用戶,會(huì)級(jí)聯(lián)刪除該用戶的所有文章
//擁有mappedBy注解的實(shí)體類為關(guān)系被維護(hù)端
//mappedBy="author"中的author是Article中的author屬性
private List<Article> articleList;//文章列表
}
@Data
@Entity //表示這個(gè)類是一個(gè)實(shí)體類
@Table(name = "article") //對(duì)應(yīng)的數(shù)據(jù)庫中表名稱
public class Article {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY) // 自增長策略
@Column(name = "id", nullable = false)
private Long id;
@Column(nullable = false, length = 50) // 映射為字段,值不能為空
private String title;
@Lob // 大對(duì)象,映射 MySQL 的 Long Text 類型
@Basic(fetch = FetchType.LAZY) // 懶加載
@Column(nullable = false) // 映射為字段,值不能為空
private String content;//文章全文內(nèi)容
@ManyToOne(cascade={CascadeType.MERGE,CascadeType.REFRESH},optional=false)//可選屬性optional=false,表示author不能為空。刪除文章,不影響用戶
@JoinColumn(name="author_id")//設(shè)置在article表中的關(guān)聯(lián)字段(外鍵)
private Author author;//所屬作者
}
新增
@Autowired
AuthorRepository authorRepository;
@Autowired
ArticleRepository articleRepository;
@Test
public void testFind13() {
Author author=new Author();
author.setName("itlils");
Author author1 = authorRepository.save(author);
Article article1=new Article();
article1.setTitle("1");
article1.setContent("123");
article1.setAuthor(author1);
articleRepository.save(article1);
Article article2=new Article();
article2.setTitle("2");
article2.setContent("22222");
article2.setAuthor(author1);
articleRepository.save(article2);
}
刪除文章來源:http://www.zghlxwxcb.cn/news/detail-856413.html
@Test
public void testFind14() {
articleRepository.deleteById(2L);
}
查詢
@Transactional
@Test
public void testFind15() {
Optional<Author> byId = authorRepository.findById(1L);
if (byId.isPresent()){
Author author = byId.get();
List<Article> articleList = author.getArticleList();
System.out.println(articleList);
}
}
注意點(diǎn):
懶加載會(huì)導(dǎo)致不能顯示出作者,我們只需要把:作者 fetch=FetchType.EAGER,把懶加載取消掉就可以了
但是還會(huì)出現(xiàn)有個(gè)循環(huán)依賴的問題,tostring文章的時(shí)候需要有作者,作者的又要文章的,解決方案:循環(huán)toString 破壞一方的toString即可。文章加上@ToString(exclude = {"author"})
七、多對(duì)多的關(guān)系
用戶和權(quán)限,一個(gè)權(quán)限可以有多個(gè)用戶,一個(gè)用戶又可以有多個(gè)權(quán)限。這種多對(duì)多要怎么處理呢,這個(gè)時(shí)候需要一個(gè)中間關(guān)聯(lián)表來做。
JPA使用@ManyToMany來注解多對(duì)多的關(guān)系,由一個(gè)關(guān)聯(lián)表來維護(hù)。這個(gè)關(guān)聯(lián)表的表名默認(rèn)是:主表名+下劃線+從表名。(主表是指關(guān)系維護(hù)端對(duì)應(yīng)的表,從表指關(guān)系被維護(hù)端對(duì)應(yīng)的表)。這個(gè)關(guān)聯(lián)表只有兩個(gè)外鍵字段,分別指向主表ID和從表ID。字段的名稱默認(rèn)為:主表名+下劃線+主表中的主鍵列名,從表名+下劃線+從表中的主鍵列名。
需要注意的:
1、多對(duì)多關(guān)系中一般不設(shè)置級(jí)聯(lián)保存、級(jí)聯(lián)刪除、級(jí)聯(lián)更新等操作。
2、可以隨意指定一方為關(guān)系維護(hù)端,在這個(gè)例子中,我指定 User 為關(guān)系維護(hù)端,所以生成的關(guān)聯(lián)表名稱為: user_authority,關(guān)聯(lián)表的字段為:user_id 和 authority_id。
3、多對(duì)多關(guān)系的綁定由關(guān)系維護(hù)端來完成,即由 User.setAuthorities(authorities) 來綁定多對(duì)多的關(guān)系。關(guān)系被維護(hù)端不能綁定關(guān)系,即User不能綁定關(guān)系。
4、多對(duì)多關(guān)系的解除由關(guān)系維護(hù)端來完成,即由Authority.getUser().remove(user)來解除多對(duì)多的關(guān)系。關(guān)系被維護(hù)端不能解除關(guān)系,即Authority不能解除關(guān)系。
5、如果 User 和 Authority 已經(jīng)綁定了多對(duì)多的關(guān)系,那么不能直接刪除 Authority,需要由 User 解除關(guān)系后,才能刪除 Authority。但是可以直接刪除 User,因?yàn)?User 是關(guān)系維護(hù)端,刪除 User 時(shí),會(huì)先解除 User 和 Authority 的關(guān)系,再刪除 Authority。
@Data
@Entity //這是實(shí)體類
@Table(name = "users") //對(duì)應(yīng)哪張表
public class Users {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false, length = 20, unique = true)
private String username; // 用戶賬號(hào),用戶登錄時(shí)的唯一標(biāo)識(shí)
@Column(length = 100)
private String password; // 登錄時(shí)密碼
@ManyToMany
@JoinTable(name = "user_authority",joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "authority_id"))
//1、關(guān)系維護(hù)端,負(fù)責(zé)多對(duì)多關(guān)系的綁定和解除
//2、@JoinTable注解的name屬性指定關(guān)聯(lián)表的名字,joinColumns指定外鍵的名字,關(guān)聯(lián)到關(guān)系維護(hù)端(User)
//3、inverseJoinColumns指定外鍵的名字,要關(guān)聯(lián)的關(guān)系被維護(hù)端(Authority)
//4、其實(shí)可以不使用@JoinTable注解,默認(rèn)生成的關(guān)聯(lián)表名稱為主表表名+下劃線+從表表名,
//即表名為user_authority
//關(guān)聯(lián)到主表的外鍵名:主表名+下劃線+主表中的主鍵列名,即user_id
//關(guān)聯(lián)到從表的外鍵名:主表中用于關(guān)聯(lián)的屬性名+下劃線+從表的主鍵列名,即authority_id
//主表就是關(guān)系維護(hù)端對(duì)應(yīng)的表,從表就是關(guān)系被維護(hù)端對(duì)應(yīng)的表
private List<Authority> authorityList;
}
@Data
@Entity //這是實(shí)體類
@Table(name = "authority") //對(duì)應(yīng)哪張表
public class Authority {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(nullable = false)
private String name; //權(quán)限名
@ManyToMany(mappedBy = "authorityList")
private List<Users> userList;
}
添加
@Autowired
private UsersRepository usersRepository;
@Autowired
private AuthorityRepository authorityRepository;
@Test
public void testFind16() {
Authority authority = new Authority();
authority.setId(1);
authority.setName("ROLE_ADMIN");
authorityRepository.save(authority);
}
@Test
public void testFind17() {
Users users = new Users();
users.setUsername("itlils");
users.setPassword("123456");
Authority authority = authorityRepository.findById(1).get();
List<Authority> authorityList = new ArrayList<>();
authorityList.add(authority);
users.setAuthorityList(authorityList);
usersRepository.save(users);
}
先運(yùn)行 saveAuthority 添加一條權(quán)限記錄,
然后運(yùn)行 saveUser 添加一條用戶記錄,與此同時(shí),user_authority 表中也自動(dòng)插入了一條記錄
刪除
@Test
public void testFind18() {
usersRepository.deleteById(1L);
}
user 表中刪除一條記錄,同時(shí) user_authority 能夠級(jí)聯(lián)刪除一條記錄,中間表和users表數(shù)據(jù)都刪除了文章來源地址http://www.zghlxwxcb.cn/news/detail-856413.html
到了這里,關(guān)于Spring Data JPA 快速上手的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!