Java持久化之--Spring Data JPA

发布于:2025-02-12 ⋅ 阅读:(116) ⋅ 点赞:(0)

1、简介

Java持久化技术是Java开发中比较重要的部分,主要用于将对象数据持久化到数据库,或者从数据库中查询数据,简化数据库的CRUD操作。

2、JPA简介

JPA(Java Persistence API)是Java实现ORM(Object Relational Mapping)技术提供的规范,主要用于将Java对象映射到关系数据库,便于持久化操作。

3、Spring Data JPA简介

Spring Data JPA是Spring 框架下的一个模块,是基于JPA规范实现的上层封装,旨在简化JPA的使用。Spring Data JPA提供了一些常用的接口,例如JpaRepository、JpaSpecificationExecutor,这些接口中包含了很多CRUD操作方法,同时提供了基于方法命名规范的查询方法,可以根据方法自动生成相应的SQL。

除了基础的CRUD操作,Spring Data JPA还提供很多高级功能,例如分页查询、排序、动态查询等,同时支持多种数据库,例如MySQL、PostgreSQL、Oracle等。

  • Spring Data JPA 是 Spring Data 项目家族中的一员,它为基于Spring框架应用程序提供了更加便捷和强大的数据操作方式。
  • Spring Data JPA 支持多种数据存储技术,包括关系型数据库和非关系型数据库。
  • Spring Data JPA 提供了简单、一致且易于使用的API来访问和操作数据存储,其中包括基本的CRUD操作、自定义查询方法、动态查询等功能。
  • Spring Data JPA 也支持QueryDSL、Jinq、Kotlin Query等其他查询框架

4、快速使用

4.1、添加依赖

<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

4.2、创建实体类

1、实体类必须使用@Entity注解、还可以添加@Table映射表名,使用lombok的@Data

package com.mqtt.mqttproject.entity;

import lombok.Data;
import javax.persistence.*;

/**
 * @ Author : Gridsum
 * @ Description : 测试实体类
 */
@Entity
@Table(name = "user")
@Data
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(name = "name")
    private String name;
    @Column(name = "age")
    private Integer age;
    @Column(name = "addr")
    private String addr;
}

4.3、创建Repository接口

package com.mqtt.mqttproject.repository;

import com.mqtt.mqttproject.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface UserRepository extends JpaRepository<User, Long> {

    User findByName(String name);
}

实现类

package com.mqtt.mqttproject.service.impl;

import com.mqtt.mqttproject.entity.User;
import com.mqtt.mqttproject.repository.UserRepository;
import com.mqtt.mqttproject.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * @ Author : Gridsum
 * @ Description :
 */
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserRepository userRepository;
    @Override
    public User findByName(String name) {
        return userRepository.findByName(name);
    }

    @Override
    public void save(User user){
        userRepository.save(user);
    }
}

4.4、基本CRUD

定义Repository接口,继承JpaRepository<T, ID>,泛型T指实体类,ID实体id。

方法名 描述
T save(T entity) 保存实体对象
Iterable saveAll(Iterable entities) 批量保存实体对象
Optional findById(ID id) 根据主键获取实体对象
boolean existsById(ID id) 判断是否存在特定主键的实体对象
Iterable findAll() 获取所有实体对象
Iterable findAllById(Iterable ids) 根据主键批量获取实体对象
long count() 获取实体对象的数量
void deleteById(ID id) 根据主键删除实体对象
void delete(T entity) 删除实体对象
void deleteAll(Iterable<? extends T> entities) 批量删除实体对象
package com.mqtt.mqttproject.repository;

import com.mqtt.mqttproject.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Optional;

@Repository
public interface UserRepository extends JpaRepository<User, Long> {

    User findByName(String name);

    @Override
    User save(User user);

    @Override
    Optional<User> findById(Long id);
    
    @Override
    List<User> findAll();
    
    @Override
    void deleteById(Long id);
}

4.5、自定义查询

方法名称查询是 Spring Data JPA 中最简单的一种自定义查询方法,并且不需要额外的注解或 XML 配置。它通过方法名来推断出查询的条件,例如以 findBy 开头的方法表示按照某些条件查询,以 deleteBy 开头的方法表示按照某些条件删除数据。

 例如 findByName(String name)

@Repository
public interface UserRepository extends JpaRepository<User, Long> {

    User findByName(String name);

    @Override
    User save(User user);

    @Override
    Optional<User> findById(Long id);

    @Override
    List<User> findAll();

    @Override
    void deleteById(Long id);
}

4.5.1、查询参数设置

除了方法名称查询外,还可以使用参数设置方式进行自定义查询。它通过在方法上使用 @Query 注解来指定查询语句,然后使用 @Param 注解来指定方法参数与查询语句中的参数对应关系。 

UserRepository接口中自定义查询接口:

@Query("SELECT u FROM User u WHERE u.name = :name")
User findByUserName(@Param("name") String name);

 4.6、使用 Sort 和 Pageable 进行排序和分页

在查询数据时,经常需要对结果进行排序和分页操作。Spring Data JPA 提供了 SortPageable 两个类来实现排序和分页功能。

Sort 类表示排序规则,可以使用 Sort.by() 静态方法

创建实例,并指定排序属性和排序方向。常用方法如下:

方法名 描述
static Sort by(Sort.Order... orders) 根据排序规则创建 Sort 实例
static Sort.Order by(String property) 根据属性升序排序
static Sort.Order by(String property, Sort.Direction direction) 根据属性排序
    List<User> findByOrderByAgeAsc();

    // 根据年龄降序分页查询用户列表
    Page<User> findBy(Pageable pageable);

4.7、Specification 进行动态查询

在实际应用中,我们经常需要根据条件动态生成查询语句。Spring Data JPA 提供了 Specification 接口来支持动态查询,它可以通过使用匿名内部类或 Lambda 表达式来实现。

Specification 接口定义了 toPredicate() 方法,该方法接受一个 Root<T> 对象和一个 CriteriaQuery<?> 对象作为参数,并返回一个 Predicate 对象,表示查询条件。

toPredicate() 方法内部,可以通过 root.get() 方法获取实体属性,并使用 criteriaBuilder 构建查询条件。 1.例如,以下 Lambda 表达式表示查询 age 大于等于 18 的用户。

 

public interface UserRepository extends JpaRepository<User, Long>, JpaSpecificationExecutor<User> {
    List<User> findAll(Specification<User> spec);
}

// 使用
Specification<User> spec = (root, query, criteriaBuilder) -> criteriaBuilder.greaterThanOrEqualTo(root.get("age"), 18);
userRepostory.findAll(spec);