網頁

2021/6/8

Spring Data JPA @NamedQuery作用

Spring Data JPA @NamedQuery用法如下。


@NamedQuery與定義在Repository方法上的@Query類似,都可對Repository方法自訂JPQL查詢

@NamedQuery掛在@Entity類別前,可以直接撰寫JPQL查詢語言及對應的Repository查詢方法名稱,當呼叫Repository查詢方法時會以@NamedQuery定義的JPQL查詢。

例如下面是entity類Employee。類別名稱前加上@NamedQuery並在query定義EmployeeRepository.findByAge(int age)查詢時使用JPQL。對應的呼叫方法名稱設定在屬性name,要以entity類的名稱開頭後接點號再接方法名。

Employee

package com.abc.demo.entity;

import javax.persistence.*;
import java.io.Serializable;

@NamedQuery(
        name = "Employee.findByAge",
        query = "SELECT e FROM Employee e WHERE e.age = ?1"
)
@Entity
public class Employee implements Serializable {
    private static final Long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    private String name;

    private Integer age;
    
    // getters, setters, equals() and hashCode()

}

Employee的Repository類EmployeeRepository

EmployeeRepository

package com.abc.demo.repository;

import com.abc.demo.entity.Employee;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface EmployeeRepository extends JpaRepository<Employee, Long> {

    List<Employee> findByAge(int age); // 會以Employee的@NamedQuery.query設定的JPQL查詢
    
}

產生的SQL如下:

select employee0_.id as id1_1_, employee0_.age as age2_1_, employee0_.name as name3_1_ from employee employee0_ where employee0_.age=?

也可以改用名稱參數(Named Parameters)如下:

Employee

@NamedQuery(
        name = "Employee.findByAge",
        query = "SELECT e FROM Employee e WHERE e.age = :age"
)
@Entity
public class Employee implements Serializable {...}

EmployeeRepository

@Repository
public interface EmployeeRepository extends JpaRepository<Employee, Long> {

    List<Employee> findByAge(@Param("age") int age); // named parameters

}

@NamedQuery可設定多個。

Employee

@NamedQuery(
        name = "Employee.findByAge",
        query = "SELECT e FROM Employee e WHERE e.age = :age"
)
@NamedQuery(
        name = "Employee.findByName",
        query = "SELECT e FROM Employee e WHERE e.name = :name"
)
@Entity
public class Employee implements Serializable {...}

JPA 2.2及Hibernate 5.2以前若有多個@NamedQuery要用@NamedQueries包起。

Employee

@NamedQueries(
        {
                @NamedQuery(
                        name = "Employee.findByAge",
                        query = "SELECT e FROM Employee e WHERE e.age = :age"
                ),
                @NamedQuery(
                        name = "Employee.findByName",
                        query = "SELECT e FROM Employee e WHERE e.name = :name"
                )
        }
)
@Entity
public class Employee implements Serializable {...}

若要用原生SQL則改用@NamedNativeQuery

Employee

@NamedNativeQuery(
        name = "Employee.findByAge",
        query = "SELECT * FROM employee WHERE age = :age", // native sql
        resultClass = Employee.class
)
@Entity
public class Employee implements Serializable {...}

查詢的SQL如下:

SELECT * FROM employee WHERE age = ?


沒有留言:

張貼留言