1.SpringData概述
1.1.持久层开发的问题
随着互联网技术的发展,现在的企业开发中用到的用于数据存储的产品,不再仅仅是关系型数据库,而是要根据场景需要选择不同的存储技术,比如用于缓存热点数据的redis,用于存储文档数据的mongodb,用于支持强大搜索功能的elasticsearch等等。
在Java中,对于上面所说的产品都提供了优秀的访问技术。比如针对关系型数据库mybatis、jpa等技术,针对于redis的jedis技术等等..... 这些技术虽然可以很好的针对各个存储产品进行访问操作,但同时也带来了新的问题,那就是不同的持久层技术的API是不一样的。
这样一来,开发人员就必须同时掌握多种数据访问技术,这无疑增加了开发成本。那么我们会想,有没有这样一种技术,它可以使用一套API支持各个不同的存储的访问呢?就在这样的需求下,SpringData产生了。
1.2.SpringData简介
1.2.1.什么是SpringData
SpringData是一个用来简化dao层开发的框架。它在保证了各个底层存储特性的同时,提供了一套统一的数据访问API。它可以很好的支持常用的关系型数据库和非关系型数据库。
使用SpringData作为dao层开发技术,将大大简化代码量,而且其API比各个技术的原生API更加简单易用。
1.2.2.SpringData的主要模块
SpringData支持的持久层技术非常多,我们只介绍几个常见的:
- Spring Data common SpringData的核心模块,定义了SpringData的核心功能
- Spring Data JDBC 对JDBC的Spring Data存储库支持
- Spring Data JPA 对JPA的Spring Data存储库支持
- Spring Data MongoDB 对MongoDB的基于Spring对象文档的存储库支持
- Spring Data Redis 封装Jedis技术,对redis实现访问操作
- Spring Data Elasticsearch 对Elasticsearch实现访问操作
2.JPA回顾
2.1.JPA基础
JPA 的全称是 Java Persistence API,即 Java 持久化 API,是 SUN 公司推出的一套基于 ORM 的规范,注意不是 ORM 框架——因为 JPA 并未提供 ORM 实现,它只是提供了一些编程的 API 接口。
2.2.JPA实战
2.2.1.目标
本章节我们是实现的功能是搭建Jpa环境,并实现一条数据的增删改查。
目录解构:
2.2.2.准备数据库环境
--准备数据库,创建一张文章表备用
CREATE TABLE `article` (
`aid` int(11) NOT NULL auto_increment COMMENT '主键',
`author` varchar(255) default NULL COMMENT '作者',
`createTime` datetime default NULL COMMENT '创建时间',
`title` varchar(255) default NULL COMMENT '标题',
PRIMARY KEY (`aid`)
);
2.2.3.创建java工程,导入坐标
<dependencies>
<!--Jpa的支撑框架hibernate-->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-c3p0</artifactId>
<version>5.6.15.Final</version>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
<!-- 日志 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
<!-- 单元测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.28</version>
</dependency>
</dependencies>
2.2.4.创建实体类,并配置映射关系
注意引入的是:import javax.persistence.*,不是hibernate下面的
@Data
@Entity//告诉jpa这是一个实体类,需要把它跟数据库中的表做映射
@Table(name = "article") //建立实体类和表的映射关系
public class Article implements Serializable {
@Id//声明当前私有属性为主键
//指定主键生成策略,GenerationType.IDENTITY就是对应到mysq1中的数据自增策略
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer aid;
//声明类的属性跟数据表字段的对应关系,如果属性名称和字段名称一致,可省略
@Column(name = "title")
private String title;
private String author;
private Date createTime;
}
2.2.5.加入 JPA 的核心配置文件
在maven工程的resources路径下创建一个名为META-INF的文件夹,在文件夹下创建一个名为
persistence.xml的配置文件。注意: META-INF文件夹名称不能修改,persistence.xml文件名称不能改。
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<!--持久化单元
name 持久化单元的名称 唯一
transaction-type 事务类型
RESOURCE LOCAL 本地事务
JTA 分布式事务-->
<!--持久化单元-->
<persistence-unit name="springdata" transaction-type="RESOURCE_LOCAL">
<!--配置 JPA 规范的服务提供商 -->
<!--当项目中只有一个JPA的实现时,此选项可省略-->
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<!--指定实体类,此选项可省略-->
<class>com.fang.domain.Article</class>
<properties>
<!-- 数据库驱动 -->
<property name="javax.persistence.jdbc.driver"
value="com.mysql.cj.jdbc.Driver"/>
<!-- 数据库地址 -->
<property name="javax.persistence.jdbc.url"
value="jdbc:mysql://localhost:3306/springbootjpa?serverTimezone=Asia/Shanghai"/>
<!-- 数据库用户名 -->
<property name="javax.persistence.jdbc.user" value="root"/>
<!-- 数据库密码 -->
<property name="javax.persistence.jdbc.password"
value="123456"/>
<!--jpa的核心配置中兼容hibernate的配置-->
<!-- 是否显示SQL-->
<property name="hibernate.show_sql" value="true"/>
<!--是否格式化显示的SQL-->
<property name="hibernate.format_sql" value="true"/>
<!--自动建表
update 如果数据库存在数据表,就使用:不存在,就创建
create 小管数据库有没有数据表,每次SQL请求都会重新建表
-->
<property name="hibernate.hbm2ddl.auto" value="update"/>
</properties>
</persistence-unit>
</persistence>
2.2.6.测试添加
@Test
public void testSave() {
// 创建文章对象
Article article = new Article();
article.setTitle("测试文章");
article.setAuthor("黑马");
article.setCreateTime(new Date());
//1 创建持久化管理器工厂
String persistenceUnitName = "springdata";
EntityManagerFactory factory =
Persistence.createEntityManagerFactory(persistenceUnitName);
//2 创建持久化管理器(这个API是我们最重要的一个API,基于此API我们可以完成获取事务以及对数据库的cRUD操作]
EntityManager entityManager = factory.createEntityManager();
//3 获取事务,并开启
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
//4 操作
entityManager.persist(article);
//5 事务提交
transaction.commit();
//6 关闭资源
entityManager.close();
}
2.2.7.测试查询
@Test
public void testFind() {
//1 创建持久化管理器工厂
String persistenceUnitName = "springdata";
EntityManagerFactory factory =
Persistence.createEntityManagerFactory(persistenceUnitName);
//2 创建持久化管理器(这个API是我们最重要的一个API,基于此API我们可以完成获取事务以及对数据库的cRUD操作]
EntityManager entityManager = factory.createEntityManager();
//3 获取事务,并开启
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
//4 操作
Article article = entityManager.find(Article.class, 1);
System.out.println(article.toString());
//5 事务提交
transaction.commit();
//6 关闭资源
entityManager.close();
}
2.2.8.测试更新
@Test
public void testUpdate() {
EntityManagerFactory factory =
Persistence.createEntityManagerFactory("springdata");
EntityManager entityManager = factory.createEntityManager();
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
// 4 操作:JPA的修改操作,要求必须先查询,再修改
Article article = entityManager.find(Article.class, 1);
//修改
article.setAuthor("黑马程序员");
entityManager.merge(article);
transaction.commit();
entityManager.close();
}
2.2.9.测试删除
@Test
public void testDelete() {
EntityManagerFactory factory =
Persistence.createEntityManagerFactory("springdata");
EntityManager entityManager = factory.createEntityManager();
EntityTransaction transaction = entityManager.getTransaction();
transaction.begin();
// 4 操作:JPA的修改操作,要求必须先查询,再删除
Article article = entityManager.find(Article.class, 1);
//删除
entityManager.remove(article);
transaction.commit();
entityManager.close();
}
2.3.JPA的重要API介绍
- Persistence:通过读取持久化单元名称,根据配置创建持久化管理器工厂
- EntityTransaction:进行事务管理 begin commit rollback
- EntityManagerFactory:这是一个工厂类,目的是为了创建Entitymanager,是一个线程安全的对象,对于这种工厂类,它的创建和销毁是十分耗费资源的,在一共工程中一般维持一个就好(单例)
- EntityManager:这是我们最重要的一个API证,我们基于这个API可以完成数据库的CRUD操作,他是线程不安全的,需要保持线程独有。persist(T)find(Class,T)merge(class)remove(T)
3.SpringData JPA基础
3.1.SpringData JPA简介
SpringData JPA是Spring Data家族的一个成员,是Spring Data对JPA封装之后的产物,目的在于简化基于JPA的数据访问技术。使用SpringData JPA技术之后,开发者只需要声明Dao层的接口,不必再写实现类或其它代码,剩下的一切交给SpringData JPA来搞定 。
3.2.SpringData JPA快速入门
3.2.1.目标
本章节我们是实现的功能是搭建SpringData JPA环境(Spring+JPA),并实现一条数据的增删改查。
3.2.2.准备数据环境
同 2.2.2,也可让JPA自动生成表结构
3.2.3.创建java工程,导入坐标
<dependencies>
<!--Jpa的支撑框架hibernate-->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-c3p0</artifactId>
<version>5.6.15.Final</version>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
<!-- 日志 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.12</version>
</dependency>
<!-- 单元测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version&