JPA介绍
JPA的全称是Java Persistence API,提供了一个规范,用于将数据通过Java对象持久化、读取和管理数据库中的关系表。所以JPA本质上就是一种ORM规范,它的目标是实现ORM的天下归一。
1、java数据库编程的进化史:
1)jdbc:
jdbc是jdk提供数据库操作最基础的api,它提供了一套操作数据库的标准规范,不同的数据库厂商通过自己的驱动jar来适配该规范。
Class.forName("com.mysql.cj.jdbc.Driver");
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test","root","123456");
// 执行查询
Statement stmt = conn.createStatement();
String sql = "SELECT id, name, url FROM websites";
ResultSet rs = stmt.executeQuery(sql);
2)hibernate、mybatis 等ORM框架:
- Hibernate 可以认为是JPA规范的的一种实现,使用起来比较方便,但是不够灵活;
- Mybatis是一个持久层的sql mapping框架。 mybatis的优势在于可以灵活的写SQL,自由度比较高
3)spring data jpa:
spring data jpa不是像Hibernate那样对jpa的实现,而是对其更进一步做了封装,使用起来非常简单、灵活。
spring data jpa的目的就是不让程序员花太多时间在数据库层面的处理,所以要做的只是声明接口(类似于mybatis),而且spring data jpa会帮常用sql都帮你拼写好(不像mybatis那样,还需要自己写sql或者mapper)。基于spring data jpa编写持久层逻辑,一般分为如下几步:
- 定义实体类,关联数据库中的表。
- 声明持久层接口,接口需要继承Repository。
- 接口中声明需要的方法,spring data jpa会自动给我们生成实现代码
Spring data jpa有以下几个常用的接口:
- Repository:仅仅是一个标识,表明任何继承它的均为仓库接口类,方便Spring自动扫描识别, 一般不在程序中直接使用。
- CrudRepository:继承Repository,实现了一组CRUD相关的方法,这个用的比较多,一般如果上层业务只需要基本的增删改查,继承这个接口就可以了。
- JpaRepository:继承PagingAndSortingRepository,实现一组JPA规范相关的方法。这个也用的比较多,它和CrudRepository区别在于支持分页和排序。
简单示例
创建springboot项目:
1)pom.xm如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.qiyi.test</groupId>
<artifactId>TestSpringBoot</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>TestSpringBoot</name>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.4.RELEASE</version>
<relativePath />
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</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>
<scope>runtime</scope>
</dependency>
<!--引入JPA的依赖关系 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.9</version>
</dependency>
</dependencies>
<build>
</build>
</project>
2)application.properties:
spring.jpa.show-sql = true
logging.level.org.springframework.data=DEBUG
spring.jpa.hibernate.ddl-auto=
spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&allowMultiQueries=true
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
3)定义实体类:
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
(name="test")
public class Test{
(strategy = GenerationType.IDENTITY)
private Integer id;
(name = "name")
private String name;
(name = "service_code")
private String serviceCode;
private int status = 0;//0:正常、-1异常
//set get方法
}
4)dao接口:
import org.springframework.data.jpa.repository.JpaRepository;
import com.qiyi.test.TestSpringBoot.entity.WoodyService;
public interface TestDao extends JpaRepository<Test, Integer> {
}
5)controller层:
public class TestController {
private TestDao testDao;
("/jpsTest")
public JSONObject jpsTest(HttpServletRequest request,HttpServletResponse httpResponse) {
JSONObject res = new JSONObject();
try {
List<WoodyService> findAll = testDao.findAll();
Optional<WoodyService> findById = testDao.findById(33);
System.out.println(findById);
System.out.println("==============");
long count = testDao.count();
System.out.println(count);
res.put("data",findAll);
res.put("code","success");
} catch (Exception e) {
res.put("code","error");
return res;
}
return res;
}
}
注:省略了service层.
可以看到,dao层接口继承了JpaRepository后,默认会有如下findXXX方法,以及count等方法。
查询规范
直接在接口中定义查询方法,如果是符合规范的,可以不用写实现,目前支持的关键字写法如下:
参考:http://www.machengyu.net/tech/2019/06/29/spring-data-jpa-demo.html