您现在的位置是:首页 >技术教程 >SpringBoot整合JPA网站首页技术教程
SpringBoot整合JPA
JPA、Hibernate、Spring Data JPA的关系
JPA是Java Persistence API的简称,中文名Java持久层API,是JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。Sun引入新的JPA ORM规范出于两个原因:其一,简化现有Java EE和Java SE应用开发工作;其二,Sun希望整合ORM技术,实现天下归一。
Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用,最具革命意义的是,Hibernate可以在应用EJB的JavaEE架构中取代CMP,完成数据持久化的重任。
Spring Data JPA是更大的Spring Data家族的一部分,它使实现基于JPA的存储库变得容易。 本模块处理对基于 JPA 的数据访问层的增强支持。 它使构建使用数据访问技术的 Spring 驱动的应用程序变得更加容易。在相当长的一段时间内,实现应用程序的数据访问层一直很麻烦。 必须编写太多样板代码来执行简单的查询以及执行分页和审核。 Spring Data JPA旨在通过将工作量减少到实际需要的数量来显着改进数据访问层的实现。 作为开发人员,您编写存储库接口,包括自定义查找器方法,Spring 将自动提供实现。底层是Hibernate。
简单理解就是JPA是java自带的持久层API,然后Hibernate对JPA进行了二次开发和优化,Spring Data JPA又对Hibernate进行了二次开发和优化。
整合JPA
pom.xml
<dependencies>
<!-- lombok插件依赖 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</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>
</dependency>
<!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.30</version>
<scope>runtime</scope>
</dependency>
<!-- jpa -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
</dependencies>
application.yml
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/spring_boot_jpa_demo?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: 123456
jpa:
# 打印SQL
show-sql: true
hibernate:
# 5种建表策略,一般推荐update或none,首推update。
ddl-auto: update
- create:启动时删除上一次生成的表,并根据实体类生成表,表中数据会被清空
- create-drop:启动时根据实体类生成表,程序关闭时表会被删除
- update:启动时会根据实体类生成表,当实体类属性变动的时候,表结构也会更新,在初期开发阶段使用此选项
- validate:启动时验证实体类和数据表是否一致,在数据结构稳定时采用此选项
- none:不采取任何措施
Person实体类
import lombok.Data;
import org.hibernate.annotations.Comment;
//import org.hibernate.annotations.Table;
import javax.persistence.*;
/**
* 人员
*/
@Data
@Entity
//@Table(appliesTo = "person",comment = "人员表")//appliesTo指表的名称(必填),MySQL表名小写,用Person会抛异常。
public class Person {
@Id//主键标识
@GeneratedValue(strategy = GenerationType.IDENTITY)//数据库主键策略,默认是AUTO。IDENTITY自增有符号主键
@Comment("主键ID")//字段备注
private Long id;
@Column(name = "name",length = 20,unique = true,nullable = false)//字段属性设置
@Comment("名称")
private String name;
@Comment("性别")
private Integer sex;
@Transient//此注解表示数据库不创建该字段
private String ignore;//忽略字段
}
PersonRepository接口
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* 写法参考<a href="https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.query-methods.query-creation"/>
*/
@Repository //不加也可以,只要你使用的时候注入即可。JpaRepository里面有很多简单的CRUD接口,可以少写很多代码。
public interface PersonRepository extends JpaRepository<Person, Long> {
//根据名称精确查询
List<Person> findByName(String name);//自定义方法
//模糊查询
List<Person> findByNameLike(String name);
//分页模糊查询
Page<Person> findAllByNameLike(String name, PageRequest pageRequest);
}
具体写法以及写法所对应的SQL如下:
Test测试类
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import javax.annotation.Resource;
@Slf4j
@SpringBootTest
public class PersonRepositoryTests {
@Resource
private PersonRepository personRepository;
/**
* 新增/修改。一般情况下新增是不传ID的,只有修改才传ID。
*/
@Test
public void save(){
Person person = new Person();
person.setName("Meta39");
person.setSex(0);
this.personRepository.save(person);
log.info("{}",this.personRepository.save(person));
}
/**
* 查询
*/
@Test
public void search(){
// log.info("{}",this.personRepository.findById(1L));//使用框架自带的方法
// log.info("{}",this.personRepository.findByName("Meta"));//使用自定义根据名称查询方法
// log.info("{}",this.personRepository.findByNameLike("%t%"));//使用自定义模糊查询方法
// Page<Person> personPage = this.personRepository.findAll(PageRequest.of(0, 10, Sort.by(Sort.Direction.DESC, "id")));//分页查询
// log.info("{}", personPage);//自带无参分页查询
Page<Person> personPageByNameLike = this.personRepository.findAllByNameLike("%e%", PageRequest.of(0, 10, Sort.by(Sort.Direction.DESC, "id")));
personPageByNameLike.forEach(System.out::println);//自定义模糊分页查询(%M%这种写法是不会有SQL注入的,不信自己可以试试%M% and id = 1)
}
/**
* 删除
*/
@Test
public void delete(){
this.personRepository.deleteById(1L);//根据ID删除一条记录
this.personRepository.deleteAllById(Arrays.asList(1L,2L,3L));//根据ID集合批量删除记录
}
}
总结
JPA相比较MyBatis来说,整体还是非常不错的。可以说简单的单表几乎不用写SQL。复杂的业务建议用SQL去实现,JPA的复杂查询,太啰嗦了!