Spring Data JPA是Spring Data家族的一部分,可以轻松实现基于JPA的存储库。 此模块处理对基于JPA的数据访问层的增强支持。 它使构建使用数据访问技术的Spring驱动应用程序变得更加容易。
在相当长的一段时间内,实现应用程序的数据访问层一直很麻烦。 必须编写太多样板代码来执行简单查询以及执行分页和审计。 Spring Data JPA旨在通过减少实际需要的工作量来显著改善数据访问层的实现。 作为开发人员,您编写repository接口,包括自定义查找器方法,Spring将自动提供实现。
Jpa、Hibernate、Spring Data Jpa三者之间的关系,如下图所示:

总的来说JPA是ORM规范,Hibernate、TopLink等是JPA规范的具体实现,这样的好处是开发者可以面向JPA规范进行持久层的开发,而底层的实现则是可以切换的。Spring Data Jpa则是在JPA之上添加另一层抽象(Repository层的实现),极大地简化持久层开发及ORM框架切换的成本。
编写第一个Spring Data JPA案例。
项目结构图如下:

实现步骤:
1.配置application.yml
#yml格式配置文档范例
server:
#端口配置
port: 8080
#上下文
servlet:
context-path: /jpademo
#数据源配置
spring:
#使用自定义banner的配置
output:
ansi:
enabled: always
datasource:
url: jdbc:mysql://localhost:3306/springboot?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
username: root
password: root
# 使用druid数据源
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
filters: stat
maxActive: 500
initialSize: 1
maxWait: 60000
minIdle: 1
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: select 'x'
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
maxOpenPreparedStatements: 20
jpa:
show-sql: true
properties:
hibernate:
#dialect: org.hibernate.dialect.MySQL5Dialect ,注意这个是不支持事务的方言。
dialect: org.hibernate.dialect.MySQL5InnoDBDialect
format_sql: true
#配置懒加载策略
enable_lazy_load_no_trans: true
hbm2ddl:
auto: update
2.创建Students实体类
package com.oracle.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.*;
import java.io.Serializable;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity //表示这个类对应数据库中的一张表
public class Students implements Serializable,Cloneable {
//既然是表,就必须有主键
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY) //使用数据库默认的主键生成策略
private int sid; //主键
@Column(length = 20) //规定学生的姓名不超过20个字符
private String sname; //姓名,默认是占用255个字符。
@Column(length = 2)
private String gender; //性别
@Column(length = 32)
private String date; //出生日期
private String school; //所在学校
private String major; //所学的专业
private boolean status; //状态 1:在籍 0:辍学
}
3.创建StudentsRepository业务逻辑接口。
package com.oracle.repository;
import com.oracle.entity.Students;
import org.springframework.data.jpa.repository.JpaRepository;
public interface StudentsRepository extends JpaRepository<Students,Integer> {
}
4.创建StudentsService服务层接口和实现类
StudentsService.java
package com.oracle.service;
import com.oracle.entity.Students;
import java.util.List;
public interface StudentsService {
Students save(Students s); //保存一个学生对象;
Students queryStudentsBySid(Integer sid); //查询单个学生
void delete(int sid);
Students update(Students s);
List<Students> queryAllStudents(); //查询所有学生
}
StudentsServiceImpl.java
package com.oracle.service.impl;
import com.oracle.entity.Students;
import com.oracle.repository.StudentsRepository;
import com.oracle.service.StudentsService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
@Service
public class StudentsServiceImpl implements StudentsService {
@Resource
private StudentsRepository studentsRepository;
@Override
public Students save(Students s) {
return studentsRepository.save(s);
}
@Override
public Students queryStudentsBySid(Integer sid) {
return studentsRepository.getOne(sid);
}
@Override
public void delete(int sid) {
studentsRepository.deleteById(sid);
}
@Override
public Students update(Students s) {
return studentsRepository.save(s);
}
@Override
public List<Students> queryAllStudents() {
return studentsRepository.findAll();
}
}
5.编写测试类,测试StudentsService接口里的各个方法。
package com.oracle.service;
import com.oracle.entity.Students;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import javax.annotation.Resource;
import java.util.List;
@RunWith(SpringRunner.class)//指定Junit4使用Spring提供的测试环境
@SpringBootTest
public class StudentsServiceTest {
@Resource
private StudentsService studentsService;
//测试保存单个学生对象
@Test
public void testSaveStudents(){
Students s = new Students();
s.setSname("东方不败");
s.setGender("女");
s.setSchool("黑木崖大学");
s.setDate("2000-10-10");
s.setMajor("葵花宝典");
s.setStatus(true);
s = studentsService.save(s);
System.out.println(s);
}
@Test
public void testQueryStudentsBySid(){
//查询出东方不败。
Students s = studentsService.queryStudentsBySid(2);
System.out.println(s);
}
//更新学生资料
@Test
public void testUpdateStudents(){
//把东方不败的性别改为‘男’
Students s = studentsService.queryStudentsBySid(2);
s.setGender("男");
studentsService.update(s);
System.out.println(s);
}
//查询所有学生
@Test
public void testQueryAllStudents(){
List<Students> studentsList = studentsService.queryAllStudents();
for(Students s: studentsList){
System.out.println(s);
}
}
//删除学生
@Test
public void testDeleteStudentsBySid(){
studentsService.delete(2);
}
}