本节讲解如何使用spring-data-jpa来访问数据,通过内存数据库h2来存储数据。在这个过程中,我们将了解到:
spring-data-jpa
的特点和强大之处h2
使用环境参考Spring Boot基础教程汇总中的讲解:详情请点击
└─src
├─main
│ ├─java
│ │ └─com
│ │ └─qingtian
│ │ ├─entity
│ │ └─service
│ └─resources
└─test
└─java
└─com
└─qingtian
spring-boot-starter-data-jpa
和h2
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>com.qingtiangroupId>
<artifactId>spring-boot-jpa-h2artifactId>
<version>1.0version>
<packaging>jarpackaging>
<name>spring-boot-jpa-h2name>
<description>Demo project for Spring Bootdescription>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.0.0.RELEASEversion>
<relativePath/>
parent>
<properties>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
<java.version>1.8java.version>
properties>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starterartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-data-jpaartifactId>
dependency>
<dependency>
<groupId>com.h2databasegroupId>
<artifactId>h2artifactId>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
plugins>
build>
project>
设计User
类,并使用注解@Entity
将其标识为JPA的实体
src/main/java/com/qingtian/entity/User.java
@Entity
public class User {
@Id
@GeneratedValue(strategy= GenerationType.AUTO)
private Long id;
private String firstName;
private String lastName;
protected User() {}
public User(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
@Override
public String toString() {
return String.format(
"User[id=%d, firstName='%s', lastName='%s']",
id, firstName, lastName);
}
// 省略了getter和setter
}
在User
中定义了id
,firstName
,lastName
这三个属性,同时定义了两个构造器,其中定义无参构造器是因为JPA需要,我们不会用到它,所以定义为protected
,另一个构造器用来初始化实例。
使用@Entity
表示为JPA实体,不使用@Table
注解,则默认使用User
类名作为表名。
使用@Id
表示字段id为表的主键,@GeneratedValue(strategy= GenerationType.AUTO)
表明主键自增长。
设计UserRepository
接口操作User
对象
src/main/java/com/qingtian/service/UserRepository.java
public interface UserRepository extends CrudRepository<User, Long> {
List findByLastName(String lastName);
}
UserRepository
继承CrudRepository
,其中T表示entity,ID表示为table的主键。CrudRepository
中封装好了一些方法,包括对User
的查找,删除,更新等,这是Spring Data JPA特点之一。
当然,Spring Data JPA也允许在UserRepository
操作类中定义其他的方法,比如我们在这里定义了findByLastName
。从字面上的意思便是通过lastName
字段来查询User。
一旦UserRepository
继承了CrudRepository
,我们便无须为UserRepository
接口创建实现类,在运行application时,Spring Data JPA会为我们动态创建一个实现类,这就是其强大的地方之一。并且,在执行findByLastName
方法时,会根据方法名和参数来执行方法,并不需要我们去实现和写sql
设计Demo
来执行UserRepository
的curd操作。
src/main/java/com/qingtian/Demo
@Component
public class Demo implements CommandLineRunner {
private static final Logger log = LoggerFactory.getLogger(Demo.class);
@Autowired
private UserRepository repository;
@Override
public void run(String... args) throws Exception {
// 插入5个用户
repository.save(new User("Jack", "Bauer"));
repository.save(new User("Chloe", "O'Brian"));
repository.save(new User("Kim", "Bauer"));
repository.save(new User("David", "Palmer"));
repository.save(new User("Michelle", "Dessler"));
// 查询用户列表
log.info("Customers found with findAll():");
log.info("-------------------------------");
for (User user : repository.findAll()) {
log.info(user.toString());
}
log.info("");
// 通过id查询某个用户
repository.findById(1L)
.ifPresent(user -> {
log.info("Customer found with findById(1L):");
log.info("--------------------------------");
log.info(user.toString());
log.info("");
});
// 通过lastName查询用户
log.info("Customer found with findByLastName('Bauer'):");
log.info("--------------------------------------------");
repository.findByLastName("Bauer").forEach(bauer -> {
log.info(bauer.toString());
});
log.info("");
}
}
在这里使用CommandLineRunner
的实现类来执行curd操作。如果需要在SpringApplication
启动后执行一些特殊的代码,便可以实现CommandLineRunner
,并使用@Component
将实现类注入到容器中。
CommandLineRunner
接口提供单一的run
方法,该方法会在SpringApplication.run(...)
完成之前调用。
设计application
src/main/java/com/qingtian/SpringBootJpaH2Application
@SpringBootApplication
public class SpringBootJpaH2Application {
public static void main(String[] args) {
SpringApplication.run(SpringBootJpaH2Application.class, args);
}
}
不了解@SpringBootApplication
注解的,可以参考下构建spring-rest-curd + 单元测试
在程序的根目录下(与pom.xml同级),执行
Spring Data JPA有以下特点:
1. CrudRepository
实现了一些简单的增删查改等方法,继承该类便可以使用,不用用户重复开发
2. demoRepository
接口继承CrudRepository
,不用编写实现类,会在项目运行时动态创建
3. 会根据方法名和参数自动实现一些简单的查询,比如本文的findByLastName
h2(内存数据库):
1. 使用起来非常方便,不需要提供任何连接URLs
,只需要添加想使用的的内嵌数据库依赖。
2. 只需要在应用启动时填充数据库,在应用结束前清楚数据
项目源码,欢迎star,本小节为spring-boot-jpa-h2:https://github.com/mcrwayfun/spring-boot-learning