前言:公司新的項目使用的jpa伟葫,之前沒有過,所以在此小結(jié)一下
一弟跑、Spring data JPA簡介
Spring data JPA是Spring在ORM(對象關(guān)系映射)框架廊蜒,以及JPA規(guī)范的基礎(chǔ)上,封裝的一套JPA應(yīng)用框架胯盯,并提供了一整套的數(shù)據(jù)訪問層解決方案懈费。
二、JPA優(yōu)缺點
使用jpa也有一段時間了博脑,在我看來jpa的優(yōu)點很明顯:
1.對于單表查詢十分快捷方便憎乙,不需要像mybatis一樣寫sql,只需要在dao層按jpa命名規(guī)范調(diào)方法就好了
2.我們當(dāng)前項目使用的數(shù)據(jù)庫是mysql叉趣,jpa的一大作用就是數(shù)據(jù)庫無關(guān)性泞边,也就是說,以后項目改用oracle或者其他數(shù)據(jù)庫時疗杉,我們不需要做任何處理阵谚,數(shù)據(jù)庫可以輕松實現(xiàn)遷移。
但是呢烟具,jpa的缺點也很明顯梢什,就是寫復(fù)雜查詢真的很蛋疼,像什么查詢條件來自不同表净赴,需要關(guān)聯(lián)好幾張表绳矩,有需要分頁,需要排序玖翅,業(yè)務(wù)一復(fù)雜就腦殼疼(ps:可能還是太菜了)
注意:JPA 對多表復(fù)雜查詢很不友好翼馆,JPA核心就是為了盡量不用多表查詢,所有在表設(shè)計這塊應(yīng)該再三斟酌金度。另外应媚,JPA的
@OneToMany,@OneToOne表關(guān)聯(lián)查詢注解我開發(fā)時是不用的
三猜极、初級查詢
3.1 常見注解
二.JPA常用注解
注解 | 解釋 |
---|---|
@Entity | 聲明類為實體或表中姜。 |
@Table | 聲明表名。 |
@Basic | 指定非約束明確的各個字段跟伏。 |
@Embedded | 指定類或它的值是一個可嵌入的類的實例的實體的屬性丢胚。 |
@Id | 指定的類的屬性,用于識別(一個表中的主鍵)受扳。 |
@GeneratedValue | 指定如何標(biāo)識屬性可以被初始化携龟,例如自動、手動勘高、或從序列表中獲得的值峡蟋。 |
@Transient | 指定的屬性坟桅,它是不持久的,即:該值永遠(yuǎn)不會存儲在數(shù)據(jù)庫中蕊蝗。 |
@Column | 指定持久屬性欄屬性仅乓。 |
@SequenceGenerator | 指定在@GeneratedValue注解中指定的屬性的值。它創(chuàng)建了一個序列蓬戚。 |
@TableGenerator | 指定在@GeneratedValue批注指定屬性的值發(fā)生器夸楣。它創(chuàng)造了的值生成的表。 |
@AccessType | 這種類型的注釋用于設(shè)置訪問類型子漩。如果設(shè)置@AccessType(FIELD)裕偿,則可以直接訪問變量并且不需要getter和setter,但必須為public痛单。如果設(shè)置@AccessType(PROPERTY),通過getter和setter方法訪問Entity的變量劲腿。 |
@JoinColumn | 指定一個實體組織或?qū)嶓w的集合旭绒。這是用在多對一和一對多關(guān)聯(lián)。 |
@UniqueConstraint | 指定的字段和用于主要或輔助表的唯一約束焦人。 |
@ColumnResult | 參考使用select子句的SQL查詢中的列名挥吵。 |
@ManyToMany | 定義了連接表之間的多對多一對多的關(guān)系。 |
@ManyToOne | 定義了連接表之間的多對一的關(guān)系花椭。 |
@OneToMany | 定義了連接表之間存在一個一對多的關(guān)系忽匈。 |
@OneToOne | 定義了連接表之間有一個一對一的關(guān)系。 |
@NamedQueries | 指定命名查詢的列表矿辽。 |
@NamedQuery | 指定使用靜態(tài)名稱的查詢丹允。 |
3.2 jpa 簡單查詢
3.2.1使用 @Query 創(chuàng)建查詢
查詢
方式一:原生sql查詢
@Query(value = "select user_id,user_name,.. from user_info where userId= :userId"袋倔, nativeQuery = true)
Object[] findByUserId(@Param("userId") Long userId);
方式二:使用jpa的查詢方式
查詢部分字段
@Query(value = "select userId雕蔽,userName,.. from userInfo where userId= :userId")
User findByUserId(@Param("userId") Long userId);
查詢所有字段
@Query(value = "select info from UserInfo info where info.userId= :userId")
User findByUserId(@Param("userId") Long userId);
UserInfo 是和數(shù)據(jù)庫映射的實體類,查詢屬性名是UserInfo 類中的字段名宾娜,而原生查詢直接是數(shù)據(jù)庫字段名
注意 :@Param 注解是一定要的
刪除
方式一:原生sql刪除
@Modifying
@Transactional(rollbackFor = Exception.class)
@Query(value = "delete from user_info where userId= :userId"批狐, nativeQuery = true)
void deleteByUserId(@Param("userId") Long userId);
方式二:使用jpa的刪除方式
@Modifying
@Transactional(rollbackFor = Exception.class)
@Query("DELETE FROM StationUser where userId IN(:userIdList)")
int deleteByIds(@Param("userIdList") List<Long> userIdList);
修改和刪除類似,注意修改前塔、刪除和查詢是不同的嚣艇,一定要加
@Modifying (必須要,否則會報錯)
@Transactional(rollbackFor = Exception.class)
兩個注解 华弓,@Transactional(rollbackFor = Exception.class)注解也可以不在方法名上加食零,在調(diào)用這個方法的service層的類上加也可以,如下
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class TestServiceImpl implements TestService {
...
}
3.2.2通過解析方法名創(chuàng)建查詢
Keyword | Sample | JPQL snippet |
---|---|---|
And |
findByLastnameAndFirstname |
… where x.lastname = ?1 and x.firstname = ?2 |
Or |
findByLastnameOrFirstname |
… where x.lastname = ?1 or x.firstname = ?2 |
Is,Equals |
findByFirstname ,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<Age> ages) |
… where x.age in ?1 |
NotIn |
findByAgeNotIn(Collection<Age> 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) |