Spring Data JPA - @NamedQueries 示例

x33g5p2x  于2022-02-19 转载在 Spring  
字(6.2k)|赞(0)|评价(0)|浏览(509)

在本教程中,我们将学习如何在 Spring Data JPA 中使用 @NamedQueries 注解创建多个命名 JPQL 查询。

好吧,我们使用来自 JPA 的 @NamedQueries 注释来定义多个 Named JPQL 查询。

定义命名 JPQL 查询的步骤

如果我们想创建一个命名的 JPQL 查询,我们必须遵循以下步骤:

  1. 使用来自 JPA 的 @NamedQueries 注释对实体进行注释:
@NamedQueries(
        {
                @NamedQuery(
                        name = "Product.findAllOrderByNameDesc",
                        query = "SELECT p from Product p ORDER By p.name DESC"
                ),
                @NamedQuery(
                        name = "Product.findByPrice",
                        query = "SELECT p from Product p where p.price = :price"
                )
        }
)
public class Product {}
  1. 使用来自 JPA/Hibernate 的多个 @NamedQuery 注释来定义命名查询:
@NamedQueries(
        {
                @NamedQuery(
                        name = "Product.findAllOrderByNameDesc",
                        query = "SELECT p from Product p ORDER By p.name DESC"
                ),
                @NamedQuery(
                        name = "Product.findByPrice",
                        query = "SELECT p from Product p where p.price = :price"
                )
        }
)
  1. 使用 @NamedQuery 注解的 name 属性设置命名查询的名称:
@NamedQuery(
        name = "Product.findByPrice",
        query = "SELECT p from Product p where p.price = :price"
)
  1. 使用 @NamedQuery 注解的 query 属性设置 JPQL 查询的值:
@NamedQuery(
        name = "Product.findByPrice",
        query = "SELECT p from Product p where p.price = :price"
)
  1. 在 Spring Data JPA 存储库中使用命名查询名称:
// Define Named JPQL query
    Product findByPrice(@Param("price") BigDecimal price);

    List<Product> findAllOrderByNameDesc();

让我们从头开始创建一个 Spring Boot 项目,并了解 Spring Data JPA 中 @NamedQueries 注解的用法。

1. 创建 Spring Boot 项目

Spring Boot 提供了一个名为 https://start.spring.io 的网络工具来快速引导应用程序。只需转到 https://start.spring.io 并生成一个新的 Spring Boot 项目。

在 Spring Boot 创建中使用以下详细信息:

项目名称: spring-data-jpa-course

**项目类型:**Maven

选择依赖项: Spring Data JPA、MySQL 驱动程序、Lombok

**包名:**net.javaguides.springboot

2. Maven 依赖项

这是完整的 pom.xml 供您参考:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.6.1</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>net.javaguides</groupId>
	<artifactId>spring-data-jpa-course</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>spring-data-jpa-course</name>
	<description>Demo project for Spring Boot</description>
	<properties>
		<java.version>11</java.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>

		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<scope>runtime</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

3.配置MySQL数据库

让我们使用 MySQL 数据库来存储和检索此示例中的数据,我们将使用 Hibernate 属性来创建和删除表。

打开 application.properties 文件并向其中添加以下配置:

spring.datasource.url=jdbc:mysql://localhost:3306/demo?useSSL=false
spring.datasource.username=root
spring.datasource.password=Mysql@123

spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5InnoDBDialect

spring.jpa.hibernate.ddl-auto = create-drop

确保在运行 Spring Boot 应用程序之前创建一个演示数据库。
此外,根据您机器上的 MySQL 安装更改 MySQL 用户名和密码。

4. 创建 JPA 实体 - Product.java

让我们在基础包“net.javaguides.springboot”中创建一个实体包。

在实体包中,创建具有以下内容的产品类:

import lombok.*;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;

import javax.persistence.*;
import java.math.BigDecimal;
import java.time.LocalDateTime;

@Entity
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString

@NamedQueries(
        {
                @NamedQuery(
                        name = "Product.findAllOrderByNameDesc",
                        query = "SELECT p from Product p ORDER By p.name DESC"
                ),
                @NamedQuery(
                        name = "Product.findByPrice",
                        query = "SELECT p from Product p where p.price = :price"
                )
        }
)
@Table(
        name = "products",
        schema = "ecommerce",
        uniqueConstraints = {
                @UniqueConstraint(
                        name = "sku_unique",
                        columnNames = "stock_keeping_unit"
                )
        }
)
public class Product {

    @Id
    @GeneratedValue(
            strategy = GenerationType.SEQUENCE,
            generator = "product_generator"
    )

    @SequenceGenerator(
            name = "product_generator",
            sequenceName = "product_sequence_name",
            allocationSize = 1
    )
    private Long id;

    @Column(name = "stock_keeping_unit", nullable = false)
    private String sku;

    @Column(nullable = false)
    private String name;

    private String description;
    private BigDecimal price;
    private boolean active;
    private String imageUrl;

    @CreationTimestamp
    private LocalDateTime dateCreated;

    @UpdateTimestamp
    private LocalDateTime lastUpdated;
}

请注意,我们使用 Lombok 注释来减少样板代码。

5. 创建 Spring Data JPA 存储库

我们要做的下一件事是创建一个存储库来访问数据库中的产品实体数据。

JpaRepository 接口定义了实体上所有 CRUD 操作的方法,以及名为 SimpleJpaRepository 的 JpaRepository 的默认实现。

让我们在基本包“net.javaguides.springdatarest”中创建一个存储库包。
在存储库包中,创建具有以下内容的 ProductRepository 接口:

import com.springdatajpa.springboot.entity.Product;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.query.Param;

import java.math.BigDecimal;


public interface ProductRepository extends JpaRepository<Product, Long> 
{
    // Define Named JPQL query
    Product findByPrice(@Param("price") BigDecimal price);
    List<Product> findAllOrderByNameDesc();
}

6. 测试命名的 JPQL 查询

import com.springdatajpa.springboot.entity.Product;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.math.BigDecimal;
import java.util.List;

@SpringBootTest
public class NamedQueriesTest {

    @Autowired
    private ProductRepository productRepository;

    @Test
    void namedJPQLQueries(){

        List<Product> products = productRepository.findAllOrderByNameDesc();

        products.forEach((p) -> {
            System.out.println(p.getName());
            System.out.println(p.getDescription());
        });

        Product product = productRepository.findByPrice(new BigDecimal(200));

        System.out.println(product.getName());
        System.out.println(product.getDescription());

    }
}

输出:

相关文章