转载

Spring Data JPA 注解式查询方法

使用命名查询为实体声明查询是一种有效的方法,对于少量查询很有效。一般只需要关心@Query里面的value和nativeQuery的值。使用声明式JPQL查询有一个好处,就是启动的时候就知道语法正确与否。

一、Query 声明式查询使用

1.1、@Query详解

声明一个注解在Repository的查询方法上。

public interface UserRepository extends JpaRepository<User, Long> { 
@Query ("select u from User u where u. emailAddress = ?1”)
User findByEmailAddress(String emailAddress);}

Like查询,注意firstname不会自动加上%关键字的

public interface UserRepository extends JpaRepository<User, Long> { 
@Query("select u from User u where u.firstname like %?1") 
List<User> findByFirstnameEndsWith(String firstname);
}

直接用原始SQL。

public interface UserRepository extends JpaRepository<User ,Long> {
@Query(value = "SELECT * FROM USERS WHERE EMAIL_ADDRESS = ?1", nativeQuery = true )
User findByEmailAddress(String emailAddress);
}

nativeQuery不支持直接Sort的参数查询

1.2、@Query排序

@Query在JPQL下想实现排序,直接用PageRequest或者直接用Sort参数都可以。

在排序实例中实际使用的属性需要与实体模型里面的字段相匹配,这意味着它们需要解析为查询中使用的属性或别名。这是一个state_field_path_expression JPQL定义,并且Sort的对象支持一些特定的函数。

public interface UserRepository extends JpaRepository<User, Long> {
@Query(nselect u from User u where u.lastname like ? l %n)
List<User> findByAndSort(String lastname, Sort sort);
@Query("select u.id, LENGTH(u.firstname) as fn_len from User u where u.lastname like ?1%,?)
List<Object[]> findByAsArrayAndSort(String lastname, Sort sort);
}
//调用方的写法,如下:
repo.findByAndSort("lannister",new Sort('firstname'));
repo.findByAndSort("stark",new Sort("LENGTH(firstname)")) ;
repo.findByAndSort("targaryen",JpaSort.unsafe("LENGTH(firstname)"));
repo.findByAsArrayAndSort("bolton",new Sort(nfn_lenn));

1.3、@Query分页

直接用Page对象接收接口,参数直接用Pageable的实现类即可。

public interface UserRepository extends JpaRepository<User, Long> {
@Query(value = "select u from User u where u.lastname = ?ln) 
Page<User> findByLastname(String lastname, Pageable pageable)

//调用者的写法
repository.findByFirstName(njackzhang",new PageRequest(1,10));

二、@Param用法

默认情况下,参数是通过顺序绑定在查询语句上的。这使得查询方法对参数位置的重构容易出错。为了解决这个问题,你可以使用@Param注解指定方法参数的具体名称,通过绑定的参数名字做查询条件。

import org.springframework.data.jpa.repository.Query;
public interface UserRepository extends JpaRepository<User, Long> {
@Query("select u from User u where u.firstname = :firstname or u.lastname =:lastname")
User findByLastnameOrFirstname(@Param("lastname") String lastname,@Param("firstname1') String firstname);
}

三、SpEL表达式的支持

在Spring Data JPA 1.4以后,支持在@Query中使用SpEL表达式(简介)来接收变量。

变量名 使用方法 描述
entityName select x from #{#entityName} x 根据指定的Repository自动插入相关的entityName。
有两种方式能被解析出来:
(1)如果定义了@Entity注解,直接用其属性名
(2)如果没定义,直接用实体类的名称

在以下的例子中,我们在查询语句中插入表达式:

@Entity (’’User”) 
public class User {
@Id
@GeneratedValue 
Long id;
String lastname;
}
public interface UserRepository extends JpaRepository<User, Long> { 
@Query("select u from #{#entityName} u where u.lastname = ?1" )
List<User> findByLastname(String lastname);
}

四、@Modifying修改查询

可以通过在@Modifying注解实现只需要参数绑定的update查询执行:

@Modifying
@Query ("update User u set u. f irstname = ?1 where u. lastname = ?2’’)  
int setFixedFirstnameFor(String firstname, String lastname);

简单地针对某些特定属性的更新也可以直接用基类里面提供的通用save。还有第三种方法,就是自定义Repository,使用EntityManager来进行更新操作。用法如下:

interface UserRepository extends Repository<User,Long>(
void deleteByRoleId(long roleId);
@Modifying
@Query(”delete from User u where user.role.id= ?1”)
void deleteInBulkByRoleId(Long roleId);
}

五、@QueryHints

有很多数据库支持Hint Query的语法,不过这种查询支持比较老旧,感觉应该会慢慢被淘汰,工作中很少有人使用。Spring Data JPA还是做了很好的支持,它只支持一些固定的HintValue值,用来优化Query的作用。有两个注解需要了解和知道一下@QueryHints,value等于多个@QueryHint。

六、@Procedure储存过程的查询方法

我们通过@Procedure来介绍一下JPA对储存过程的支持。对于存储过程的使用,这里不做详解。

七、@NamedQueries预定义查询

在@Entity下增加@NamedQuery定义

public @interface Named Query(
//query的名称, 规则:实体.方法名;
String name() ;
//具体的JP QL查询语法
String query() ;

需要注意,query里面的值也是JPQL。查询参数也要和实体对应起来。因为实际场景中这种破坏Entity的侵入式很不美,也不方便,所以这种方式容易遗忘,工作中也很少推荐。

与之相对应的还有@NamedNativeQuery。用法一样,唯一不一样的是,query里面放置的是原生SQL语句,而非实体的字段名字

原文  https://cn-blogs.cn/archives/8466.html
正文到此结束
Loading...