spring data jpa 利用@Query進行查詢


介紹@Query注釋之前,先看看怎么利用@NamedQuery進行命名查詢

1.現在實體類上定義方法已經具體查詢語句

@Entity
@NamedQuery(name = "Task.findByTaskName",
  query = "select t from Task t where t.taskName = ?1")
public class Task{
 
}

 

2.然后我們繼承接口之后,就可以直接用這個方法了,它會執行我們定義好的查詢語句並返回結果

public interface TaskDao extends JpaRepository<Task, Long> {
  Task findByTaskName(String taskName);
}

 

試想一下,如果我們想自己定義執行查詢,利用命名查詢,顯然不行,因為,會在實體類上寫很多的@NamedQuery,這種情況的話,我們可以用@Query直接在方法上定義查詢語句,例如這樣

public interface TaskDao extends JpaRepository<Task, Long> {
  @Query("select t from Task t where t.taskName = ?1")
  Task findByTaskName(String taskName);
}

 

@Query上面的1代表的是方法參數里面的順序,除了寫hql,我們還可以寫sql語句

public interface TaskDao extends JpaRepository<Task, Long> {
  @Query("select * from tb_task t where t.task_name = ?1", nativeQuery = true)
  Task findByTaskName(String taskName);
}

 

在參數綁定上,我們還可以這樣子用

public interface TaskDao extends JpaRepository<Task, Long> {
   @Query("select t from Task t where t.taskName = :taskName and t.createTime = :createTime")
  Task findByTaskName(@Param("taskName")String taskName,@Param("createTime") Date createTime);
}

 

當然在參數綁定上,我們還可以直寫問號

public interface TaskDao extends JpaRepository<Task, Long> {
   @Query("select t from Task t where t.taskName = ? and t.createTime = ?")
  Task findByTaskName(String taskName, Date createTime);
}

 

再利用SpEL表達式,我們把實體類寫成動態的

public interface TaskDao extends JpaRepository<Task, Long> {
   @Query("select t from #{#entityName} t where t.taskName = ? and t.createTime = ?")
  Task findByTaskName(String taskName, Date createTime);
}

 

這個的作用就是,當倆個實體類都有共同的父類的時候,例如這樣

// JPA 基類的標識
@MappedSuperclass
@SuppressWarnings("serial")
public abstract class IdEntity implements Serializable{
    protected Long id;
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
}
 
@Entity
public class Task extends IdEntity{
 
}
 
@Entity
public class Project extends IdEntity{
 
}

 

然后有一個通用的接口

public interface GenericDao<T> extends JpaRepository<T, ID> { 
  @Query("select t from #{#entityName} t where t.id= ?1")
   public T findById(Long id);   
}

 

再然后就taskDao和projectDao來繼承這個接口,這樣子的話,把公用的方法放在通用接口上,就不用重復寫方法了。

好,下面再說下,利用@Modifying進行更新

@Modifying
@Query("update Task t set t.taskName = ?1 where t.id = ?2")
int updateTask(String taskName, Long id);

 

在這里我們說下,spring data jpa的查詢策略,spring data jpa可以利用創建方法進行查詢,也可以利用@Query注釋進行查詢,那么如果在命名規范的方法上使用了@Query,那spring data jpa是執行我們定義的語句進行查詢,還是按照規范的方法進行查詢呢?看下查詢策略

查詢策略的配置可以在配置query-lookup-strategy,例如這樣

    <jpa:repositories base-package="com.liuxg.**.dao"
        repository-impl-postfix="Impl" 
        query-lookup-strategy = "create-if-not-found"
        entity-manager-factory-ref="entityManagerFactory"
        transaction-manager-ref="transactionManager" >
    </jpa:repositories>

 

他有三種值可以配置

  1. create-if-not-found(默認):如果通過 @Query指定查詢語句,則執行該語句,如果沒有,則看看有沒有@NameQuery指定的查詢語句,如果還沒有,則通過解析方法名進行查詢

  2. create:通過解析方法名字來創建查詢。即使有 @Query,@NameQuery都會忽略

  3. use-declared-query:通過執行@Query定義的語句來執行查詢,如果沒有,則看看有沒有通過執行@NameQuery來執行查詢,還沒有則拋出異常


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM