![1fa36fc9eec48aaa9fce389a9ef58526.png](https://i-blog.csdnimg.cn/blog_migrate/5ad93144d77d0308390ec70f3f97e490.jpeg)
今日份主题
Spring Boot 整合 Spring Data JPA
JPA(Java Persistence API)是用于对象持久化的 API,是Java EE 5.0 平台标准的 ORM 规范,它使得应用程序以统一的方式访问持久层。
大家一定听过大名鼎鼎的Hibernate,在国内早期很多JavaEE项目使用该框架,现在在国外依然非常火爆。其实JPA和Hibernate之间是有一定的关系的。这里给大家介绍一下。
JPA 是 Hibernate 的一个抽象(就像JDBC和JDBC驱动的关系)。JPA 本质上就是一种 ORM 规范,不是ORM 框架,这是因为 JPA 并未提供 ORM 实现,它只是制订了一些规范,提供了一些编程的 API 接口,但具体实现则由 ORM 厂商提供实现。Hibernate 除了作为 ORM 框架之外,它也是一种 JPA 实现。从功能上来说, JPA 是 Hibernate 功能的一个子集。
JPA 的目标之一是制定一个可以由很多供应商实现的 API,Hibernate 3.2+、TopLink 10.1+ 以及 OpenJPA 都提供了 JPA 的实现。
Spring Data 是 Spring 的一个子项目。用于简化数据库访问,支持NoSQL 和 关系数据存储。其主要目标是使数据库的访问变得方便快捷。Spring Data Jpa 致力于减少数据访问层 (DAO) 的开发量. 开发者唯一要做的,就是声明持久层的接口,其他都交给 Spring Data JPA 来帮你完成。
Spring boot整合Spring Data JPA,我们可以通过一个案例来带着大家入门学习一下。有整合MyBatis的基础,应该不是难事。
案例:通过Spring Data JPA操作两张关联表,完成表的增、删、查、改操作。
步骤
01在MySql中创建数据库empdb。特别说明不需要创建表。只要做好能自动完成表结构的创建。
02创建Spring boot工程chapter05-jpa.并添加mysql、durid、jpa、web依赖。工程的创建省略。
依赖如下:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.10</version>
</dependency>
03在application.properties进行相关的配置。
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.username=root
spring.datasource.url=jdbc:mysql://localhost:3306/empdb?serverTimezone=UTC
spring.datasource.password=1234
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.database=mysql
spring.jpa.database-platform=mysql
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect
说明
在spring data jpa中,它的配置spring.jpa.hibernate.ddl-auto的取值如下:
a)create:每次运行程序时,都会重新创建表,故而数据会丢失
b)create-drop:每次运行程序时会先创建表结构,然后待程序结束时清空表
c)upadte:每次运行程序,没有表时会创建表,如果对象发生改变会更新表结构,原有数据不会清空,只会更新(推荐使用)
d)validate:运行程序会校验数据与数据库的字段类型是否相同,字段不同会报错
e)none: 禁用DDL处理
spring.jpa.hibernate.show-sql:表示在运行的时候是否在控制台显示执行的sql语句。一般在调试和开发阶段会打开该配置。
spring.jpa.hibernate.database=mysql,表示使用的是mysql数据库。
spring,jpa.database-platform=mysql,是设置默认的数据库存储引擎。这里默认的是mysql的引擎。
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect,:表示数据库使用的方言。因为不同的数据库生成的sql语句有一定的差异性。
04编写实体类Emp。
@Entity(name = "t_emp")
@JsonIgnoreProperties(value = { "hibernateLazyInitializer", "handler" })
public class Emp{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(name = "name",length = 50,nullable = false)
private String name;
@Column(name = "sex",length = 10)
private String sex;
@Column(name = "did")
private Integer deptId;
//getter和setter省略...
}
说明
@JsonIgnoreProperties:hibernate对象懒加载,json序列化失败,因为懒加载这个对象属性只是一个代理对象,如果json直接当作一个存在的属性去序列化就会出现错误。
@Entity 是一个必选的注解,声明这个类对应了一个数据库表。
@Id 注解声明了实体唯一标识对应的属性。
@GeneratedValue:这个是设置主键的自动增长策略。
@Column(name = "name",length = 50,nullable = false) 用来声明实体属性的表字段的定义。默认的实体每个属性都对应了表的一个字段。字段的名称默认和属性名称保持一致(并不一定相等)。这里表示字段名name,长度50,字段非空。
05编写接口EmpDao。
public interface EmpDao extends JpaRepository<Emp,Integer> {
}
代码解释:EmpDao接口继承JpaRepository接口。该接口提供了很多的关于数据库操作的方法基本方法。有基本的增删查过、分页查询、排序查询。这也正是jpa的强大之处。有兴趣的同学可以进去看看接口中声明的方法。这里不做过多的解读。
06创建包service,创建EmpService。
@Service
@Transactional
public class EmpService {
@Autowired
private EmpDao empDao;
public Emp saveEmp(Emp emp){
Emp emp1 = empDao.save(emp);
return emp1;
}
public boolean deleteById(Integer id){
try{
empDao.deleteById(id);
return true;
}catch (Exception e){
return false;
}
}
public Emp updateEmp(Emp emp){
Emp emp1 = empDao.saveAndFlush(emp);
return emp1;
}
public Emp findEmpById(Integer id){
Emp emp = empDao.getOne(id);
return emp;
}
public List<Emp> getEmps(){
return empDao.findAll();
}
public Page<Emp> getEmpByPage(Integer pageNum,Integer pageSize){
PageRequest pageable=PageRequest.of(pageNum-1,pageSize);
Page<Emp> page = empDao.findAll(pageable);
return page;
}
}
07创建包controller,创建EmpController处理器。
@RestController
@RequestMapping("/emp")
public class EmpController {
@Autowired
private EmpService empService;
@PostMapping("/save")
public Emp saveEmp(Emp emp){
Emp emp1 = empService.saveEmp(emp);
return emp1;
}
@DeleteMapping("/delete/{id}")
public boolean deleteEmp(@PathVariable("id") Integer id){
return empService.deleteById(id);
}
@PutMapping("/update")
public Emp updateEmp(Emp emp){
Emp emp1 = empService.updateEmp(emp);
return emp1;
}
@GetMapping("/{id}")
public Emp getEmpById(@PathVariable("id") Integer id){
return empService.findEmpById(id);
}
@GetMapping("/list")
public List<Emp> getEmpList(){
return empService.getEmps();
}
@GetMapping("/page")
public Map<String,Object> getEmpByPage(@RequestParam("pageNum") Integer pageNum, @RequestParam(value = "pageSize",defaultValue = "2") Integer pageSize){
Page<Emp> page= empService.getEmpByPage(pageNum,pageSize);
Map<String,Object> map=new HashMap<>();
map.put("总页数",page.getTotalPages());
map.put("查询本页记录",page.getContent());
map.put("当前页号",page.getNumber()+1);
map.put("页面大小",page.getSize());
map.put("总记录数",page.getTotalElements());
map.put("当前页记录数",page.getNumberOfElements());
return map;
}
}
代码解释:这里所有的测试,都返回json到前台。对于分页查询,一般返回page就可以了。这里为了解释清楚,专门把数据取出来封装到map中。
08在postman中进行测试,结果如下:
A)添加操作
![3c8204450daade3aaaa6b0923378a992.png](https://i-blog.csdnimg.cn/blog_migrate/74d6db78bee02d1551061344c140b60c.jpeg)
B)修改操作,将关羽的名字改成关云长
![4b336420efae371d31e03695a0b519df.png](https://i-blog.csdnimg.cn/blog_migrate/6ce686002bec039bb114c65fed278fa6.jpeg)
C)删除操作,删除id=11的记录。
![78cfb7cc84ae1f6b053417886e30ecfa.png](https://i-blog.csdnimg.cn/blog_migrate/a62450aac35e6ff01ca3bfaaa63a748d.png)
D)查询操作,查找id为1的记录
![f3636a5bcfa0ebe430571001f95c119e.png](https://i-blog.csdnimg.cn/blog_migrate/16ee2edb78d0923eb11c2872ef8f5dd1.jpeg)
E)分页查询
![e8c493910e7caf72918920bd0d3ccdca.png](https://i-blog.csdnimg.cn/blog_migrate/13827d21c35a095f80c763978049156e.jpeg)
以上就是spring data jpa的基本用法,但是对于查询我们不仅仅是编号、分页查询。有时候需要根据多个条件进行查询,请继续关注峰哥后续文章,我会继续讲解这些问题。