Hibernate / JPA
什么是Hibernate
Hibernate是一个开源的对象关系映射(ORM)框架,它广泛用于Java应用程序中,用于处理数据库操作和数据持久化。Hibernate提供了一种将Java对象映射到数据库表的方法,并从数据库中检索这些对象,这样开发者就可以在编程时更多地关注于对象和数据之间的交互,而不是直接与SQL语句打交道
什么是JPA
JPA(Java Persistence API)是Java EE和Java SE环境中提供对象/关系映射(ORM)功能的一套规范。这意味着JPA自身不是一个框架,而是定义了一系列的API和概念,这些API和概念使得开发者能够以面向对象的方式来操作数据库中的数据。JPA的目标是简化现有的Java ORM技术,使得数据库操作更加容易管理和维护。
在Spring Boot中,hibernate是默认的JPA规范的实现。
@Entity
@Entity
注释标识一个类为实体,通常会在下面再加上@Table(name = "tableName")
注释来表示这个实体对应数据库中的那个表。对于属性,使用@Column(name="attributeName")
标识Java实体类中的属性对应数据库表中的属性。
对于主键属性,例如id,使用@Id
和 @GeneratedValue(strategy = GenerationType.strategyName)
来对其进行标识。下图是一些不同的生成策略:
Entity Manager
Entity Manager 是JPA规范中的对象,这个对象负责管理实体生命周期和数据库操作。Hibernate会实例化它。
Spring Boot 会自动创建JPA Entity Mangaer 和 Data Source。 Data Source被定义在application.properties
中,包括jdbc url
,username
,password
等等。我们可以把JPA Entity Manager注入到DAO中使用它。
Create(增)
生成一个对象并保存到数据库中,使用下面的语句。对于DAO的实现类,使用@Repository
进行注释
1 |
|
Read(查)
- 查询单个对象
根据主键查询单个对象使用EntityManager
的find
方法:1
Student myStudent = entityManger.find(Student.class, 1); // 查找id为1的学生对象并返回,如果不存在则会返回null
- 使用JPQL查询语句查询多个对象
JPQL是JPA用来检索对象的语句,和SQL语句鱼类,但是JPQL语法是基于实体的名字和实体的属性。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18//查询student表的所有记录
TypedQuery<Student> theQuery = entityManager.createQuery("FROM Student", Student.class);//Student是实体的名字,不是表的名字
List<Student> students = theQuery.getResultList();
//查询lastName为某个值的记录
TypedQuery<Student> theQuery = entityManager.createQuery("FROM Student WHERE lastName = 'Doe'", Student.class);// lastName是Student实体类的属性名。
List<Student> students = theQuery.getResultList();
//带参数的查询
public List<Student> findByLastName(String theLastName) {
TypedQuery<Student> theQuery = entityManager.createQuery("FROM Student WHERE lastName=:theData", Student.class);//:theData是一个占位符,及参数的位置,名字可以是随意的
theQuery.setParameter("theData", theLastName);
return theQuery.getResultList();
}
Update(改)
- 修改单个对象
首先查找到要修改的对象,然后通过setter
方法改变属性的值,最后通过EntityManager
的merge()
方法更新实体:1
2
3Student theStudent = entityManager.find(Student.class);
theStudent.setFirstName("Scooby");
entityManager.merge(theStudent); - 修改多个对象
使用下面的方法修改多个记录,方法返回的值是更新行的数量。1
2int numRowsUpdated = entityManager.createQuery("UPDATE Student SET lastName = 'Tester'").executeUpdate()
Delete(删)
-
删除单个对象
1
2
3int id = 1;
Student theStudent = entityManager.find(Student.class, 1);
entityManager.remove(theStudent); -
删除多个对象:
1
int numRowsDeleted = entityManager.createQuery("DELETE FROM Student WHERE lastName='Smith'").executeUpdate();
生成表
通过在application.properties
中添加设置,可以根据实体和其属性自动生成需要的数据表。下图是不同的生成策略:
Spring Data JPA
Spring Data JPA 是一个用于简化数据访问层(DAO)代码的库,主要针对 Java 应用程序。它是 Spring Data 的一部分,旨在通过减少数据访问层的重复代码来提高开发效率。
JpaRepository
Spring Data JPA 提供了一个JpaRepository
接口, 它暴露一些方法,例如findAll(..)
、findById(..)
、save(...)
等等。只需要注入实体,就可以直接用这些方法。减少了不同实体的数据访问层相似代码的重复构建。
1 | public interface EmployRepository extends JpaRepository<Employee, Integer> { |
注入实体和其主键的类型,不需要实现这个接口,Spring Data JPA会帮助实现。
Spring Data REST
Spring Data REST的目的是将存储库自动导出为 RESTful 资源。这意味着你可以不需要编写大量的控制器代码,直接将数据访问层转化为可通过 HTTP 访问的 REST 接口。
Spring Data REST 自动为 Spring Data 存储库创建 RESTful 端点。这包括 CRUD 操作(创建、读取、更新、删除)以及分页和排序功能,全部通过 HTTP 端点暴露出来。
所以对于Spring Data REST只需要Entity, JpaRepository就够了
Spring data REST的一些定制化
在application.properties
中使用:spring.data.rest.base-path = /xxxx
就可以改变暴露端点的基本路径
通常,Spring data REST暴露的端点就是实体名称第一个字母小写后并变为复数的形式。例如,Employee
实体暴露的端点就是\employees
。
但是我们一般自己指定其暴露的端点名称, 使用@RepositoryRestResource(path="xxxx")
注释:
1 |
|
其他的定制化,例如分页中page的大小,page的最大值,都可以在配置文件中配置。具体的可以查看spring提供的属性列表
使用page属性:http://localhost:8080/employee?page=0
使用sort属性:http://localhost:8080/employee?sort=lastName, desc