Spring Data
一、为什么要用Spring Data
在实际开发过程中,会接触到不同的存储技术。比如针对不同的场景,需要es、mysql或者redis。那么开发人员就需要去学校这些存储技术的不同脚本或者相关中间件,无疑开发成本和时间成本是比较大的。
所以希望有一种技术,能够统一这些不同的存储方式的实现。spring data就是来做这样的事情的。
操作不同的存储技术,使用对应的spring data模板即可。
spring data帮助我们统一了数据访问层,降低了学习成本,提升了开发效率。针对不同的存储技术,提供了不同的模板对象
总结
-
S p r i n g D a t a 致力为数据访问 ( D A O ) 提供熟悉且一致的基于 S p r i n g 的编程模板 \color{red}{Spring\ Data致力为数据访问(DAO)提供熟悉且一致的基于Spring的编程模板} Spring Data致力为数据访问(DAO)提供熟悉且一致的基于Spring的编程模板
-
其目的是统一和简化不同类型持久存储的访问 \color{red}{其目的是统一和简化不同类型持久存储的访问} 其目的是统一和简化不同类型持久存储的访问
二、JPA介绍及JDBC的关系
JPA与JDBC:
- 相同处:
- 都跟数据库操作有关,JPA 是JDBC 的升华,升级版。
- JDBC和JPA都是一组规范接口
- 都是由SUN官方推出的
- 不同处
- .JDBC是由各个关系型数据库实现的, JPA 是由ORM框架实现
- JDBC 使用SQL语句和数据库通信。 JPA用面向对象方式, 通过ORM框架来生成SQL,进行操作。
- JPA在JDBC之上的, JPA也要依赖JDBC才能操作数据库。
加载JDBC驱动,其实就是指定具体存储技术的实现
JDBC是我们最熟悉的用来操作数据库的技术,但是随之而来带来了一些问题:
- 需要面向SQL语句来操作数据库,开发人员学习成本更高。
- 数据库的移至性不高,不同数据库的SQL语句无法通用。
- java对象和数据库类型的映射是个麻烦事。
举个例子:
现在我要和另一个国家的人进行交流:
那么需要用英语来进行交流,那么不同国家的人会使用不同的语言进行交流。对于我来说,若要和不同国家的人打交道,我的学习成本是比较大的。
上面的我相当于Java,不同国家的人相当于不同的存储技术。若使用JDBC,因为不同的存储技术之间规范不一样,则需要开发人员去学习相关的规范。
若能够有统一规范的工具就好了,比如翻译机:
此时,我只需要说中文,然后选定翻译机的模板让他去帮我做转换成其他国家语言的操作。那么对我而言,和谁讲话都只需要说中文就好了,减少了很多学习成本(只需要学习这个翻译机怎么用就行)。
这里的翻译机就相当于jpa。
当然我打招呼会指定某个外国人,比如 hello 二狗,所以这个翻译机需要找到二狗是哪个外国人。
这里翻译机找到外国人的过程,就是进行ORM映射的过程,所以我们需指定好类的每个属性和某个字段的映射关系。
所以, J P A 是一种 O R M 规范! \color{red}{JPA是一种ORM规范!} JPA是一种ORM规范!
即帮我们找到指定的存储技术实例,并帮我们转换成其合法的SQL。
该规范为我们提供了:
- ORM映射元数据:
- JPA支持XML和注解两种元数据的形式,元数据描述对象和表之间的映射关系,框架据此将实体对象持久化到数据库表中;
- 如:
@Entity
、@Table
、@Id
与@Column
等注解。
- JPA 的API:
- 用来操作实体对象,执行CRUD操作,框架在后台替我们完成所有的事情,开发者从繁琐的JDBC和SQL代码中解脱出来。
- 如:entityManager.merge(T t);
- JPQL查询语言:
- 通过面向对象而非面向数据库的查询语言查询数据,避免程序的SQL语句紧密耦合。
- 如:from Student s where s.name = ?
这里的Student是个对象
三、Hibernate与JPA
JPA仅仅是一种规范,也就是说JPA仅仅定义了一些接口,而接口是需要实现才能工作的。
而Hibernate就是实现了JPA接口的ORM框架。
JPA是一套ORM规范,Hibernate实现了JPA规范!
扩展:
hibernate和之前学的mybatis有什么区别呢?
- mybatis:小巧、高效、简单、直接、半自动
- 半自动的ORM框架,
- 小巧: mybatis就是jdbc封装
- 在国内更流行。
- 场景: 在业务比较复杂系统进行使用
- hibernate:强大、方便、高效、(简单)复杂、绕弯子、全自动
- 全自动的ORM框架,
- 强大:根据ORM映射生成不同SQL
- 在国外更流。
- 场景: 在业务相对简单的系统进行使用,随着微服务的流行。
四、Hibernate&JPA快速搭建
-
添加相关依赖
<?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"> <parent> <artifactId>springdata</artifactId> <groupId>com.guoshao.springdata</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>01-jpa-hibernate</artifactId> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> </properties> <dependencies> <!-- junit4 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13</version> <scope>test</scope> </dependency> <!-- hibernate对jpa的支持包 --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> <version>5.4.32.Final</version> </dependency> <!-- Mysql and MariaDB --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.22</version> </dependency> <!--openjpa--> <dependency> <groupId>org.apache.openjpa</groupId> <artifactId>openjpa-all</artifactId> <version>3.2.0</version> </dependency> </dependencies> </project>
-
hibernate有一个概念就是 c o d e f i r s t \color{red}{code\ first} code first,先创建实体类,然后hibernate会帮我们创建表
-
所以,先写一个实体类:
package com.guoshao.pojo; import javax.persistence.*; @Entity // 作为hibernate 实体类 @Table(name = "tb_customer") // 映射的表明 public class Customer { /** * @Id:声明主键的配置 * @GeneratedValue:配置主键的生成策略 * strategy * GenerationType.IDENTITY :自增,mysql * * 底层数据库必须支持自动增长(底层数据库支持的自动增长方式,对id自增) * GenerationType.SEQUENCE : 序列,oracle * * 底层数据库必须支持序列 * GenerationType.TABLE : jpa提供的一种机制,通过一张数据库表的形式帮助我们完成主键自增 * GenerationType.AUTO : 由程序自动的帮助我们选择主键生成策略 * @Column:配置属性和字段的映射关系 * name:数据库表中字段的名称 */ @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id") private Long custId; //客户的主键 @Column(name = "cust_name") private String custName;//客户名称 @Column(name="cust_address") private String custAddress;//客户地址 public Long getCustId() { return custId; } public void setCustId(Long custId) { this.custId = custId; } public String getCustName() { return custName; } public void setCustName(String custName) { this.custName = custName; } public String getCustAddress() { return custAddress; } public void setCustAddress(String custAddress) { this.custAddress = custAddress; } @Override public String toString() { return "Customer{" + "custId=" + custId + ", custName='" + custName + '\'' + ", custAddress='" + custAddress + '\'' + "}\n"; } }
-
编写hibernate.cfg.xml文件
<?xml version="1.0" encoding="UTF-8"?> <!-- 此文件是 Hibernate 的配置文件,遵循 Hibernate 3.0 配置 DTD --> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <!-- 数据库连接相关配置 --> <!-- 配置 JDBC 驱动程序,这里使用 MySQL 的 JDBC 驱动 --> <property name="connection.driver_class">com.mysql.cj.jdbc.Driver</property> <!-- 数据库连接 URL,连接到本地 3306 端口的 springdata_jpa 数据库,设置字符编码为 UTF-8 --> <property name="connection.url">jdbc:mysql://localhost:3306/springdata_jpa?characterEncoding=UTF-8</property> <!-- 数据库用户名 --> <property name