springboot整合hibernate_峰哥说技术系列-17 .Spring Boot 整合 Spring Data JPA

1fa36fc9eec48aaa9fce389a9ef58526.png

今日份主题

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

B)修改操作,将关羽的名字改成关云长

4b336420efae371d31e03695a0b519df.png

C)删除操作,删除id=11的记录。

78cfb7cc84ae1f6b053417886e30ecfa.png

D)查询操作,查找id为1的记录

f3636a5bcfa0ebe430571001f95c119e.png

E)分页查询

e8c493910e7caf72918920bd0d3ccdca.png

以上就是spring data jpa的基本用法,但是对于查询我们不仅仅是编号、分页查询。有时候需要根据多个条件进行查询,请继续关注峰哥后续文章,我会继续讲解这些问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值