关于 Repository 接口
Repository 讲解
- Repository 接口是 Spring Data 的核心接口,不提供任何方法
- public interface Repository<T,ID extends Serializable> { }
- @RepositoryDefinition 注解的使用
Repository是一个空接口,标记接口 没有包含方法声明的接口
@RepositoryDefinition 注解的使用
/**
* @author weilai
* @version 1.0.0 2018/8/23
*/
@RepositoryDefinition(domainClass = Employee.class, idClass = Integer.class)
public interface EmployeeRepository { // extends Repository<Employee, Integer> {
public Employee findByName(String name);
}
Repository 子接口详解
- CrudRepository:
- 继承 Repository,实现了 CRUD 相关的方法。
- PagingAndSortingRepository:
- 继承 CrudRepository,实现了 分页和排序 相关的方法。
- JpaRepository:
- 继承 PagingAndSortingRepository,实现了 JPA 相关的方法。
查询方法定义规则和使用
Repository 中查询方法定义规则和使用
| Keyword | Sample | JPQL snippet |
|---|---|---|
| And | findByLastnameAndFirstname | where |
| x.lastname = ?1 | ||
| and | ||
| x.firstname = ?2 | ||
| Or | findByLastnameOrFirstname | where |
| x.lastname = ?1 | ||
| or | ||
| x.firstname = ?2 | ||
| Between | findByStartDataBetween | where |
| x.startData between | ||
| ?1 and ?2 | ||
| LessThan | findByAgeLessThan | where x.age < ?1 |
| GreaterThan | findByAgeGreaterThan | where x.age > ?1 |
| After | findByStartDataAfter | where x.startData > ?1 |
| Before | findByStartDataAfter | where x.startData > ?1 |
| IsNull | findByAgeIsNull | where x.age is null |
| IsNotNull,NotNull | findByAge(Is)NotNull | where x.age is 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 ages) | … 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) |
| 操作实例 |
package com.imooc.repository;
import com.imooc.domain.Employee;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.RepositoryDefinition;
import java.util.List;
/**
* 数据操作实体
*
* @author weilai
* @version 1.0.0 2018/8/23
*/
@RepositoryDefinition(domainClass = Employee.class, idClass = Integer.class)
public interface EmployeeRepository { // extends Repository<Employee, Integer> {
public Employee findByName(String name);
// where name like ?% and age <?
public List<Employee> findByNameStartingWithAndAgeLessThan(String name, Integer age);
// where name like ?% and age >?
public List<Employee> findByNameEndingWithAndAgeLessThan(String name, Integer age);
// where name in (?,?,?....) or age >?
public List<Employee> findByNameInOrAgeLessThan(List<String> nameList, Integer age);
}
对于按照方法命名规则来使用的话,有弊端:
- 方法名会比较长: 约定大于配置
- 对于一些复杂的查询,是很难实现
Query注解使用
- 在 Repository 方法中使用,不需要遵循查询方法命名规则
- 只需要将 @Query 定义在 Repository 方法上
- 命名参数及索引参数的使用 ?1 ?2 :name :age 占位符
- 本地查询(@Query(nativeQuery = true,value = “select count(1) from employee”)) 开启 nativeQuery 使用原生 SQL 进行查询
更新操作整合事务使用
- @Modifying 注解使用
- @Modifying 结合 @Query 注解执行更新操作
事务在Spring data中的使用:
- 事务一般是在Service层作注解
- @Query、 @Modifying、@Transactional的综合使用
@Query(nativeQuery = true, value = "select count(1) from employee") // 注意!!此处 employee 是表名
public long getCount();
@Modifying
@Query("update Employee o set o.age = :age where o.id = :id") // 注意!!此处 Employee 是类名
public void update(@Param("id") Integer id, @Param("age") Integer age);
...
@Service
public class EmployeeService {
@Transactional
public void update(Integer id, Integer age) {
employeeRepository.update(id, age);
}
}
...
一般在 Service 的一个操作中有很多 dao方法,所以都要让他们在一个事务中。