springboot 集成 springboot data jpa

一、前言

Spring Data JPA 为 Java Persistence API (JPA) 提供Repository支持。它简化了需要访问 JPA 数据源的应用程序的开发。

二、依赖

Spring Boot 会选择最新版本的 Spring Data 模块。

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

三、使用Spring Data Repositories

Spring Data repository 抽象的目标是显着减少为各种持久性存储实现数据访问层所需的样板代码量。

3.1核心概念

Spring Data Repository抽象中的中心接口是Repository. 它需要域类来管理以及域类的 ID 类型作为类型参数。此接口主要用作标记接口,以捕获要使用的类型并帮助发现扩展此接口的接口。该CrudRepository接口为正在管理的实体类提供复杂的 CRUD 功能。

  • CrudRepository接口
public interface CrudRepository<T, ID> extends Repository<T, ID> {

	/** 保存给定的实体。 */
  <S extends T> S save(S entity);      
	/** 返回由给定 ID 标识的实体。 */
  Optional<T> findById(ID primaryKey); 
	/** 返回所有实体。 */
  Iterable<T> findAll();               
	/** 返回实体的数量。 */
  long count();                        
	/** 删除给定的实体。 */
  void delete(T entity);               
	/** 指示具有给定 ID 的实体是否存在。 */
  boolean existsById(ID primaryKey);   

  // … more functionality omitted.
}
  • PagingAndSortingRepository,实现CrudRepository接口,它添加了额外的方法来简化对实体的分页访问:
public interface PagingAndSortingRepository<T, ID> extends CrudRepository<T, ID> {

  Iterable<T> findAll(Sort sort);

  Page<T> findAll(Pageable pageable);
}

访问User页面大小为 20的第二页,可以执行以下操作:

PagingAndSortingRepository<User, Long> repository = // … get access to a bean
Page<User> users = repository.findAll(PageRequest.of(1, 20));

除了查询方法,计数和删除查询的查询派生也是可用的。以下列表显示了派生计数查询的接口定义:

  • 派生计数查询
interface UserRepository extends CrudRepository<User, Long> {

  long countByLastname(String lastname);
}
  • 派生删除查询
interface UserRepository extends CrudRepository<User, Long> {

  long deleteByLastname(String lastname);

  List<User> removeByLastname(String lastname);
}

3.2查询方法

标准 CRUD 功能Repository通常对底层数据存储进行查询。使用 Spring Data,分四步:
1.声明一个扩展 Repository 或其子接口之一的接口,并将其键入它应该处理的域类和 ID 类型,如以下示例所示:

interface PersonRepository extends Repository<Person, Long> {}

2.在接口上声明查询方法。

interface PersonRepository extends Repository<Person, Long> {
  List<Person> findByLastname(String lastname);
}

3.创建一个类似于以下内容的配置类。

import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

@EnableJpaRepositories
class Config {}

4.注入Repository实例并使用,如以下示例所示:

class SomeClient {

  private final PersonRepository repository;

  SomeClient(PersonRepository repository) {
    this.repository = repository;
  }

  void doSomething() {
    List<Person> persons = repository.findByLastname("Matthews");
  }
}

3.3定义Repository接口

要定义Repository接口,首先需要定义特定于域类的Repository接口。接口必须扩展Repository并键入域类和 ID 类型。如果要公开该域类型的 CRUD 方法,使用扩展CrudRepository而不是Repository。

3.3.1 微调Repository定义

通常情况下,自己的接口扩展Repository,CrudRepository或PagingAndSortingRepository。或者,如果您不想扩展 Spring Data 接口,您也可以使用@RepositoryDefinition. 扩展CrudRepository公开了一套完整的方法来操作实体。如果选择公开的方法,将要公开的方法从CrudRepository复制到域存储库中。
下面的示例示展示如何选择性地公开CRUD方法(findById和save):

@NoRepositoryBean
interface MyBaseRepository<T, ID> extends Repository<T, ID> {

  Optional<T> findById(ID id);

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

interface UserRepository extends MyBaseRepository<User, Long> {
  User findByEmailAddress(EmailAddress emailAddress);
}

以上接口中,UserRepository可以保存用户,通过 ID 查找单个用户,并触发查询以Users通过电子邮件地址查找。

中间存储库接口使用@NoRepositoryBean. 确保将该注释添加到 Spring Data, 不在运行时为其创建实例的所有存储库接口。

四、简单示例

  • 建简单实体
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class Customer {

  @Id
  @GeneratedValue(strategy=GenerationType.IDENTITY)
  private Long id;
  private String firstName;
  private String lastName;

  protected Customer() {}

  public Customer(String firstName, String lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
  }

  @Override
  public String toString() {
    return String.format(
        "Customer[id=%d, firstName='%s', lastName='%s']",
        id, firstName, lastName);
  }

  public Long getId() {
    return id;
  }

  public String getFirstName() {
    return firstName;
  }

  public String getLastName() {
    return lastName;
  }
}
  • 简单查询
import java.util.List;

import org.springframework.data.repository.CrudRepository;

public interface CustomerRepository extends CrudRepository<Customer, Long> {

  List<Customer> findByLastName(String lastName);

  Customer findById(long id);
}
  • 配置启动时自动建表
  spring:
  	jpa:
    	generate-ddl: true
  • 启动执行记录
    从记录可看出表已生成,并且存入数据,查询方法均执行成功。
2021-09-01 22:13:58.308  INFO 11296 --- [  restartedMain] com.chan.datajpa.DatajpaApplication      : Started DatajpaApplication in 3.503 seconds (JVM running for 4.184)
2021-09-01 22:13:58.525  INFO 11296 --- [  restartedMain] com.chan.datajpa.DatajpaApplication      : Customers found with findAll():
2021-09-01 22:13:58.525  INFO 11296 --- [  restartedMain] com.chan.datajpa.DatajpaApplication      : -------------------------------
2021-09-01 22:13:58.609  INFO 11296 --- [  restartedMain] com.chan.datajpa.DatajpaApplication      : Customer[id=1, firstName='Jack', lastName='Bauer']
2021-09-01 22:13:58.609  INFO 11296 --- [  restartedMain] com.chan.datajpa.DatajpaApplication      : Customer[id=2, firstName='Chloe', lastName='O'Brian']
2021-09-01 22:13:58.609  INFO 11296 --- [  restartedMain] com.chan.datajpa.DatajpaApplication      : Customer[id=3, firstName='Kim', lastName='Bauer']
2021-09-01 22:13:58.609  INFO 11296 --- [  restartedMain] com.chan.datajpa.DatajpaApplication      : Customer[id=4, firstName='David', lastName='Palmer']
2021-09-01 22:13:58.609  INFO 11296 --- [  restartedMain] com.chan.datajpa.DatajpaApplication      : Customer[id=5, firstName='Michelle', lastName='Dessler']
2021-09-01 22:13:58.609  INFO 11296 --- [  restartedMain] com.chan.datajpa.DatajpaApplication      : 
2021-09-01 22:13:58.623  INFO 11296 --- [  restartedMain] com.chan.datajpa.DatajpaApplication      : Customer found with findById(1L):
2021-09-01 22:13:58.623  INFO 11296 --- [  restartedMain] com.chan.datajpa.DatajpaApplication      : --------------------------------
2021-09-01 22:13:58.623  INFO 11296 --- [  restartedMain] com.chan.datajpa.DatajpaApplication      : Customer[id=1, firstName='Jack', lastName='Bauer']
2021-09-01 22:13:58.623  INFO 11296 --- [  restartedMain] com.chan.datajpa.DatajpaApplication      : 
2021-09-01 22:13:58.623  INFO 11296 --- [  restartedMain] com.chan.datajpa.DatajpaApplication      : Customer found with findByLastName('Bauer'):
2021-09-01 22:13:58.623  INFO 11296 --- [  restartedMain] com.chan.datajpa.DatajpaApplication      : --------------------------------------------
2021-09-01 22:13:58.653  INFO 11296 --- [  restartedMain] com.chan.datajpa.DatajpaApplication      : Customer[id=1, firstName='Jack', lastName='Bauer']
2021-09-01 22:13:58.653  INFO 11296 --- [  restartedMain] com.chan.datajpa.DatajpaApplication      : Customer[id=3, firstName='Kim', lastName='Bauer']

五、问题记录

  • 启动时老报错,排查后发现我的问题是在做了连接池后,没有把连接池配置做完整。完善配置后就可以了。
Failed to auto-configure a DataSource: 'spring.datasource.url' is not specified and no embedded datasource could be auto-configured.

Reason: Failed to determine suitable jdbc url


Action:

Consider the following:
If you want an embedded database (H2, HSQL or Derby), please put it on the classpath.
If you have database settings to be loaded from a partic
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值