Spring Data JPA 实战 - 注解式方法查询之@NamedQuery、@NamedNativeQuery

在 Spring Data JPA 中,除了通过定义方法签名来实现查询功能外,还可以使用注解来定义查询。其中两种常用的注解是 @NamedQuery@NamedNativeQuery

@NamedQuery

@NamedQuery 注解允许你在实体类上定义命名查询,这些查询是基于 JPQL(Java Persistence Query Language)的。一旦定义了命名查询,你就可以在你的 Repository 接口中通过名称引用这些查询。

示例

假设我们有一个 Product 实体类:

import javax.persistence.*;

@Entity
@Table(name = "products")
public class Product {

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

    private String name;
    private Double price;
    private Integer quantity;

    // 构造函数、getters 和 setters 省略

    // 定义一个命名查询
    @NamedQuery(
            name = "Product.findProductsByPrice",
            query = "SELECT p FROM Product p WHERE p.price <= :maxPrice"
    )
}

然后,在 Repository 接口中,你可以通过名称引用这个查询:

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface ProductRepository extends JpaRepository<Product, Long> {

    // 使用命名查询
    @Query(name = "Product.findProductsByPrice")
    List<Product> findProductsByPrice(Double maxPrice);
}

@NamedNativeQuery

@NamedNativeQuery 注解与 @NamedQuery 类似,但它是用来定义原生 SQL 查询的。这在你需要执行复杂的数据库特定查询时非常有用。

示例

同样以 Product 实体类为例:

import javax.persistence.*;

@Entity
@Table(name = "products")
public class Product {

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

    private String name;
    private Double price;
    private Integer quantity;

    // 构造函数、getters 和 setters 省略

    // 定义一个命名的原生 SQL 查询
    @NamedNativeQuery(
            name = "Product.findProductsByPriceNative",
            query = "SELECT * FROM products WHERE price <= ?1",
            resultSetMapping = "ProductMapping"
    )

    // 可选的结果集映射
    @SqlResultSetMapping(
            name = "ProductMapping",
            entities = @EntityResult(entityClass = Product.class,
                    fields = {
                            @FieldResult(name = "id", column = "id"),
                            @FieldResult(name = "name", column = "name"),
                            @FieldResult(name = "price", column = "price"),
                            @FieldResult(name = "quantity", column = "quantity")
                    }
            )
    )
}

在 Repository 接口中,你可以通过名称引用这个原生查询:

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface ProductRepository extends JpaRepository<Product, Long> {

    // 使用命名的原生查询
    @Query(name = "Product.findProductsByPriceNative", nativeQuery = true)
    List<Product> findProductsByPriceNative(Double maxPrice);
}

使用 @Query 注解

虽然 @NamedQuery@NamedNativeQuery 都很有用,但在实际应用中,@Query 注解通常更加灵活,因为它可以直接在 Repository 接口的方法上定义查询,而不是在实体类中定义。

示例

使用 @Query 直接在 Repository 接口中定义查询:

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface ProductRepository extends JpaRepository<Product, Long> {

    // 使用 @Query 定义 JPQL 查询
    @Query("SELECT p FROM Product p WHERE p.price <= :maxPrice")
    List<Product> findProductsByPrice(Double maxPrice);

    // 使用 @Query 定义原生 SQL 查询
    @Query(value = "SELECT * FROM products WHERE price <= ?1", nativeQuery = true)
    List<Product> findProductsByPriceNative(Double maxPrice);
}

总结

  • 使用 @NamedQuery@NamedNativeQuery 可以让你在实体类中定义命名查询,这样可以在 Repository 接口中直接引用。
  • @Query 注解则允许你直接在 Repository 接口中定义查询,提供更多的灵活性。

如果你想要尝试这些例子或有其他关于 Spring Data JPA 的问题,请随时告诉我!

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值