什么是 JPA
对象 - 关系表
的映射关系,并将运行期的实体对象持久化到 DB中。相互之间的联系 :
Spring Data 是一个开源框架,在这个框架中 Spring Data JPA 只是这个框架中的一个模块,所以名称才叫 Spring Data JPA。
如果单独使用 JPA 开发,会发现这个代码量和使用 JDBC 开发一样繁琐,所以 Spring Data JPA 的出现就为了简化 JPA 的写法,只需要编写一个接口继承一个类就能实现简单 CRUD 操作了。
JPA 规范本质上就是一种 ORM 规范,不是 ORM 框架——因为 JPA 并未提供 ORM 实现,它只是制订了一些规范,提供了一些编程的API接口,但具体实现则由服务厂商来提供实现。
JPA 和 Hibernate 的关系就像 JDBC 和 JDBC 驱动的关系,JPA 是规范,Hibernate 除了作为 ORM 框架之外,它也是一种 JPA 实现。
JPA 怎么取代 Hibernate 呢?JDBC 规范可以驱动底层数据库吗?答案是 NO,即是说如果使用 JPA 规范进行数据库操作,底层需要 hibernate 作为其实现类完成数据持久化工作。
Spring Data JPA 有什么功能
Spring Data JPA 提供的核心接口:
A、Repository:最顶层的空接口,是为了统一所有 Repository 的类型,且能让组件扫描的时候自动识别。
B、CrudRepository :是 Repository 的子接口,提供 CRUD 的功能。
C、PagingAndSortingRepository:是 CrudRepository 的子接口,添加分页和排序的功能。
D、JpaRepository:是 PagingAndSortingRepository 的子接口,增加了一些实用的功能(批量操作等)。
E、JpaSpecificationExecutor:用来做负责查询的接口。
F、Specification:是 Spring Data JPA 提供的一个查询规范,要做复杂的查询,只需围绕这个规范来设置查询条件即可。
A、pom.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<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.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.rookie</groupId>
<artifactId>jpa</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>jpa</name>
<description>Demo project for Spring Boot Jpa</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.4</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
这里作者使用的是 springboot 2.1.5.RELEASE 版本,如果使用 2.0.x 以下的版本,会出现某些错误。后边会讲到。
B、创建 dto 对象
@Getter
@Setter
@ToString
@AllArgsConstructor
@NoArgsConstructor
@Entity //声明实体类
@Table(name = "tab_customer") //建立实体类和表的映射关系
public class Customer implements Serializable{@Id //声明当前私有属性为主键
@GeneratedValue(strategy=GenerationType.IDENTITY) //配置主键的生成策略
private Long id;
@Column(name="first_Name") //指定和表中 first_Name 字段的映射关系
private String firstName;
@Column(name="last_Name") //指定和表中 last_Name 字段的映射关系
private String lastName;
public Customer(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
}
常用注解的说明 :
@Id :指定当前字段是主键。
@GeneratedValue :指定主键的生成方式。strategy :指定主键生成策略。
— AUTO主键由程序控制, 是默认选项 ,不设置就是这个。
— IDENTITY 主键由数据库生成, 采用数据库自增长, Oracle不支持这种方式。
— SEQUENCE 通过数据库的序列产生主键, MYSQL 不支持。
— Table 提供特定的数据库产生主键, 该方式更有利于数据库的移植。
@Entity :指定当前类是实体类。
@Table :指定实体类和表之间的对应关系。name:指定数据库表的名称
@Column :指定实体类属性和数据库表之间的对应关系
属性:name:指定数据库表的列名称。
unique:是否唯一 。
nullable:是否可以为空 。
inserttable:是否可以插入 。
updateable:是否可以更新 。
columnDefinition: 定义建表时创建此列的DDL 。
C、创建操作数据的 Repository 对象
public interface CustomerDao extends JpaRepository<Customer,Long>,JpaSpecificationExecutor {
}
对于 JpaRepository 可以从其源码看出:
CustomerDao 继承了 JpaRepository 之后就拥有了CrudRepository、QueryByExampleExecutor、PagingAndSortingRepository 的基本功能方法了,包括基本的增删改查都有了。
D、数据库相关配置 ( application.yml )
server:
port: 8088
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/sample?serverTimezone=UTC&useSSL=false&characterEncoding=UTF8
username: root
password: root
jpa:
database: mysql
show-sql: true
hibernate:
ddl-auto: create
注意
① 使用 springboot 版本 2.0.x 以上的需要使用如图的 driver-class-name 和 url 中配置serverTimezone=UTC&useSSL=false 否则会报错。不信就试试呗。
② 最后一行 ddl-auto : create。此参数是为了方便处理数据库表,该属性的值一般有如下:
validate : 加载hibernate时,验证创建数据库表结构 create : 每次加载hibernate,重新创建数据库表结构,这就是导致数据库表数据丢失的原因。 create-drop : 加载hibernate时创建,退出是删除表结构 update : 加载hibernate自动更新数据库结构
D、为方便演示 demo 起见,在 controller 类中演示。
@RestController
@RequestMapping("/customer")
public class CustomerController {@Autowired
private CustomerDao customerDao;
/**
* 初始化数据
*/
@RequestMapping("/index")
public void index() {
customerDao.save(new Customer("Jack", "Bauer"));
customerDao.save(new Customer("Chloe", "O'Brian"));
customerDao.save(new Customer("Kim", "Bauer"));
customerDao.save(new Customer("David", "Palmer"));
customerDao.save(new Customer("Michelle", "Dessler"));
customerDao.save(new Customer("Bauer", "Dessler"));
}
@RequestMapping("/findAll")
public void findAll() {
List<Customer> customerList = customerDao.findAll();
for (Customer customer : customerList) {
System.out.println(customer.toString());
}
}
/**
* 查询 id 为 1 的数据
*/
@RequestMapping("/findOne")
public void findById() {
Customer customer = customerDao.findById(1L).get();
if (customer != null) {
System.out.println(customer);
}
}
/**
* 根据 id 删除和批量删除数据
*/
@RequestMapping("/delete")
public void delete() {
List<Customer> customerList = null;
System.out.println("删除前的数据:");
customerList = customerDao.findAll();
for (Customer customer : customerList) {
System.out.println(customer.toString());
}
System.out.println("删除ID=3数据:");
customerDao.deleteById(3L);
System.out.println("删除后的数据:");
customerList = customerDao.findAll();
for (Customer customer : customerList) {
System.out.println(customer.toString());
}
}
}
E、控制台会打印如下信息。
① 启动项目后,控制台显示建表成功。打印如下语句
Hibernate: drop table if exists tab_customer Hibernate: create table tab_customer (id bigint not null auto_increment, first_name varchar(255), last_name varchar(255), primary key (id)) engine=MyISAM
② 使用 postman 调用接口 :localhost :8088/customer/index,会插入数据。
Hibernate: select customer0_.id as id1_0_, customer0_.first_name as first_na2_0_, customer0_.last_name as last_nam3_0_ from tab_customer customer0_ Hibernate: insert into tab_customer (first_name, last_name) values (?, ?) Hibernate: insert into tab_customer (first_name, last_name) values (?, ?) Hibernate: insert into tab_customer (first_name, last_name) values (?, ?) Hibernate: insert into tab_customer (first_name, last_name) values (?, ?) Hibernate: insert into tab_customer (first_name, last_name) values (?, ?) Hibernate: insert into tab_customer (first_name, last_name) values (?, ?)
③ 使用 postman 调用接口 :localhost :8088/customer/findAll,会查询 DB 中所有数据。
Hibernate: select customer0_.id as id1_0_, customer0_.first_name as first_na2_0_, customer0_.last_name as last_nam3_0_ from tab_customer customer0_ Customer(id=1, firstName=Jack, lastName=Bauer) Customer(id=2, firstName=Chloe, lastName=O'Brian) Customer(id=3, firstName=Kim, lastName=Bauer) Customer(id=4, firstName=David, lastName=Palmer) Customer(id=5, firstName=Michelle, lastName=Dessler) Customer(id=6, firstName=Bauer, lastName=Dessler)
④ 使用 postman 调用接口 :localhost :8088/customer/delete,会删除 DB 中相应的数据。
删除前的数据: Hibernate: select customer0_.id as id1_0_, customer0_.first_name as first_na2_0_, customer0_.last_name as last_nam3_0_ from tab_customer customer0_ Customer(id=1, firstName=Jack, lastName=Bauer) Customer(id=2, firstName=Chloe, lastName=O'Brian) Customer(id=3, firstName=Kim, lastName=Bauer) Customer(id=4, firstName=David, lastName=Palmer) Customer(id=5, firstName=Michelle, lastName=Dessler) Customer(id=6, firstName=Bauer, lastName=Dessler) 删除ID=3数据: Hibernate: delete from tab_customer where id=? 删除后的数据: Hibernate: select customer0_.id as id1_0_, customer0_.first_name as first_na2_0_, customer0_.last_name as last_nam3_0_ from tab_customer customer0_ Customer(id=1, firstName=Jack, lastName=Bauer) Customer(id=2, firstName=Chloe, lastName=O'Brian) Customer(id=4, firstName=David, lastName=Palmer) Customer(id=5, firstName=Michelle, lastName=Dessler) Customer(id=6, firstName=Bauer, lastName=Dessler)
代码地址 Github :https://github.com/RookieMZL/SpringBoot-JPA
手机扫一扫
移动阅读更方便
你可能感兴趣的文章