Spring Data JPA - 排序示例

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

在之前的教程中,我们已经了解了如何使用 Spring Data JPA 实现分页。在本教程中,我们将学习如何使用 Spring Data JPA 实现排序。

Spring Data JPA 排序概述

要使用 Spring Data JPA 提供的分页和排序 API,您的存储库接口必须扩展 PagingAndSortingRepository 接口。

PagingAndSortingRepository 是 CrudRepository 的扩展,提供额外的方法来使用分页和排序抽象检索实体。它提供了两种方法:

  • Page findAll(Pageable pageable) - 返回满足 Pageable 对象中提供的分页限制的实体页面。
  • Iterable findAll(Sort sort) - 返回按给定选项排序的所​​有实体。此处不应用分页。
    以下是 PagingAndSortingRepository 接口的内部源代码:
@NoRepositoryBean
public interface PagingAndSortingRepository < T, ID > extends CrudRepository < T, ID > {

    /**
* Returns all entities sorted by the given options.
*
* @param sort
* @return all entities sorted by the given options
*/
    Iterable < T > findAll(Sort sort);

    /**
* Returns a {@link Page} of entities meeting the paging restriction provided in the {@codePageable} object.
*
* @param pageable
* @return a page of entities
*/
    Page < T > findAll(Pageable pageable);
}

JpaRepository 接口扩展了 PagingAndSortingRepository 接口,因此如果您的存储库接口是 JpaRepository 类型,则无需对其进行更改。
对于排序,我们将使用 PagingAndSortingRepository 接口中的以下方法:

Iterable < T > findAll(Sort sort);

注意: Spring Data JPA 具有 SimpleJPARepository 类,它实现了 PagingAndSortingRepository 接口方法,因此我们不必编写代码来实现 PagingAndSortingRepository 接口方法。

让我们从头开始创建一个 Spring Boot 项目,并使用 Spring Data JPA 实现排序。

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
@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> 
{

}

6. Spring Data JPA 排序实现

让我们编写 JUnit 测试,在 JUnit 测试中,我们将编写一个逻辑来使用 Spring Data JPA 实现排序:

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 org.springframework.data.domain.Sort;

import java.util.List;

@SpringBootTest
public class PaginationAndSortingTest {

    @Autowired
    private ProductRepository productRepository;

    @Test
    void sorting(){

        String sortBy = "price";
        String sortDir = "desc";

        Sort sort = sortDir.equalsIgnoreCase(Sort.Direction.ASC.name())?
                Sort.by(sortBy).ascending(): Sort.by(sortBy).descending();

        List<Product> products = productRepository.findAll(sort);

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

要在结果集中只应用排序,我们需要创建 Sort 对象并将其传递给 findAll() 方法

Sort sort = sortDir.equalsIgnoreCase(Sort.Direction.ASC.name())?
                Sort.by(sortBy).ascending(): Sort.by(sortBy).descending();

        List<Product> products = productRepository.findAll(sort);

输出:

运行 JUnit 测试后,您将获得以下输出:

请注意,Spring Data JPA 在后台使用 Hibernate 生成以下 SQL 查询以进行排序:

select
        product0_.id as id1_0_,
        product0_.active as active2_0_,
        product0_.date_created as date_cre3_0_,
        product0_.description as descript4_0_,
        product0_.image_url as image_ur5_0_,
        product0_.last_updated as last_upd6_0_,
        product0_.name as name7_0_,
        product0_.price as price8_0_,
        product0_.stock_keeping_unit as stock_ke9_0_ 
    from
        products product0_ 
    order by
        product0_.price desc

相关文章