Spring Data JPA 的概述
ORM 的概述
对象关系映射(英语:(Object Relational Mapping,简称 ORM,或 O/RM,或 O/R mapping),是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。从效果上说,它其实是创建了一个可在编程语言里使用的–“虚拟对象数据库”。
综上所述:ORM 技术中 的操作实体类就相当于操作数据库表建立两个映射关系:
- 实体类和表的映射关系
- 实体类中属性和表中字段的映射关系
Hibernate 的概述
Hibernate 是一个开放源代码的对象关系映射框架,它对 JDBC 进行了非常轻量级的对象封装,它将 POJO与数据库表建立映射关系,是一个全自动的 orm 框架,hibernate 可以自动生成 SQL 语句,自动执行,使得 Java 程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate 可以应用在任何使用 JDBC 的场合,既可以在 Java 的客户端程序使用,也可以在 Servlet/JSP 的 Web 应用中使用,最具革命意义的是,Hibernate可以在应用 EJB 的 JaveEE 架构中取代 CMP,完成数据持久化的重任。
JPA 的概述
JPA 的全称是 Java Persistence API,即 Java 持久化 API,是 SUN 公司推出的一套基于 ORM 的规范,内部是由一系列的接口和抽象类构成。JPA 通过 JDK 5.0 注解或 XML 描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。
Spring Data Jpa 的概述
Spirng Data Jpa 是 spring 提供的一套简化 JPA 开发的框架,按照约定好的方法命名规则写 dao 层接口,就可以在不写接口实现的情况下,实现对数据库的访问和操作。除了 CRUD 的功能外,同时提供了很多如分页、排序、复杂查询等等的功能。
Spring Data JPA 可以理解为 JPA 规范的再次封装抽象,底层还是使用了 Hibernate 的 JPA 技术实现。
SpringBoot 整合 Spring Data JPA
配置属性文件
## 数据源配置
spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=admin
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
##Spring Data JPA 配置
spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect
##运行时输出 jpa 执行的 sql 语句
spring.jpa.show-sql=true
## spring-boot-starter-data-jpa 自动映射创建表动作 配置: 有表更新,无表创建
spring.jpa.hibernate.ddl-auto=update
#应用端口
server.port=8080
#应用项目名称
#server.context-path=/mydemo
#修改 tomcat 的 URIEncoding 为 UTF-8
server.tomcat.uri-encoding=UTF-8
#集中解决各种编码问题
#banner.charset=UTF-8
spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true
spring.http.encoding.force=true
spring.messages.encoding=UTF-8
#jackson 对日期时间格式化设置:时间格式
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
#jackson 对日期时间格式化设置:时区设置
spring.jackson.time-zone=GMT+8
创建实体
//学生实体类
/**
* 由于数据库没有数据表@Entity 创建实体
* @table(name="studenttb")在 springbootjpahelloworlddb 里面自动创建表名为 studenttb 的数据表
*/
@Entity
@Table(name="studentdb")
public class Student {
@Id//实体类的主键
@GeneratedValue(strategy = GenerationType.IDENTITY)//自动增长列
private Integer id;//id
private String name;//姓名
private String age;//年龄
}
Spring Data JPA 技术也采用了 ORM 的思想,操作实体类就相当于操作数据库表。我们需要建立两个映射关系:
- 实体类和表的映射关系,通过注解@Entity,@Table 实现映射;
- 实体类中属性和表中字段的映射关系,通过注解@Id,@GeneratedValue,@Column 实现映射。
JPA 中常用的注解标签:
- @Entity:标记在类名上面,作为实体类的标识;
- @Table 标注的常用选项是 name,用于指明数据库的表名。
- @Id:设置对象表示符,标识的实体类的属性映射对应表中的主键;
- @GeneratedValue:设置标识符的生成策略,常与@Id 一起使用。参数:strategy 指定具体的生成策略:
方式一:@GeneratedValue(strategy=GenerationType.AUTO) 也是默认策略,即写成@GeneratedValue也可;类似于 hibernate 的 native 策略,生成方式取决于底层的数据库。
方式二:
@GeneratedValue(strategy = GenerationType.IDENTITY)指定“自动增长”策略,适用于 MySQL;
方式三:
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = “seqtblperson”)指定“序列”策略,常用于 Oracle,其中 generator 表示生成器的名字。而且还要指定@SequenceGenerator(name = “seqtblperson”, sequenceName = “seqtblperson”, allocationSize = 1)注解配合使用。其中 name 指定生成器的名字(与 generator 的值一样),sequenceName 指定数据库中定义序列的名字,allocationSize指定序列每次增长 1。
- @Column:描述数据库表中该字段的定义,具有以下属性。
name:表示数据库表中该字段的名称,默认情形属性名称一致。
nullable:表示该字段是否允许为 null,默认为 true。
unique:表示该字段是否是唯一标识,默认为 false。
length:表示该字段的大小,仅对 String 类型的字段有效。
insertable:表示在 ORM 框架执行插入操作时,该字段是否应出现 INSETRT 语句中,默认为 true。
updateable:表示在 ORM 框架执行更新操作时,该字段是否应该出现在 UPDATE 语句中,默认为true。对于一经创建就不可以更改的字段,该属性非常有用,如对于 birthday 字段。- columnDefinition:表示该字段在数据库中的实际类型。通常 ORM 框架可以根据属性类型自动判断数据库中字段的类型,但是对于 Date 类型仍无法确定数据库中字段类型究竟是 DATE,TIME 还是TIMESTAMP。此外,String 的默认映射类型为 VARCHAR,如果要将 String 类型映射到特定数据库的 BLOB或 TEXT 字段类型,该属性非常有用。
- @OrderBy:在加载数据的时候可以为其指定顺序。
- @Transient:表示该属性并非一个到数据库表的字段的映射,ORM 框架将忽略该属性。
如果一个属性并非数据库表的字段映射。就务必将其标示为@Transient。否则。ORM 框架默认其注解为@Basic
编写 dao 接口
//接口 StudentRepository,并继承 JpaRepository 接口
public interface StudentRepository extends JpaRepository<Student, Integer>{
//JpaRepository<实体类, 实体类的主键类型>
}
Spring Data JPA 的运行过程和原理主要如下:
- 通过 JdkDynamicAopProxy 的 invoke 方法创建了一个动态代理对象;
- 动态代理对象 SimpleJpaRepository 当中封装了 JPA 的操作(借助 JPA 的 api 完成数据库的 CRUD);
- 通过 Hibernate 完成数据库操作。
编写 controller 层增删改查
@RestController
public class StudentController {
@Autowired
private StudentRepository repository;
/**
* 查询所有学生记录 http://localhost:8080/selectAllStu
*
* @param student * @return
*/
@GetMapping("/selectAllStu")
public Object selectAllStudent() {
return repository.findAll();
}
/**
* 添加一条学生记录 http://localhost:8080/addStu?name=刘一&age=100
*
* @param student * @return
*/
@GetMapping("/addStu")
public Object addStudent(Student student) {
System.out.println("student=>" + student);
student = repository.save(student);
return student;
}
/**
* 编辑一条学生记录 http://localhost:8080/updateStu?name=刘一&age=10&id=4
*
* @param student * @return
*/
@GetMapping("/updateStu")
public Object updateStudent(Student student) {
System.out.println("student=>" + student);
student = repository.save(student);
return student;
}
/**
* 删除一条学生记录 http://localhost:8080/delStu?id=4
*
* @param student * @return
* @return
*/
@RequestMapping("/delStu")
public Object delStudent(Student student) {
System.out.println("student=>" + student);
repository.delete(student);
return "成功";
}
编写主类
@EnableJpaRepositories("com.ctt.springboot.repository")
@SpringBootApplication
public class SpringDataJpa1Application {
public static void main(String[] args) {
SpringApplication.run(SpringDataJpa1Application.class, args);
}
}
SpringJpa 持久层操作
默认继承方法
关键字抽象方法
命名约定如下:
- 条件属性通过条件关键字连接。
- 条件属性的首字母必须大写。
Spring Data JPA 解析方法名的原则
- And — 等价于 SQL 中的 and 关键字,比如 findByUsernameAndPassword(String user, Striang pwd)根据用户名字和密码查找。
- Or — 等价于 SQL 中的 or 关键字,比如 findByUsernameOrAddress(String user, String addr)根据用户名或地址查找;
- Between — 等价于 SQL 中的 between 关键字,比如 findBySalaryBetween(int max, int min)查询薪资在
min 和 max 之间;- LessThan — 等价于 SQL 中的 “<”,比如 findBySalaryLessThan(int max);
- GreaterThan — 等价于 SQL 中的”>”,比如 findBySalaryGreaterThan(int min);
- IsNull — 等价于 SQL 中的 “is null”,比如 findByUsernameIsNull();
- IsNotNull — 等价于 SQL 中的 “is not null”,比如 findByUsernameIsNotNull();
- NotNull — 与 IsNotNull 等价;
- Like — 等价于 SQL 中的 “like”,比如 findByUsernameLike(String user);
- NotLike — 等价于 SQL 中的 “not like”,比如 findByUsernameNotLike(String user);
- OrderBy — 等价于 SQL 中的 “order by”,比如 findByUsernameOrderBySalaryAsc(String user);
- Not — 等价于 SQL 中的 “! =”,比如 findByUsernameNot(String user);
- In — 等价于 SQL 中的 “in”,比如 findByUsernameIn(Collection userList) ,方法的参数可以是 Collection类型,也可以是数组或者不定长参数;
- NotIn — 等价于 SQL 中的 “not in”,比如 findByUsernameNotIn(Collection userList) ,方法的参数可以是Collection 类型,也可以是数组或者不定长参数;
Spring Data JPA 关键字抽象方法的使用
- 在 com.ysd.springboot.repository 下配置 StudentRepository 类中添加如下代码:
public interface StudentRepository extends JpaRepository<Student, Integer>{
//根据姓名模糊查找学生信息
public List<Student> findByStudentNameContaining(String name);
}
- 在 StudentController 类下添加如下代码:
/***
* http://localhost:8080/findStudentByName?name=刘
* @param name * @return
*/
@RequestMapping("/findStudentByName")
public Object findStudentByName(String name) {
List<Student> student = repository.findByStudentNameContaining(name);
return student;
}