一.Spring Data JPA介绍
可以理解为JPA规范的再次封装抽象,底层还是使用了Hibernate的JPA技术实现,引用JPQL(Java Persistence Query Language)查询语言,属于Spring整个生态体系的一部分。随着Spring Boot和Spring Cloud在市场上的流行,Spring Data JPA也逐渐进入大家的视野,它们组成有机的整体,使用起来比较方便,加快了开发的效率,使开发者不需要关心和配置更多的东西,完全可以沉浸在Spring的完整生态标准实现下。JPA上手简单,开发效率高,对对象的支持比较好,又有很大的灵活性,市场的认可度越来越高。
JPA是Java Persistence API的简称,中文名为Java持久层API,是JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。
JPA包括以下3方面的内容:
(1)一套API标准。在javax.persistence的包下面,用来操作实体对象,执行CRUD操作,框架在后台替代我们完成所有的事情,开发者从烦琐的JDBC和SQL代码中解脱出来。
(2)面向对象的查询语言:Java Persistence QueryLanguage(JPQL)。这是持久化操作中很重要的一个方面,通过面向对象而非面向数据库的查询语言查询数据,避免程序的SQL语句紧密耦合
(3)ORM(object/relational metadata)元数据的映射。JPA支持XML和JDK5.0注解两种元数据的形式,元数据描述对象和表之间的映射关系,框架据此将实体对象持久化到数据库表中。
我们都知道,在使用持久化工具的时候,一般都有一个对象来操作数据库,在原生的Hibernate中叫做Session,在JPA中叫做EntityManager,在MyBatis中叫做SqlSession,通过这个对象来操作数据库。我们一般按照三层结构来看的话,Service层做业务逻辑处理,Dao层和数据库打交道,在Dao中,就存在着上面的对象。那么ORM框架本身提供的功能有什么呢?答案是基本的CRUD,所有的基础CRUD框架都提供,我们使用起来感觉很方便,很给力,业务逻辑层面的处理ORM是没有提供的,如果使用原生的框架,业务逻辑代码我们一般会自定义,会自己去写SQL语句,然后执行。在这个时候,Spring-data-jpa的威力就体现出来了,ORM提供的能力他都提供,ORM框架没有提供的业务逻辑功能Spring-data-jpa也提供,全方位的解决用户的需求。使用Spring-data-jpa进行开发的过程中,常用的功能,我们几乎不需要写一条sql语句。
Spring Data JPA 让我们解脱了DAO层的操作,基本上所有CRUD都可以依赖于它来实现,在实际的工作工程中,推荐使用Spring Data JPA + ORM(如:hibernate)完成操作,这样在切换不同的ORM框架时提供了极大的方便,同时也使数据库层操作更加简单,方便解耦
springdata jpa、jpa和hibernate三者关系
通俗来讲springdata jpa是对jpa规范的一层封装,hibernate实现了jpa规范。
java代码----->springdata jpa ------>jpa规范------>hibernate------>jdbc ----->mysql数据库
二.配置
1.依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</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-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 引入mysql需要的依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.32</version>
</dependency>
<!-- 引入spring data jpa需要的依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
2.配置文件
spring:
datasource:
# 数据源连接参数
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql:///account
username: root
password: 123
jpa:
hibernate:
ddl-auto: update
show-sql: true
database: mysql
jackson:
serialization:
#json输出格式化
indent-output: true
三.根据实体类生成数据库表案例
1.实体类
package com.chx.springdatajpa.entity;
import javax.persistence.*;
import java.io.Serializable;
@Entity
@Table(name="studentinfo")
public class Student implements Serializable {
@Id
@GeneratedValue //默认自增
private Integer id;
@Column(name="stu_name") //数据库列与实体类属性不一致时配置
private String stuname;
private Integer sex;
private Integer age;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getStuname() {
return stuname;
}
public void setStuname(String stuname) {
this.stuname = stuname;
}
public Integer getSex() {
return sex;
}
public void setSex(Integer sex) {
this.sex = sex;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
启动后日志打印出创建语句
数据库对应创建出数据表
并且配置文件取值为 'update' 数据表 会 根据实体类的修改 修改表结构
ddl-auto
- create:每次运行程序时,都会重新创建表,故而数据会丢失
- create-drop:每次运行程序时会先创建表结构,然后待程序结束时清空表
- upadte:每次运行程序,没有表时会创建表,如果对象发生改变会更新表结构,原有数据不会清空,只会更新(推荐使用)
- validate:运行程序会校验数据与数据库的字段类型是否相同,字段不同会报错
- none: 禁用DDL处理
四.模糊查询案例
dao层
package com.chx.springdatajpa.dao;
import com.chx.springdatajpa.entity.Student;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
public interface StudentDao extends JpaRepository<Student,Integer> {
@Query(value="select * from studentinfo where stu_name=?",nativeQuery = true)
Student findByStuname(String stuname);
}
controller层
先调用添加方法 保存记录
@RequestMapping("/saveAllStudent")
public String saveAllStudent(){
//Hibernate:瞬时状态 游离状态 持久状态
List<Student> students = Arrays.asList(new Student("小明", 1, 24),
new Student("小红", 0, 23),
new Student("小刚", 1, 24));
dao.saveAll(students);
//save(T t):向数据库中增加单条记录
//saveAll(Iterable i):增加多条记录
//saveAndFlush():增加并刷新缓存
return "success";
}
执行后
再调用模糊查询方法
@RequestMapping("/getByName")
@ResponseBody
public Object getByName(){
return dao.findByStuname("小明");
}
执行后