JPA(Java Persistence API,Java持久化API),定义了对象关系映射(Object Relation Mapping,ORM)以及实体对象持久化的标准接口。
JPA是一套接口规范,JPA的实现主要包括 JBoss 的 Hibernate EntityManager、Oracle 捐献给 Eclipse 社区的 EclipseLink和Apache 的 OpenJPA 等。
ORM框架的出现使得我们能够以面向对象的方式来操作关系数据库,但是长久以来实现应用系统中的数据访问层依然是一件非常繁琐的事情,简单的查询也往往涉及大量重复代码。Spring Data JPA在则基于JPA进一步简化了数据访问层的实现,它提供了一种类似于声明式编程的方式,开发者只需要编写数据访问接口(称为Repository
),Spring Data JPA就能基于接口中的方法命名自动地生成实现。
首先来实现一个Hello World应用。
创建一个Maven项目,在pom.xml
中添加spring Data JPA的依赖:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.0.RELEASE</version>
</parent>
为了快速搭建spring
环境,我们使用spring-boot
作为我们的开发框架,大家如果对Spring Boot感兴趣,可以参考Spring Boot——开发新一代Spring Java应用,这里不再赘述。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
Spring Data JPA支持多种数据库源。我们可以直接使用内存数据库,不需要再额外的在系统中安装数据库服务。在依赖中添加如下配置:
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<scope>runtime</scope>
</dependency>
如果安装了MySQL数据库,则使用MySQL可进行如下配置:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
接下来需要对数据源进行配置。在Spring Boot中,数据源相关的配置都是以spring.datasource.
开头的。
使用MySQL则添加如下配置:
spring.datasource.url=jdbc:mysql://localhost/test
spring.datasource.username=dbuser
spring.datasource.password=dbpass
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
而使用HSQLDB或者H2等内存数据库,只需要在POM文件中引入相关的依赖包即可,无需其它配置。
其它配置选项参考DataSourceProperties
这里我们使用hsqldb
作为我们的数据库,无需进行任何配置。
应用中我们定义一个实体对象User
并将其存储到关系型数据库中,并使用JPA标注:
package com.tianmaying.model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class User {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Long id;
private String name;
private String email;
protected User() {}
public User(String name, String email) {
this.name = name;
this.email = email;
}
@Override
public String toString() {
return String.format(
"User[id=%d, name='%s', email='%s']",
id, name, email);
}
...
}
User
对象包含三个字段:
id
作为唯一标识符,@GeneratedValue(strategy=GenerationType.AUTO)
表明id
是一个自增字段。name
和email
没有任何标注,由于User
添加了@Entity
标注,它们会被映射为同名的数据表字段。提示
User
对象各个字段都是private
的,所以还需要为它们加上Getter/Setter方法,限于篇幅,示例代码中省略了这些方法。
接下来创建一个访问User
对象的接口:
package com.tianmaying;
import java.util.List;
import org.springframework.data.repository.CrudRepository;
public interface UserRepository extends CrudRepository<User, Long> {
List<User> findByName(String name);
}
UserRepository
继承了Spring Data JPA中的CrudRepository
,这个接口已经包含了:
save()
)delete()
)findOne()
、findAll()
)等预定义方法。
开发者还能够根据命名约定来扩展,上例中的findByName(String name)
实际上等价于SQL语句select * from user where name=?
。
在接口中定义这个方法后,无需实现它,Spring Data JPA会根据方法的名字自动实现这个方法,很方便吧!
创建一个DataInitialization
类来使用UserRepository
接口。
package com.tianmaying;
import com.tianmaying.model.User;
import com.tianmaying.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
public class DataInitialization implements CommandLineRunner {
@Autowired
UserRepository repository;
@Override
public void run(String... strings) throws Exception {
/**
* do not modify the method
*/
// save a couple of users
repository.save(new User("Jack", "Bauer@gmail.com"));
repository.save(new User("Chloe", "OBrian@gmail.com"));
repository.save(new User("Kim", "BauerKin@gmail.com"));
repository.save(new User("David", "Palmer@gmail.com"));
repository.save(new User("Michelle", "Dessler@gmail.com"));
// fetch all users
System.out.println("User found with findAll():");
System.out.println("-------------------------------");
for (User user : repository.findAll()) {
System.out.println(user);
}
}
public List<User> helloWorld() {
/**
* write your code here
*/
return null; // place holder, you should not return null here
}
}
在DataInitialization
的run方法中,我们通过UserRepository
往数据库中插入了5条数据,并且使用repository.findAll()
将数据库中的所有数据查询了出来。这样,我们就通过简单的3个类,完成了对User
表的操作!
DataInitialization
同时还实现了CommandLineRunner
接口,该接口是Spring Boot为我们提供的。实现该接口的所有类都将在Spring Boot应用启动后被调用。也就是说,启动我们的应用后,DataInitialization.run
就会被调用,这样我们就能在控制台看到相应的输出。
为了启动我们的应用,我们需要创建一个Application
类:
package com.tianmaying;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class);
}
}
直接运行Application
类,或者在命令行下进入项目目录运行mvn spring-boot:run
就能运行我们的应用。我们可以看到输出如下:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v1.4.0.RELEASE)
...
......
如果你希望在控制台看到JPA生成的SQL(包括DDL和DML),可以在Spring Boot的Properties文件中添加spring.jpa.show-sql = true
配置即可。
此时,你运行参考代码的话,就可以通过浏览器访问本地地址http://localhost:8080/users,看到我们初始化的5个用户了。
参考代码中,已经通过Spring MVC为你写好了Controller层代码,在练习中你讲使用Spring Data JPA的知识逐步完成各个练习。
在接下来的学习中,我们将一步一步完善我们的网站,所有地址都将通过http://localhost:8080进行访问,访问时在后面加上相应的地址即可。
UserRepository
的代码只有短短几行,却已经拥有了大部分用以数据库操作的方法,比如在DataInitialization.run
方法中调用的save()
和findAll()
。
使用Spring Data JPA对关系型数据库进行访问就这么简单,基于Spring Boot对JPA的进一步封装,极大简化了数据访问层的实现,让我们能够编写出质量更高、可维护性更好的代码。
登录发表评论 登录 注册
方便到可怕
另外不知道为什么pom里面parent用1.4.0.RELEASE会出错,改成1.4.2就好了
https://blog.csdn.net/zwb19940216/article/details/78172457
情况和这个一模一样,求老师解释一下原因