Spring Data JPA 入门

内容分享21小时前发布
0 0 0
  • 什么是 Spring Data JPA

Spring Data JPA 是 Spring Data 项目家族的一部分,是对 JPA 规范的一个轻量级封装和扩展,旨在简化 JPA 的开发,提高开发效率,同时不失灵活性和强劲的特性。它提供了一种简单、一致的方式来访问不同种类的数据源,包括关系数据库、非关系数据库、MapReduce 框架等。Spring Data JPA 还提供了一些高级特性,如动态查询、多表查询、嵌套查询、存储过程和函数调用等。

  • Spring Data JPA 的优势和不足

Spring Data JPA 的优势包括:封装了 JPA 的细节,提供了更高层次的抽象,简化了数据访问层的开发,提高了开发效率;支持多种数据源,包括关系型数据库和非关系型数据库;提供了一些高级特性,如动态查询、多表查询、嵌套查询、存储过程和函数调用等;可与其他 Spring 框架无缝集成,如 Spring Boot、Spring Cloud 等。

Spring Data JPA 的不足包括:对于一些复杂的查询,仍需要手动编写 SQL 语句;默认的实现可能存在性能问题,需要手动优化。

  • Spring Data JPA 的架构和基本原理

Spring Data JPA 的架构基于 Spring Data 的一些核心概念,如 Repository 和查询方法。Repository 是一种在领域模型和数据访问层之间提供中介的模式,通过它可以简化数据访问层的代码,提高开发效率。在 Spring Data JPA 中,Repository 是一个接口,它继承了 JPA 的基础 Repository 接口,同时提供了一些自定义的方法。这些方法可以通过命名约定自动生成查询语句,从而简化了查询操作的开发。除了自动生成查询语句,还可以使用 @Query 注解来手动编写查询语句。查询方法可以使用属性表达式、关键字、运算符等来构建查询条件。查询方法还可以通过分页、排序等方式来限制查询结果的数量和顺序。Spring Data JPA 还提供了一些高级特性,如动态查询、多表查询、嵌套查询、存储过程和函数调用等。这些特性都是基于 JPA 规范的扩展,可以协助开发人员更加灵活地访问数据源。

Spring Data JPA 基础

  • Spring Data JPA 的配置和使用

Spring Data JPA 是 Spring Data 项目家族的一部分,是对 JPA 规范的一个轻量级封装和扩展,旨在简化 JPA 的开发,提高开发效率,同时不失灵活性和强劲的特性。它提供了一种简单、一致的方式来访问不同种类的数据源,包括关系数据库、非关系数据库、MapReduce 框架等。Spring Data JPA 还提供了一些高级特性,如动态查询、多表查询、嵌套查询、存储过程和函数调用等。

在使用 Spring Data JPA 进行数据访问时,需要完成一些基本的配置和使用步骤。第一,需要在项目的 pom.xml 文件中添加 Maven 依赖项,以便能够使用 Spring Data JPA。例如,可以添加以下依赖项:

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-data-jpa</artifactId>

</dependency>

其次,需要在 application.properties 或 application.yml 文件中配置数据源信息,例如:

spring.datasource.url=jdbc:mysql://localhost:3306/mydb

spring.datasource.username=root

spring.datasource.password=root

spring.datasource.driver-class-name=com.mysql.jdbc.Driver

在完成数据源的配置后,需要定义与数据库表相对应的实体类,并使用 JPA 注解来映射实体类和数据库表之间的关系。例如:

@Entity

@Table(name = “user”)

public class User {

@Id

@GeneratedValue(strategy = GenerationType.IDENTITY)

private Long id;

@Column(name = “username”)

private String username;

@Column(name = “password”)

private String password;

// 省略 getter 和 setter 方法

}

在上述代码中,@Entity 注解表明该类是一个 JPA 实体,@Table 注解指定了实体类对应的数据库表名,@Id 注解表明该属性是主键,@GeneratedValue 注解表明该属性的值由数据库自动生成,@Column 注解指定了属性对应的数据库列名。

在定义了实体类之后,需要定义一个继承 JpaRepository 接口的 Repository 接口,用于访问实体类对应的数据库表。例如:

public interface UserRepository extends JpaRepository<User, Long> {

User findByUsername(String username);

}

在上述代码中,UserRepository 接口继承了 JpaRepository 接口,并指定了实体类为 User,主键类型为 Long。findByUsername 方法可以根据用户名从数据库中查找用户信息。

最后,通过注入 UserRepository 接口的实例来使用它提供的方法。例如:

@Service

public class UserService {

@Autowired

private UserRepository userRepository;

public User getUserByUsername(String username) {

return userRepository.findByUsername(username);

}

}

在上述代码中,UserService 类通过 @Autowired 注解注入了 UserRepository 接口的实例,并使用 findByUsername 方法从数据库中查找用户信息。

除了基本的配置和使用之外,Spring Data JPA 还提供了许多高级特性,如多表查询、动态查询、嵌套查询、存储过程和函数调用等。这些特性都是基于 JPA 规范的扩展,可以协助开发人员更加灵活地访问数据源。同时,为了保证应用程序的性能和可靠性,还需要注意事务管理、缓存配置、数据库连接池配置等方面。

在使用 Spring Data JPA 进行数据访问时,需要根据实际情况选择合适的配置和使用方式,以达到最佳的开发效率和性能表现。例如,在配置数据源时,可以使用 Spring Boot 的自动配置特性,减少手动配置的工作量。同时,在定义 Repository 接口时,可以使用 Spring Data JPA 提供的命名约定来自动生成查询语句,也可以使用 @Query 注解来手动编写查询语句,以满足不同的查询需求。在使用高级特性时,需要充分了解 JPA 规范和 Spring Data JPA 的扩展特性,以确保正确和高效地使用这些功能。同时,在保证应用程序稳定性和可靠性的前提下,需要进行适当的性能优化,例如,使用缓存来减少数据库访问次数,使用连接池来提高数据库访问效率等。

总之,Spring Data JPA 是一个功能强劲、易于使用的数据访问框架,可以协助开发人员快速、高效地访问各种数据源。在使用 Spring Data JPA 进行数据访问时,需要熟悉其基本原理和使用方式,了解其高级特性和最佳实践,并根据实际情况进行选择和优化,以达到最佳的开发效率和性能表现。

  • 基本 CRUD 操作

Spring Data JPA 提供了一些基本的 CRUD 操作,包括新增、查询、修改和删除等。这些操作可以通过继承 JpaRepository 接口来实现。继承 JpaRepository 接口后,就可以直接使用它提供的方法来完成对数据库的操作,而不需要编写复杂的 SQL 语句。这些操作包括了常用的增删改查操作,例如:新增实体对象、删除实体对象、根据主键查询实体对象、查询所有实体对象、查询实体对象的总数等。

具体来说,JpaRepository 接口提供了以下一些常用的方法:

  • save(entity):新增或更新实体对象
  • delete(entity):删除实体对象
  • deleteById(id):根据主键删除实体对象
  • findById(id):根据主键查询实体对象
  • findAll():查询所有实体对象
  • count():查询实体对象的总数

在使用这些方法时,可以直接调用 UserRepository 接口的方法。例如,在 UserService 类中,我们可以通过以下方式来完成新增、删除、查询和统计操作:

@Service

public class UserService {

@Autowired

private UserRepository userRepository;

public void addUser(User user) {

userRepository.save(user);

}

public void deleteUser(Long id) {

userRepository.deleteById(id);

}

public User getUser(Long id) {

return userRepository.findById(id).orElse(null);

}

public List<User> getAllUsers() {

return userRepository.findAll();

}

public long countUsers() {

return userRepository.count();

}

}

在上述代码中,UserService 类通过 @Autowired 注解注入了 UserRepository 接口的实例,并使用它提供的方法来完成新增、删除、查询和统计操作。这样,我们就可以超级方便地操作实体对象,而不需要编写繁琐的 SQL 语句。

除了基本的 CRUD 操作之外,JpaRepository 接口还提供了一些高级特性,如动态查询、多表查询、嵌套查询、存储过程和函数调用等。这些特性都是基于 JPA 规范的扩展,可以协助开发人员更加灵活地访问数据源。例如,可以通过使用 @Query 注解来手动编写查询语句,或者使用 Spring Data JPA 提供的命名约定来自动生成查询语句。同时,在定义 Repository 接口时,可以使用 JPA 提供的关联注解来实现多表查询,或者使用 Specification 对象来实现动态查询。这些高级特性可以协助我们更加灵活地访问数据源,满足不同的查询需求。

同时,为了保证应用程序的性能和可靠性,还需要注意事务管理、缓存配置、数据库连接池配置等方面。在 Spring Data JPA 中,可以使用 @Transactional 注解来实现事务管理,使用 Spring Cache 来实现缓存配置,使用 HikariCP 来实现数据库连接池配置等。这些技术可以协助我们提高应用程序的性能和可靠性,提高开发效率。

总之,Spring Data JPA 是一个功能强劲、易于使用的数据访问框架,可以协助开发人员快速、高效地访问各种数据源。在使用 Spring Data JPA 进行数据访问时,需要熟悉其基本原理和使用方式,了解其高级特性和最佳实践,并根据实际情况进行选择和优化,以达到最佳的开发效率和性能表现。

Spring Data JPA 高级应用

  • 多表查询

Spring Data JPA 提供了一些高级特性,如动态查询、多表查询、嵌套查询、存储过程和函数调用等。其中,多表查询是一个超级常见的需求。在 Spring Data JPA 中,可以使用 JPA 提供的关联注解来实现多表查询,例如 @OneToOne、@OneToMany、@ManyToOne、@ManyToMany 等注解。这些注解可以用来定义两个实体类之间的关联关系,并通过关联属性来访问关联实体。例如,我们可以定义一个 Order 实体类和一个 OrderItem 实体类,并使用 @OneToMany 注解来定义它们之间的关联关系:

@Entity

@Table(name = “order”)

public class Order {

@Id

@GeneratedValue(strategy = GenerationType.IDENTITY)

private Long id;

@Column(name = “order_no”)

private String orderNo;

@OneToMany(mappedBy = “order”)

private List<OrderItem> orderItems;

// 省略 getter 和 setter 方法

}

@Entity

@Table(name = “order_item”)

public class OrderItem {

@Id

@GeneratedValue(strategy = GenerationType.IDENTITY)

private Long id;

@Column(name = “product_name”)

private String productName;

@Column(name = “quantity”)

private Integer quantity;

@ManyToOne(fetch = FetchType.LAZY)

@JoinColumn(name = “order_id”)

private Order order;

// 省略 getter 和 setter 方法

}

在上述代码中,Order 实体类和 OrderItem 实体类之间使用 @OneToMany 注解来定义一对多的关联关系。其中,@OneToMany 注解的 mappedBy 属性指定了 OrderItem 实体类中与 Order 实体类关联的属性名为 order。而在 OrderItem 实体类中,使用 @ManyToOne 注解来定义多对一的关联关系,其中,@JoinColumn 注解指定了与 Order 实体类关联的外键列名为 order_id。

在定义了实体类之后,就可以使用它们来进行多表查询了。例如,我们可以定义一个 OrderService 类,并使用 Spring Data JPA 提供的方法来查询订单和订单项的信息:

@Service

public class OrderService {

@Autowired

private OrderRepository orderRepository;

public List<Order> getOrdersByProductName(String productName) {

return orderRepository.findByOrderItemsProductName(productName);

}

}

在上述代码中,OrderService 类通过 @Autowired 注解注入了 OrderRepository 接口的实例,并使用它提供的
findByOrderItemsProductName 方法来查询所有包含指定产品名称的订单信息。在该方法中,我们可以使用 Spring Data JPA 提供的命名约定来自动生成查询语句,其中 findByOrderItems 表明查询 Order 实体类中所有包含指定关联实体类的订单信息,而 ProductName 表明查询关联实体类中所有包含指定产品名称的订单项信息。

除了使用命名约定外,我们还可以使用 @Query 注解来手动编写查询语句。例如:

public interface OrderRepository extends JpaRepository<Order, Long> {

@Query(“select o from Order o join o.orderItems i where i.productName = :productName”)

List<Order> findByProductName(@Param(“productName”) String productName);

}

在上述代码中,OrderRepository 接口使用 @Query 注解来定义查询语句,其中 select o from Order o join o.orderItems i 表明查询 Order 实体类中所有包含指定关联实体类的订单信息,而 where i.productName = :productName 表明查询关联实体类中所有包含指定产品名称的订单项信息。

总之,多表查询是 Spring Data JPA 中一个超级常见的需求,可以通过 JPA 提供的关联注解来定义实体类之间的关联关系,并使用 Spring Data JPA 提供的方法来进行查询。除此之外,还可以使用 @Query 注解来手动编写查询语句,以满足不同的查询需求。在使用多表查询时,需要注意事务管理、缓存配置、数据库连接池配置等方面,以保证应用程序的性能和可靠性。

  • 动态查询

在 Spring Data JPA 中,动态查询是一种超级常见的需求,它可以根据不同的查询条件动态地生成查询语句,以实现更加灵活和高效的数据访问。Spring Data JPA 提供了多种方式来实现动态查询,包括使用 Specification 对象、使用 Querydsl、使用 JPA Criteria 等。下面,我们将介绍其中的一些方法。

使用 Specification 对象

Specification 对象是 Spring Data JPA 中用于动态查询的一种常用方式。它可以根据不同的查询条件动态地生成查询语句,并在查询时自动将这些条件转换为查询条件。使用 Specification 对象进行动态查询的步骤如下:

  1. 定义 Specification 接口

public interface UserSpecification {

Specification<User> findUsersByCriteria(UserSearchCriteria criteria);

}

  1. 实现 Specification 接口

public class UserSpecificationImpl implements UserSpecification {

@Override

public Specification<User> findUsersByCriteria(UserSearchCriteria criteria) {

return (root, query, builder) -> {

List<Predicate> predicates = new ArrayList<>();

if (criteria.getName() != null) {

predicates.add(builder.like(root.get(“name”), “%” + criteria.getName() + “%”));

}

if (criteria.getGender() != null) {

predicates.add(builder.equal(root.get(“gender”), criteria.getGender()));

}

if (criteria.getAge() != null) {

predicates.add(builder.greaterThanOrEqualTo(root.get(“age”), criteria.getAge()));

}

return builder.and(predicates.toArray(new Predicate[0]));

};

}

}

在上述代码中,我们定义了一个 UserSpecification 接口,并实现了它的 findUsersByCriteria 方法。该方法接收一个 UserSearchCriteria 对象作为参数,并返回一个 Specification<User> 对象。在该方法中,我们使用 Lambda 表达式来定义一个 Predicate 对象,该对象表明了根据查询条件生成的查询语句。具体来说,我们根据 UserSearchCriteria 对象中的属性值来构建 Predicate 对象,例如,如果 name 属性不为空,则使用 builder.like 方法生成一个模糊查询条件,如果 gender 属性不为空,则使用 builder.equal 方法生成一个等于查询条件,如果 age 属性不为空,则使用
builder.greaterThanOrEqualTo 方法生成一个大于等于查询条件。最后,我们使用 builder.and 方法将这些查询条件组合成一个整体的查询条件,并返回该条件。

  1. 在 Repository 接口中使用 Specification 对象

@Repository

public interface UserRepository extends JpaRepository<User, Long>, JpaSpecificationExecutor<User> {

}

在上述代码中,我们在 UserRepository 接口中继承了 JpaSpecificationExecutor<User> 接口,该接口提供了多个方法,可以用于执行动态查询操作。例如,我们可以使用 findAll 方法来执行动态查询操作,例如:

@Autowired

private UserRepository userRepository;

@Autowired

private UserSpecification userSpecification;

public List<User> findUsersByCriteria(UserSearchCriteria criteria) {

Specification<User> specification = userSpecification.findUsersByCriteria(criteria);

return userRepository.findAll(specification);

}

在上述代码中,我们通过 @Autowired 注解注入了 UserRepository 接口和 UserSpecification 接口的实例。然后,我们调用
userSpecification.findUsersByCriteria 方法来根据查询条件生成 Specification<User> 对象,并使用 UserRepository 接口的 findAll 方法来执行动态查询操作。

使用 Querydsl

Querydsl 是一种基于 Java 的类型安全查询框架,可以用于动态查询和静态查询等多种场景。在 Spring Data JPA 中,可以使用 Querydsl 来实现动态查询操作。使用 Querydsl 进行动态查询的步骤如下:

  1. 添加 Querydsl 依赖

<dependency>

<groupId>com.querydsl</groupId>

<artifactId>querydsl-jpa</artifactId>

<version>4.4.0</version>

</dependency>

<dependency>

<groupId>com.querydsl</groupId>

<artifactId>querydsl-apt</artifactId>

<version>4.4.0</version>

<scope>provided</scope>

</dependency>

  1. 定义 Q 实体类

public class QUser extends EntityPathBase<User> {

public static final QUser user = new QUser(“user”);

public final NumberPath<Long> id = createNumber(“id”, Long.class);

public final StringPath name = createString(“name”);

public final StringPath gender = createString(“gender”);

public final NumberPath<Integer> age = createNumber(“age”, Integer.class);

public QUser(String variable) {

super(User.class, variable);

}

}

在上述代码中,我们定义了一个 QUser 类,该类继承了 EntityPathBase<User> 类,并定义了 User 实体类中的各个属性。在该类中,我们使用 createNumber 方法和 createString 方法来定义属性的类型,并使用 createNumber 方法的第二个参数来指定属性的类型。同时,我们还可以为属性指定别名,例如,使用 createString(“name”) 方法来为 name 属性指定别

  • 嵌套查询

在 Spring Data JPA 中,可以使用 JPA 提供的关联注解来实现多表查询,例如 @OneToOne、@OneToMany、@ManyToOne、@ManyToMany 等注解。这些注解可以用来定义两个实体类之间的关联关系,并通过关联属性来访问关联实体。嵌套查询是其中一个常见的查询需求,它可以用于查询两个或多个实体类之间的关联关系,并根据关联实体类的属性值来筛选符合条件的结果。

具体来说,嵌套查询可以分为两种类型:内连接查询和外连接查询。内连接查询用于查询两个或多个实体类之间的交集,即只返回两个实体类中都存在的记录。而外连接查询则用于查询两个或多个实体类之间的并集,即返回两个实体类中所有的记录,同时将不存在关联关系的记录填充为 null 值。

在 Spring Data JPA 中,可以使用 JPA 提供的关联注解来定义两个实体类之间的关联关系,并使用 Spring Data JPA 提供的方法来进行嵌套查询。例如,我们可以定义一个 Order 实体类和一个 Customer 实体类,并使用 @ManyToOne 注解来定义它们之间的关联关系:

@Entity

@Table(name = “order”)

public class Order {

@Id

@GeneratedValue(strategy = GenerationType.IDENTITY)

private Long id;

@Column(name = “order_no”)

private String orderNo;

@ManyToOne(fetch = FetchType.LAZY)

@JoinColumn(name = “customer_id”)

private Customer customer;

// 省略 getter 和 setter 方法

}

@Entity

@Table(name = “customer”)

public class Customer {

@Id

@GeneratedValue(strategy = GenerationType.IDENTITY)

private Long id;

@Column(name = “name”)

private String name;

@OneToMany(mappedBy = “customer”)

private List<Order> orders;

// 省略 getter 和 setter 方法

}

在上述代码中,Order 实体类和 Customer 实体类之间使用 @ManyToOne 注解来定义多对一的关联关系。其中,@JoinColumn 注解指定了与 Customer 实体类关联的外键列名为 customer_id。而在 Customer 实体类中,使用 @OneToMany 注解来定义一对多的关联关系,其中,@OneToMany 注解的 mappedBy 属性指定了 Order 实体类中与 Customer 实体类关联的属性名为 customer。

在定义了实体类之后,就可以使用它们来进行嵌套查询了。例如,我们可以定义一个 OrderService 类,并使用 Spring Data JPA 提供的方法来查询订单和客户的信息:

@Service

public class OrderService {

@Autowired

private OrderRepository orderRepository;

public List<Order> getOrdersByCustomerName(String customerName) {

return orderRepository.findByCustomerName(customerName);

}

}

在上述代码中,OrderService 类通过 @Autowired 注解注入了 OrderRepository 接口的实例,并使用它提供的 findByCustomerName 方法来查询所有属于指定客户的订单信息。在该方法中,我们可以使用 Spring Data JPA 提供的命名约定来自动生成查询语句,其中 findByCustomer 表明查询 Order 实体类中所有属于指定关联实体类的订单信息,而 Name 表明查询关联实体类中指定客户的名称。

除了使用命名约定外,我们还可以使用 @Query 注解来手动编写查询语句。例如:

public interface OrderRepository extends JpaRepository<Order, Long> {

@Query(“select o from Order o join o.customer c where c.name = :customerName”)

List<Order> findByCustomerName(@Param(“customerName”) String customerName);

}

在上述代码中,OrderRepository 接口使用 @Query 注解来定义查询语句,其中 select o from Order o join o.customer c 表明查询 Order 实体类中所有属于指定关联实体类的订单信息,而 where c.name = :customerName 表明查询关联实体类中指定客户的名称。

总之,嵌套查询是 Spring Data JPA 中一个超级常见的需求,可以通过 JPA 提供的关联注解来定义实体类之间的关联关系,并使用 Spring Data JPA 提供的方法来进行查询。除此之外,还可以使用 @Query 注解来手动编写查询语句,以满足不同的查询需求。在使用嵌套查询时,需要注意事务管理、缓存配置、数据库连接池配置等方面,以保证应用程序的性能和可靠性。

  • 存储过程和函数调用

在 Spring Data JPA 中,可以使用 @NamedStoredProcedureQuery 注解和 EntityManager 类的
createStoredProcedureQuery 方法来调用存储过程和函数。具体来说,调用存储过程和函数的步骤如下:

  1. 定义存储过程或函数

CREATE PROCEDURE get_user_by_id(IN user_id INT, OUT user_name VARCHAR(50))

BEGIN

SELECT name INTO user_name FROM user WHERE id = user_id;

END;

在上述代码中,我们定义了一个名为 get_user_by_id 的存储过程,该存储过程接收一个 user_id 参数,并返回一个 user_name 参数,用于返回查询到的姓名信息。

  1. 在实体类中定义 @NamedStoredProcedureQuery 注解

@Entity

@NamedStoredProcedureQuery(

name = “getUserById”,

procedureName = “get_user_by_id”,

parameters = {

@StoredProcedureParameter(mode = ParameterMode.IN, name = “user_id”, type = Integer.class),

@StoredProcedureParameter(mode = ParameterMode.OUT, name = “user_name”, type = String.class)

}

)

public class User {

// …

}

在上述代码中,我们在 User 实体类上定义了一个 @NamedStoredProcedureQuery 注解,该注解包含了存储过程的相关信息,包括 name 属性、procedureName 属性和 parameters 属性。其中,name 属性用于指定该存储过程的名称,procedureName 属性用于指定该存储过程在数据库中的名称,parameters 属性用于指定该存储过程的参数信息,包括参数的名称、类型和模式。

  1. 使用 EntityManager 类的 createStoredProcedureQuery 方法调用存储过程

@Service

public class UserService {

@PersistenceContext

private EntityManager entityManager;

public String getUserById(Integer userId) {

StoredProcedureQuery storedProcedure = entityManager.createStoredProcedureQuery(“getUserById”);

storedProcedure.registerStoredProcedureParameter(“user_id”, Integer.class, ParameterMode.IN);

storedProcedure.registerStoredProcedureParameter(“user_name”, String.class, ParameterMode.OUT);

storedProcedure.setParameter(“user_id”, userId);

storedProcedure.execute();

return (String) storedProcedure.getOutputParameterValue(“user_name”);

}

}

在上述代码中,我们定义了一个 UserService 类,并使用 @PersistenceContext 注解注入了 EntityManager 类的实例。然后,我们调用
entityManager.createStoredProcedureQuery 方法来创建一个 StoredProcedureQuery 对象,并指定要调用的存储过程的名称。接下来,我们使用
registerStoredProcedureParameter 方法来注册存储过程的参数信息,包括参数的名称、类型和模式。然后,我们使用 setParameter 方法来设置存储过程的输入参数值,使用 execute 方法来执行存储过程,最后使用 getOutputParameterValue 方法来获取存储过程的输出参数值。

除了调用存储过程外,我们还可以使用类似的方式来调用数据库函数,例如:

@Service

public class UserService {

@PersistenceContext

private EntityManager entityManager;

public Integer getUserCount() {

Query query = entityManager.createNativeQuery(“SELECT COUNT(*) FROM user”);

return ((BigInteger) query.getSingleResult()).intValue();

}

}

在上述代码中,我们定义了一个 getUserCount 方法,该方法使用
entityManager.createNativeQuery 方法来创建一个原生查询对象,并执行 SQL 语句来查询 user 表中的记录数量。最后,我们使用 getSingleResult 方法来获取查询结果,并将结果转换为 Integer 类型返回。

总之,调用存储过程和函数是 Spring Data JPA 中一个超级常见的需求,可以使用 @NamedStoredProcedureQuery 注解和 EntityManager 类的
createStoredProcedureQuery 方法来完成。在调用存储过程和函数时,需要注意参数的注册、输入和输出,以及查询结果的处理方式。

  • 自定义 Repository

在 Spring Data JPA 中,可以通过自定义 Repository 接口和实现类来扩展 Spring Data JPA 的功能,以满足不同的业务需求。自定义 Repository 主要涉及到以下几个方面:定义 Repository 接口、定义实现类、使用 @RepositoryDefinition 注解、使用 @Query 注解和使用 EntityManager 类等。具体来说:

  1. 定义 Repository 接口

自定义 Repository 第一需要定义一个 Repository 接口,并继承 JpaRepository 接口或其子接口。例如,我们可以定义一个 UserRepository 接口,用于操作 User 实体类:

public interface UserRepository extends JpaRepository<User, Long> {

List<User> findByLastName(String lastName);

}

在上述代码中,我们定义了一个 UserRepository 接口,并继承了 JpaRepository 接口。其中,findByLastName 方法用于根据指定的 lastName 属性值来查询 User 实体类的记录。

  1. 定义实现类

自定义 Repository 的实现类需要实现自定义的 Repository 接口,并使用 @Repository 注解将其标记为 Spring Bean。例如,我们可以定义一个 UserRepositoryImpl 类,用于实现 UserRepository 接口的方法:

@Repository

public class UserRepositoryImpl implements UserRepository {

@Autowired

private EntityManager entityManager;

@Override

public List<User> findByLastName(String lastName) {

Query query = entityManager.createQuery(“SELECT u FROM User u WHERE u.lastName = :lastName”);

query.setParameter(“lastName”, lastName);

return query.getResultList();

}

}

在上述代码中,我们定义了一个 UserRepositoryImpl 类,并使用 @Repository 注解将其标记为 Spring Bean。其中,findByLastName 方法使用 EntityManager 类的 createQuery 方法来创建一个查询对象,并使用 setParameter 方法来设置查询参数的值。最后,使用 getResultList 方法来获取查询结果并返回。

  1. 使用 @RepositoryDefinition 注解

除了定义 Repository 接口和实现类以外,还可以使用 @RepositoryDefinition 注解来定义自定义的 Repository。例如,我们可以定义一个 UserRepository2 接口,并使用 @RepositoryDefinition 注解来标记它:

@RepositoryDefinition(domainClass = User.class, idClass = Long.class)

public interface UserRepository2 {

List<User> findByLastName(String lastName);

}

在上述代码中,我们使用 @RepositoryDefinition 注解来定义了一个 UserRepository2 接口,其中 domainClass 属性用于指定该 Repository 操作的实体类,idClass 属性用于指定实体类的主键类型。

  1. 使用 @Query 注解

除了使用自定义的 Repository 接口和实现类外,还可以使用 @Query 注解来定义查询方法。例如,我们可以在 UserRepository 接口中定义一个使用 @Query 注解的查询方法:

public interface UserRepository extends JpaRepository<User, Long> {

@Query(“SELECT u FROM User u WHERE u.lastName = :lastName”)

List<User> findByLastName(@Param(“lastName”) String lastName);

}

在上述代码中,我们使用 @Query 注解来定义了一个查询方法,其中 value 属性用于指定查询语句,@Param 注解用于指定查询参数的名称。

  1. 使用 EntityManager 类

除了使用以上方法外,还可以使用 EntityManager 类来执行自定义的查询操作。例如,我们可以在 UserRepository 接口中定义一个使用 EntityManager 类的查询方法:

public interface UserRepository extends JpaRepository<User, Long> {

List<User> findByLastName(String lastName);

List<User> findByFirstNameAndLastName(String firstName, String lastName);

}

在上述代码中,我们定义了一个 UserRepository 接口,并定义了两个查询方法。其中,
findByFirstNameAndLastName 方法使用 EntityManager 类的 createQuery 方法来创建一个查询对象,并使用 setParameter 方法来设置查询参数的值。最后,使用 getResultList 方法来获取查询结果并返回。

总之,自定义 Repository 是 Spring Data JPA 中一个超级常见的需求,可以通过定义 Repository 接口、定义实现类、使用 @RepositoryDefinition 注解、使用 @Query 注解和使用 EntityManager 类等方式来实现。在自定义 Repository 时,需要注意事务管理、缓存配置、数据库连接池配置等方面,以保证应用程序的性能和可靠性。

  • JPQL 查询和本地查询

在 Spring Data JPA 中,可以使用 JPQL 查询和本地查询来查询数据库中的数据。JPQL 查询是基于实体类和字段的查询,可以通过 EntityManager 类的 createQuery 或 createNamedQuery 方法来创建查询对象,并使用 setParameter 方法来设置查询参数的值。例如,我们可以在 UserRepository 接口中定义一个 JPQL 查询方法:

public interface UserRepository extends JpaRepository<User, Long> {

@Query(“SELECT u FROM User u WHERE u.lastName = ?1”)

List<User> findByLastName(String lastName);

}

在上述代码中,我们使用 @Query 注解来定义了一个 JPQL 查询方法,其中 value 属性用于指定查询语句,?1 表明该查询语句的第一个参数。这个查询方法可以通过调用 UserRepository 接口中的 findByLastName 方法来实现。

本地查询是基于 SQL 语句的查询,可以使用 EntityManager 类的 createNativeQuery 方法来创建查询对象,例如:

@Service

public class UserService {

@PersistenceContext

private EntityManager entityManager;

public Integer getUserCount() {

Query query = entityManager.createNativeQuery(“SELECT COUNT(*) FROM user”);

return ((BigInteger) query.getSingleResult()).intValue();

}

}

在上述代码中,我们定义了一个 getUserCount 方法,该方法使用
entityManager.createNativeQuery 方法来创建一个原生查询对象,并执行 SQL 语句来查询 user 表中的记录数量。最后,我们使用 getSingleResult 方法来获取查询结果,并将结果转换为 Integer 类型返回。

总之,JPQL 查询和本地查询是 Spring Data JPA 中常用的查询方式,可以通过 EntityManager 类的方法来创建查询对象,并使用 setParameter 方法来设置查询参数的值。在使用 JPQL 查询和本地查询时,需要注意事务管理、缓存配置、数据库连接池配置等方面,以保证应用程序的性能和可靠性。

  • 批量操作和删除

在 Spring Data JPA 中,有时需要对数据库中的多个记录进行批量操作或删除。Spring Data JPA 提供了一些方法来实现这些需求。具体来说:

  1. 批量操作

批量操作可以通过在 Repository 接口中定义方法来实现。例如,我们可以在 UserRepository 接口中定义一个批量更新方法:

public interface UserRepository extends JpaRepository<User, Long> {

@Modifying

@Query(“UPDATE User u SET u.age = :age WHERE u.lastName = :lastName”)

void updateUsersAgeByLastName(@Param(“age”) Integer age, @Param(“lastName”) String lastName);

}

在上述代码中,我们使用 @Modifying 注解来标记该方法为批量更新操作,使用 @Query 注解来定义更新语句。使用 @Param 注解来指定查询参数的名称。

另外,还可以使用 EntityManager 类的 createQuery 方法来实现批量操作。例如,我们可以在 UserService 类中定义一个批量删除方法:

@Service

public class UserService {

@PersistenceContext

private EntityManager entityManager;

@Transactional

public void deleteUsersByIds(List<Long> userIds) {

Query query = entityManager.createQuery(“DELETE FROM User u WHERE u.id IN (:userIds)”);

query.setParameter(“userIds”, userIds);

query.executeUpdate();

}

}

在上述代码中,我们使用 EntityManager 类的 createQuery 方法来创建一个删除查询对象,并使用 setParameter 方法来设置查询参数的值。使用 executeUpdate 方法来执行删除操作。

  1. 批量删除

批量删除可以通过在 Repository 接口中定义方法来实现。例如,我们可以在 UserRepository 接口中定义一个批量删除方法:

public interface UserRepository extends JpaRepository<User, Long> {

@Modifying

@Query(“DELETE FROM User u WHERE u.age > :age”)

void deleteUsersByAgeGreaterThan(@Param(“age”) Integer age);

}

在上述代码中,我们使用 @Modifying 注解来标记该方法为批量删除操作,使用 @Query 注解来定义删除语句。使用 @Param 注解来指定查询参数的名称。

另外,还可以使用 EntityManager 类的 createQuery 方法来实现批量删除。例如,我们可以在 UserService 类中定义一个批量删除方法:

@Service

public class UserService {

@PersistenceContext

private EntityManager entityManager;

@Transactional

public void deleteUsersByIds(List<Long> userIds) {

Query query = entityManager.createQuery(“DELETE FROM User u WHERE u.id IN (:userIds)”);

query.setParameter(“userIds”, userIds);

query.executeUpdate();

}

}

在上述代码中,我们使用 EntityManager 类的 createQuery 方法来创建一个删除查询对象,并使用 setParameter 方法来设置查询参数的值。使用 executeUpdate 方法来执行删除操作。

总之,批量操作和删除是 Spring Data JPA 中常用的操作,可以通过在 Repository 接口中定义方法或使用 EntityManager 类来实现。在进行批量操作和删除时,需要注意事务管理、缓存配置、数据库连接池配置等方面,以保证应用程序的性能和可靠性。

  • 更新操作和锁定机制

在 Spring Data JPA 中,更新操作可以通过在 Repository 接口中定义方法来实现。具体来说,可以使用 @Modifying 和 @Query 注解来标记更新方法,如下所示:

public interface UserRepository extends JpaRepository<User, Long> {

@Modifying

@Query(“UPDATE User u SET u.firstName = ?1 WHERE u.id = ?2”)

int setFirstNameById(String firstName, Long id);

}

在上述代码中,我们使用 @Modifying 注解来标记该方法为更新操作,使用 @Query 注解来定义更新语句。在更新语句中,通过设置参数值来指定更新的条件和值。使用 int 类型的返回值来表明更新的记录数。

在进行更新操作时,需要注意事务管理和锁定机制。如果更新操作需要锁定记录,可以使用 @Lock 注解来指定锁定机制,如下所示:

public interface UserRepository extends JpaRepository<User, Long> {

@Lock(LockModeType.PESSIMISTIC_WRITE)

@Query(“SELECT u FROM User u WHERE u.id = ?1”)

User findByIdForUpdate(Long id);

}

在上述代码中,我们使用 @Lock 注解来指定锁定机制为悲观写入锁定,使用 @Query 注解来定义查询语句。在查询语句中,通过设置参数值来指定查询条件。使用 User 类型的返回值来表明查询结果。

总之,更新操作是 Spring Data JPA 中常用的操作,可以通过在 Repository 接口中定义方法或使用 EntityManager 类来实现。在进行更新操作时,需要注意事务管理和锁定机制,以保证应用程序的性能和可靠性。

  • 分页和排序

在 Spring Data JPA 中,可以使用分页和排序来查询数据库中的数据。具体来说:

  1. 分页查询

使用 Spring Data JPA 进行分页查询有多种方法。

  1. 在 Repository 接口中定义方法

可以在 Repository 接口中定义一个分页查询方法。具体来说,可以使用 Pageable 类型的参数来表明分页信息,如下所示:

public interface UserRepository extends JpaRepository<User, Long> {

Page<User> findAll(Pageable pageable);

}

在上述代码中,我们定义了一个 UserRepository 接口,并定义了一个 findAll 方法,该方法返回一个 Page<User> 对象,使用 Pageable 类型的参数来表明分页信息。

可以使用 PageRequest 类来创建一个 Pageable 对象,如下所示:

Pageable pageable = PageRequest.of(pageNumber, pageSize);

Page<User> users = userRepository.findAll(pageable);

在上述代码中,我们创建一个 Pageable 对象,并使用 findAll 方法来查询数据库中的记录。最后,我们使用 Page 对象来获取查询结果。

  1. 在查询方法中使用 @PageableDefault 注解

除了在 Repository 接口中定义方法外,还可以在查询方法中使用 @PageableDefault 注解来定义分页信息。例如,我们可以在 UserRepository 接口中定义一个使用 @PageableDefault 注解的查询方法:

public interface UserRepository extends JpaRepository<User, Long> {

@GetMapping(“/users”)

List<User> findAllUsers(

@PageableDefault(page = 0, size = 20) Pageable pageable);

}

在上述代码中,我们使用 @PageableDefault 注解来指定分页信息的默认值,使用 Pageable 类型的参数来表明分页信息。使用 List<User> 类型的返回值来表明查询结果。

可以使用 PageRequest 类来创建一个 Pageable 对象,如下所示:

Pageable pageable = PageRequest.of(pageNumber, pageSize);

List<User> users = userRepository.findAllUsers(pageable);

在上述代码中,我们创建一个 Pageable 对象,并使用 findAllUsers 方法来查询数据库中的记录。最后,我们使用 List 对象来获取查询结果。

  1. 使用自定义的查询方法

除了以上方法外,还可以使用自定义的查询方法来进行分页查询。例如,我们可以在 UserRepository 接口中定义一个自定义的查询方法:

public interface UserRepository extends JpaRepository<User, Long> {

@Query(“SELECT u FROM User u”)

Page<User> findAllUsers(Pageable pageable);

}

在上述代码中,我们使用 @Query 注解来定义查询语句,使用 Pageable 类型的参数来表明分页信息。使用 Page<User> 类型的返回值来表明查询结果。

可以使用 PageRequest 类来创建一个 Pageable 对象,如下所示:

Pageable pageable = PageRequest.of(pageNumber, pageSize);

Page<User> users = userRepository.findAllUsers(pageable);

在上述代码中,我们创建一个 Pageable 对象,并使用 findAllUsers 方法来查询数据库中的记录。最后,我们使用 Page 对象来获取查询结果。

总之,使用 Spring Data JPA 进行分页查询有多种方法,可以在 Repository 接口中定义方法、在查询方法中使用 @PageableDefault 注解或使用自定义的查询方法来实现。在进行分页查询时,需要注意事务管理、缓存配置、数据库连接池配置等方面,以保证应用程序的性能和可靠性。

Spring Data JPA 最佳实践

  • 事务管理

在 Spring Data JPA 中,事务管理是超级重大的。事务管理可以保证数据库操作的一致性和可靠性,从而避免数据丢失和损坏的问题。在 Spring Data JPA 中,可以使用 @Transactional 注解来定义事务管理。

事务是一组数据库操作的集合,这些操作要么全部执行成功,要么全部回滚。在 Spring Data JPA 中,事务管理可以保证数据库操作的原子性、一致性、隔离性和持久性。具体来说,事务管理可以保证在多个并发事务同时进行时,每个事务都能够独立地执行,并且不会相互干扰。

在 Spring Data JPA 中,可以在 Service 类中定义一个带有 @Transactional 注解的方法来实现事务管理。例如,我们可以在 UserService 类中定义一个更新用户年龄的方法:

@Service

public class UserService {

@Autowired

private UserRepository userRepository;

@Autowired

private EntityManager entityManager;

@Transactional

public void updateUserAge(Long userId, Integer age) {

User user = userRepository.findById(userId).orElse(null);

user.setAge(age);

entityManager.merge(user);

}

}

在上述代码中,我们使用 @Transactional 注解来指定该方法需要进行事务管理。在方法中,我们第一使用 UserRepository 类来查询用户记录,然后更新用户的年龄,并使用 EntityManager 类的 merge 方法来保存更改后的用户记录。

在进行事务管理时,需要注意以下几点:

  1. 在方法中使用 try-catch 块来捕获异常,并在 catch 块中使用 @Transactional 注解来回滚事务
  2. 在使用 EntityManager 类时,需要注意事务的传播行为和隔离级别
  3. 在进行分布式事务时,需要使用 JTA 事务管理器来管理事务

除了在 Service 类中使用 @Transactional 注解外,还可以在 Repository 接口中使用 @Transactional 注解来管理事务。例如,我们可以在 UserRepository 接口中定义一个批量删除方法:

public interface UserRepository extends JpaRepository<User, Long> {

@Transactional

@Modifying

@Query(“DELETE FROM User u WHERE u.age > :age”)

void deleteUsersByAgeGreaterThan(@Param(“age”) Integer age);

}

在上述代码中,我们使用 @Transactional 注解来指定该方法需要进行事务管理,并使用 @Modifying 注解来标记该方法为批量删除操作,使用 @Query 注解来定义删除语句。

总之,事务管理是 Spring Data JPA 中超级重大的一部分,可以使用 @Transactional 注解来定义事务管理,从而保证数据库操作的一致性和可靠性。在进行事务管理时,需要注意事务的传播行为、隔离级别和异常处理等方面,以保证应用程序的正确性和可靠性。

  • 缓存配置

在 Spring Data JPA 中,缓存是提高应用程序性能的一种有效方式。Spring Data JPA 支持两种类型的缓存:一级缓存和二级缓存。一级缓存是在 EntityManager 中维护的缓存,用于存储已经载入的实体对象。二级缓存是在 EntityManagerFactory 中维护的缓存,用于存储查询结果和实体对象。

在 Spring Data JPA 中,可以使用 @Cacheable 和 @CachePut 注解来定义缓存。具体来说,可以在 Repository 接口中定义方法,并使用 @Cacheable 和 @CachePut 注解来标记缓存方法,如下所示:

public interface UserRepository extends JpaRepository<User, Long> {

@Cacheable(“users”)

User findByName(String name);

@CachePut(value = “users”, key = “#user.id”)

User save(User user);

}

在上述代码中,我们使用 @Cacheable 注解来指定查询方法需要进行缓存,使用 @CachePut 注解来指定保存方法需要进行缓存。使用字符串类型的参数来表明缓存名称,使用字符串类型的表达式来表明缓存键。在查询方法中,如果缓存中已经存在相应的数据,则直接从缓存中获取;否则,查询数据库并将结果存储到缓存中。在保存方法中,将实体对象存储到数据库中,并将结果存储到缓存中。

在进行缓存配置时,需要注意以下几点:

  1. 在使用 @Cacheable 和 @CachePut 注解时,需要指定缓存名称和缓存键
  2. 在使用二级缓存时,需要配置相应的缓存提供器,如 Ehcache、Redis 等
  3. 在使用缓存时,需要思考缓存的失效和清除机制,以保证缓存数据的正确性和可靠性

总之,缓存是提高 Spring Data JPA 性能的一种有效方式,可以使用 @Cacheable 和 @CachePut 注解来定义缓存,从而提高应用程序的性能和可靠性。

  • 数据库连接池配置

在 Spring Data JPA 中,数据库连接池是超级重大的,可以在必定程度上提高数据库操作的性能和可靠性。Spring Data JPA 支持多种类型的数据库连接池,如 Tomcat、HikariCP、C3P0 等。在使用数据库连接池时,需要注意以下几点:

  1. 连接池大小

在配置数据库连接池时,需要根据实际情况来设置连接池的大小。如果连接池的大小过小,可能会导致数据库连接不足,从而影响应用程序的性能和可靠性;如果连接池的大小过大,可能会浪费系统资源,从而影响系统的稳定性和可靠性。一般情况下,提议将连接池的大小设置为 10-20 个左右。

  1. 最大连接数

在配置数据库连接池时,需要根据数据库的最大连接数来设置连接池的最大连接数。如果连接池的最大连接数小于数据库的最大连接数,则可能导致数据库连接不足,从而影响应用程序的性能和可靠性。

  1. 连接超时时间

在配置数据库连接池时,需要设置连接超时时间。如果连接超时时间过短,则可能导致数据库连接不足,从而影响应用程序的性能和可靠性;如果连接超时时间过长,则可能导致数据库连接过多,从而浪费系统资源。一般情况下,提议将连接超时时间设置为 10-20 秒左右。

  1. 空闲连接回收时间

在配置数据库连接池时,需要设置空闲连接回收时间。如果空闲连接回收时间过短,则可能导致连接池中的连接不足,从而影响应用程序的性能和可靠性;如果空闲连接回收时间过长,则可能导致连接池中的连接过多,从而浪费系统资源。一般情况下,提议将空闲连接回收时间设置为 60-120 秒左右。

  1. 连接泄漏检测

在使用数据库连接池时,可能会出现连接泄漏的情况。为了避免连接泄漏的问题,可以在数据库连接池中配置连接泄漏检测。具体来说,可以使用 Tomcat 和 HikariCP 连接池中提供的连接泄漏检测功能,或者使用 Spring Boot 中提供的连接泄漏检测功能。在进行连接泄漏检测时,需要注意定期清理无效连接,以避免连接池中的连接过多,从而影响应用程序的性能和可靠性。

总之,数据库连接池是 Spring Data JPA 中超级重大的一部分,可以在必定程度上提高应用程序的性能和可靠性。在使用数据库连接池时,需要注意连接池大小、最大连接数、连接超时时间、空闲连接回收时间和连接泄漏检测等方面,以保证应用程序的正确性和可靠性。

  • 性能优化

在 Spring Data JPA 中,性能优化是超级重大的,可以提高应用程序的性能和可靠性。以下是一些常见的性能优化技巧:

  1. 使用懒加载

在 Spring Data JPA 中,可以使用懒加载来延迟加载实体对象的关联对象。具体来说,可以在实体对象的关联属性上使用 @ManyToOne、@OneToOne、@ManyToMany 和 @OneToMany 注解,并使用 FetchType.LAZY 参数来指定懒加载。这样可以减少数据库查询的次数,从而提高应用程序的性能。

  1. 使用批量操作

在 Spring Data JPA 中,可以使用批量操作来减少数据库操作的次数,从而提高应用程序的性能。具体来说,可以在 Repository 接口中定义批量操作方法,并使用 @Modifying 注解来标记批量操作方法。例如,可以在 UserRepository 接口中定义一个批量删除方法:

public interface UserRepository extends JpaRepository<User, Long> {

@Modifying

@Query(“DELETE FROM User u WHERE u.age > :age”)

void deleteUsersByAgeGreaterThan(@Param(“age”) Integer age);

}

在上述代码中,我们使用 @Modifying 注解来标记该方法为批量删除操作,使用 @Query 注解来定义删除语句。这样可以减少删除操作的次数,从而提高应用程序的性能。

  1. 使用索引

在 Spring Data JPA 中,可以使用索引来提高数据库查询的性能。具体来说,可以在实体对象的属性上使用 @Index 注解来定义索引。例如,可以在 User 实体对象的 name 属性上定义索引:

@Entity

@Table(name = “user”)

public class User {

@Id

@GeneratedValue(strategy = GenerationType.IDENTITY)

private Long id;

@Column(name = “name”)

@Index(name = “idx_user_name”)

private String name;

// other fields and methods…

}

在上述代码中,我们使用 @Index 注解来定义 name 属性的索引。这样可以加速 name 属性的查询,从而提高应用程序的性能。

  1. 使用二级缓存

在 Spring Data JPA 中,可以使用二级缓存来提高应用程序的性能。具体来说,可以在 EntityManagerFactory 中配置 Ehcache、Redis 等缓存提供器,并在实体对象的 Repository 接口中使用 @Cacheable 和 @CachePut 注解来定义缓存。这样可以减少数据库查询的次数,从而提高应用程序的性能。

总之,性能优化是 Spring Data JPA 中超级重大的一部分,可以使用懒加载、批量操作、索引和二级缓存等技巧来提高应用程序的性能和可靠性。在进行性能优化时,需要根据实际情况来选择合适的技巧,并进行适当的测试和评估,以保证应用程序的正确性和可靠性。

在 Spring Data JPA 中,可以使用 @Cacheable 和 @CachePut 注解来定义缓存。具体来说,可以在 Repository 接口中定义方法,并使用 @Cacheable 和 @CachePut 注解来标记缓存方法,如下所示:

public interface UserRepository extends JpaRepository<User, Long> {

@Cacheable(“users”)

User findByName(String name);

@CachePut(value = “users”, key = “#user.id”)

User save(User user);

}

在上述代码中,我们使用 @Cacheable 注解来指定查询方法需要进行缓存,使用 @CachePut 注解来指定保存方法需要进行缓存。使用字符串类型的参数来表明缓存名称,使用字符串类型的表达式来表明缓存键。在查询方法中,如果缓存中已经存在相应的数据,则直接从缓存中获取;否则,查询数据库并将结果存储到缓存中。在保存方法中,将实体对象存储到数据库中,并将结果存储到缓存中。

在进行缓存配置时,需要注意以下几点:

  1. 在使用 @Cacheable 和 @CachePut 注解时,需要指定缓存名称和缓存键
  2. 在使用二级缓存时,需要配置相应的缓存提供器,如 Ehcache、Redis 等
  3. 在使用缓存时,需要思考缓存的失效和清除机制,以保证缓存数据的正确性和可靠性

总之,缓存是提高 Spring Data JPA 性能的一种有效方式,可以使用 @Cacheable 和 @CachePut 注解来定义缓存,从而提高应用程序的性能和可靠性。

© 版权声明

相关文章

暂无评论

none
暂无评论...