在前一篇博客中已经对于Spring Data JPA做了简单的描述,了解了一下Repository,CrudRepository等接口的作用和区别,并对于如何选择进行了简单的描述,那么本篇博客就深入JPA,了解一下如何使用。
CrudRepository 接口
public interface CrudRepository<T, ID extends Serializable>
extends Repository<T, ID> {
S save(S entity);
T findOne(ID primaryKey);
Iterable findAll();
Long count();
void delete(T entity);
boolean exists(ID primaryKey);
// … more functionality omitted.
}
PagingAndSortingRepository接口
public interface PagingAndSortingRepository<T, ID extends Serializable>
extends CrudRepository<T, ID> {
Iterable findAll(Sort sort);
Page findAll(Pageable pageable);
}
我们有两种方法可以指定查询语句:
(1)根据JPA所提供的命名规范,来命名自己的方法,那么Spring Data JPA就会根据它的解析规范来进行处理。
(2)在声明的方法上面使用@query 注解,并自己提供一个查询语句,那么Spring Data JPA在处理的时候就会按照我们提供的语句来进行处理。
Spring Data JPA的方法名解析规范
框架在进行方法名解析时,会先把方法名多余的前缀截取掉,比如 find、findBy、read、readBy、get、getBy,然后对剩下部分进行解析。并且如果方法的最后一个参数是 Sort 或者 Pageable 类型,也会提取相关的信息,以便按规则进行排序或者分页查询。
And — 等价于 SQL 中的 and 关键字,比如 findByUsernameAndPassword(String user, Striang pwd);
Or — 等价于 SQL 中的 or 关键字,比如 findByUsernameOrAddress(String user, String addr);
Between — 等价于 SQL 中的 between 关键字,比如 findBySalaryBetween(int max, int min);
LessThan — 等价于 SQL 中的 “<”,比如 findBySalaryLessThan(int max);
GreaterThan — 等价于 SQL 中的”>”,比如 findBySalaryGreaterThan(int min);
IsNull — 等价于 SQL 中的 “is null”,比如 findByUsernameIsNull();
IsNotNull — 等价于 SQL 中的 “is not null”,比如 findByUsernameIsNotNull();
NotNull — 与 IsNotNull 等价;
Like — 等价于 SQL 中的 “like”,比如 findByUsernameLike(String user);
NotLike — 等价于 SQL 中的 “not like”,比如 findByUsernameNotLike(String user);
OrderBy — 等价于 SQL 中的 “order by”,比如 findByUsernameOrderBySalaryAsc(String user);
Not — 等价于 SQL 中的 “! =”,比如 findByUsernameNot(String user);
In — 等价于 SQL 中的 “in”,比如 findByUsernameIn(Collection userList) ,方法的参数可以是 Collection 类型,也可以是数组或者不定长参数;
NotIn — 等价于 SQL 中的 “not in”,比如 findByUsernameNotIn(Collection userList) ,方法的参数可以是 Collection 类型,也可以是数组或者不定长参数;
public interface PersonRepository extends Repository<User, Long> {
List findByEmailAddressAndLastname(EmailAddress emailAddress, String lastname);
// Enables the distinct flag for the query
List findDistinctPeopleByLastnameOrFirstname(String lastname, String firstname);
List findPeopleDistinctByLastnameOrFirstname(String lastname, String firstname);
// Enabling ignoring case for an individual property
List findByLastnameIgnoreCase(String lastname);
// Enabling ignoring case for all suitable properties
List findByLastnameAndFirstnameAllIgnoreCase(String lastname, String firstname);
// Enabling static ORDER BY for a query
List findByLastnameOrderByFirstnameAsc(String lastname);
List findByLastnameOrderByFirstnameDesc(String lastname);
}
使用@Query注解的方式来定义语句
这个就不进行详细描述了,给出几组例子就明白了
类型1:以 ?1 来标记需要输入参数的地方,然后在方法中给出参数。
public interface UserDao extends Repository<AccountInfo, Long> {
@Query("select a from AccountInfo a where a.accountId = ?1")
public AccountInfo findByAccountId(Long accountId);
@Query("select a from AccountInfo a where a.balance > ?1")
public Page findByBalanceGreaterThan(
Integer balance,Pageable pageable);
}
类型2:使用 :id 这种方式标记参数,在参数列表中使用@Parameter来呼应。
public interface UserDao extends Repository<AccountInfo, Long> {
public AccountInfo save(AccountInfo accountInfo);
@Query("from AccountInfo a where a.accountId = :id")
public AccountInfo findByAccountId(@Param("id")Long accountId);
问题三:既然查询解决了,那么 删除和修改,增加怎么解决呢?
//使用 @Modifying 将查询标识为修改
@Modifying
@Query("update AccountInfo a set a.salary = ?1 where a.salary < ?2")
public int increaseSalary(int after, int before);
Spring Data JPA 对事务的支持 也是一个很重要的问题,下次讨论。