Spring Data JPA
JPA规范
Spring Data JPA入门案例
Spring Data JPA 的实现过程
-
注入的
customerDao
对象,本质上是通过JdkDynamicAopProxy
生成的一个代理对象 -
SimpleJpaRepository
当中封装了JPA的操作(借助JPA
的API
完成数据库的CRUD
) -
通过
hibernate
完成数据库操作(封装了jdbc
)
Spring Data JPA查询
JPQL
的方式查询
@Query
注解的使用:只需在方法上面标注该注解,同时提供一个JPQL
查询语句即可- 使用
@Query
来执行一个更新操作,需要用@Modifying
来将该操作标识为修改查询
SQL 的方式查询
@Query
注解的使用:只需在方法上面标注该注解,同时提供一个SQL
查询语句即可- 要将
@Query
中的nativeQuery
改为true
方法命名规则查询
- 查询方法以
findBy
开头 - 涉及条件查询时,条件的属性用条件关键字连接
- 条件属性首字母需大写
- 框架在进行方法名解析时,会先把方法名多余的前缀截取掉,然后对剩下部分进行解析
Keyword | Simple | 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) |
Specifications 动态查询
自定义查询条件
- 实现
Specification
接口(提供泛型,查询的对象类型) - 实现
toPredicate
方法(构造查询条件) - 需要借助方法参数中的两个参数(
root
:获取需要查询的对象属性CriteriaBuilder
:构造查询条件的,内部封装了很多的查询条件)
方法名称 | Sql对应关系 |
---|---|
equal | filed = value |
gt(greaterThan ) | filed > value |
lt(lessThan ) | filed < value |
ge(greaterThanOrEqualTo ) | filed >= value |
e( lessThanOrEqualTo) | filed <= value |
notEqule | filed != value |
like | filed like value |
notLike | filed not like value |
JPA 中的一对多
映射注解说明:
@OneToMany
:建立一对多的关系映射
属性:
targetEntityClass
:指定多的多方的类的字节码
mappedBy
:指定从表实体类中引用主表对象的名称(放弃维护主键)
cascade
:指定要使用的级联操作
fetch
指定是否采用延迟加载
orphanRemoval
:是否使用孤儿删除
@ManyToOne
:建立多对一的关系
属性:
targetEntityClass
:指定一的一方实体类字节码
cascade
:指定要使用的级联操作
值:
CascadeType.MERGE
级联更新
CascadeType.PERSIST
级联保存:
CascadeType.REFRESH
级联刷新:
CascadeType.REMOVE
级联删除:
CascadeType.ALL
包含所有
fetch
:指定是否采用延迟加载
optional
:关联是否可选。如果设置为false,则必须始终存在非空关系。
@JoinColumn
用于定义主键字段和外键字段的对应关系。
属性:
name
:指定外键字段的名称
referencedColumnName
:指定引用主表的主键字段名称
unique
:是否唯一,默认值不唯一
nullable
:是否允许为空。默认值允许。
insertable
:是否允许插入。默认值允许。
updatable
:是否允许更新。默认值允许。
columnDefinition
:列的定义信息。
JPA 中的多对多
映射注解说明:
@ManyToMany
:用于映射多对多关系
属性:
cascade
:配置级联操作。
值:
CascadeType.MERGE
级联更新
CascadeType.PERSIST
级联保存:
CascadeType.REFRESH
级联刷新:
CascadeType.REMOVE
级联删除:
CascadeType.ALL
包含所有
mappedBy
:放弃对中间表的维护
fetch
:配置是否采用延迟加载。
targetEntity
:配置目标的实体类。映射多对多的时候不用写。
@JoinTable
:针对中间表的配置
属性:
name
:配置中间表的名称
joinColumns
:中间表的外键字段关联当前实体类所对应表的主键字段
inverseJoinColumn
:中间表的外键字段关联对方表的主键字段
@JoinColumn用于定义主键字段和外键字段的对应关系。
属性:
name
:指定外键字段的名称
referencedColumnName
:指定引用主表的主键字段名称
unique
:是否唯一,默认值不唯一
nullable
:是否允许为空。默认值允许。
insertable
:是否允许插入。默认值允许。
updatable
:是否允许更新。默认值允许。
columnDefinition
:列的定义信息。
对象导航查询
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class ObjectQueryTest {
@Autowired
private CustomerDao customerDao;
@Autowired
private LinkManDao linkManDao;
//测试对象导航查询(查询一个对象的时候,通过此对象查询所有的关联对象)
//对象导航查询(一的一方查询多的一方),默认使用的是延迟加载的形式查询的
//修改配置(fetch):将延迟加载该为立即加载
@Test
@Transactional //解决在Java代码中的no session问题
@Rollback(value = false)
public void testQuery1(){
//查询id为1的客户
Customer customer = customerDao.findOne(1L);
//对象导航查询,客户下的所有联系人
Set<LinkMan> linkMans = customer.getLinkMen();
for(LinkMan linkMan : linkMans){
System.out.println(linkMan);
}
}
//对象导航查询(多的一方查询一的一方),默认使用的是立即加载的形式查询的
@Test
@Transactional //解决在Java代码中的no session问题
@Rollback(value = false)
public void testQuery2(){
//查询id为1的联系人
LinkMan linkMan = linkManDao.getOne(1L);
//对象导航查询,联系人的kehu
Customer customer = linkMan.getCustomer();
System.out.println(customer);
}
}