初识 Spring Data JPA

FFish 2021年08月29日 22次浏览

引用 Spring Data JPA

JPA (Java Persistence API),直译为 Java 持久层 API,是 Java EE 的一套标准。

Spring Data JPA 旨在抽象各种数据库的数据访问层,以减少样板式代码(boilerplate code),这也正是 Spring 的精髓。

引用 Spring Data JPA 的方式如下(本文基于 spring-data 2.5.3):
maven

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

gradle

dependencies {
    // ...
    implementation 'org.springframework.data:spring-data-jpa'
    // ...
}

Repository

JPA 的核心概念是Repository,它本身是一个空的接口。

package org.springframework.data.repository;

import org.springframework.stereotype.Indexed;

/**
 * Central repository marker interface. Captures the domain type to manage as well as the domain type's id type. General
 * purpose is to hold type information as well as being able to discover interfaces that extend this one during
 * classpath scanning for easy Spring bean creation.
 * <p>
 * Domain repositories extending this interface can selectively expose CRUD methods by simply declaring methods of the
 * same signature as those declared in {@link CrudRepository}.
 * 
 * @see CrudRepository
 * @param <T> the domain type the repository manages
 * @param <ID> the type of the id of the entity the repository manages
 * @author Oliver Gierke
 */
@Indexed
public interface Repository<T, ID> {

}

CrudRepository

CrudRepository接口继承Repository,提供基本的增删改查(CRUD)功能。

import java.util.Optional;

@NoRepositoryBean
public interface CrudRepository<T, ID> extends Repository<T, ID> {

    <S extends T> S save(S entity);

    <S extends T> Iterable<S> saveAll(Iterable<S> entities);

    Optional<T> findById(ID id);

    boolean existsById(ID id);

    Iterable<T> findAll();

    Iterable<T> findAllById(Iterable<ID> ids);

    long count();

    void deleteById(ID id);

    void delete(T entity);

    void deleteAllById(Iterable<? extends ID> ids);

    void deleteAll(Iterable<? extends T> entities);

    void deleteAll();
}

<T>Entity<ID>EntityID类型,例如:

public interface DemoRepository extends CrudRepository<DemoEntity, Long> {

}

PagingAndSortingRepository

PagingAndSortingRepository继承CrudRepository,提供了分页查询的能力,它的定义如下:

package org.springframework.data.repository;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;

/**
 * Extension of {@link CrudRepository} to provide additional methods to retrieve entities using the pagination and
 * sorting abstraction.
 *
 * @author Oliver Gierke
 * @see Sort
 * @see Pageable
 * @see Page
 */
@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 {@code Pageable} object.
	 *
	 * @param pageable
	 * @return a page of entities
	 */
	Page<T> findAll(Pageable pageable);
}

分页查询,假设查询第一页(page 0),每页10条数据,写法如下:

Page<DemoEntity> demoEntityPage = testPagingRepository.findAll(PageRequest.of(0, 10));

其中PageRequest继承自Pageable

当然在Controller中支持基于url的写法如下:

GET https://demo.ffish.net/demo/entities?page=0&size=10

查询语句写法

声明自定义interface,继承Repository或其子类(CrudRepository, PagingAndSortingRepository, JpaRepository),然后添加查询函数。

interface PersonRepository extends PagingAndSortingRepository<Person, Long>
{
    List<Person> findByLastname(String lastname);
    Page<Person> findByAge(int age, Pageable pageable);
    List<Person> findByLastnameOrderByFirstnameAsc(String lastname);
}

这样就可以了,不需要写查询语句。关于Repository方法的编写规则,请参考下面的文章。

飞鱼原创 https://ffish.net,未经允许,严禁转载!