SpringData JPA(1)

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: SpringData JPA(1)

1 持久层开发的问题

随着互联网技术的发展,现在的企业开发中用到的用于数据存储的产品,不再仅仅是关系型数据库,而是要根据场景需要选择不同的存储技术,比如用于缓存热点数据的redis,用于存储文档数据的mongodb,用于支持强大搜索功能的elasticsearch等等。

20210120111216329.png

 在Java中,对于上面所说的产品都提供了优秀的访问技术。比如针对关系型数据库的mybatis、jpa等技术,针对于redis的jedis技术等等… 这些技术虽然可以很好的针对各个存储产品进行访问操作,但同时也带来了新的问题,那就是不同的持久层技术的API是不一样的。

这样一来,开发人员就必须同时掌握多种数据访问技术,这无疑增加了开发成本。那么我们会想,有没有这样一种技术,它可以使用一套API支持各个不同的存储的访问呢?就在这样的需求下,SpringData产生了。

20210120111238551.png

1 SpringData简介

2.1 什么是SpringData

SpringData是一个用来简化dao层开发的框架。它在保证了各个底层存储特性的同时,提供了一套统一的数据访问API。它可以很好的支持常用的关系型数据库和非关系型数据库。

使用SpringData作为dao层开发技术,将大大简化代码量,而且其API比各个技术的原生API更加简单易用。

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实现访问操作

3 JPA基础

Hibernate是一个全自动的ORM框架,是对 JDBC技术的封装。它在实体类和数据库表之间建立了映射关系,使得程序员可以使用面向对象编程思维来操纵数据库,而Hibernate会自动给我们生成 SQL 语句。

JPA 的全称是 Java Persistence API,即 Java 持久化 API,是 SUN 公司推出的一套基于 ORM 的规范,注意不是 ORM 框架——因为 JPA 并未提供 ORM 实现,它只是提供了一些编程的 API 接口。

20210120111352766.png

4 JPA实战

4.1 目标

本章节我们是实现的功能是搭建Jpa环境,并实现一条数据的增删改查。

4.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`)
);

4.3 创建java工程,导入坐标

<dependencies>
    <!--Jpa的支撑框架hibernate-->
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
        <version>5.0.7.Final</version>
    </dependency>
    <!--mysql-->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.6</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>
</dependencies>

4.4 创建实体类

public class Article  implements Serializable {
    private Integer aid;
    private String title;
    private String author;
    private Date createTime;
  //省略set和get方法。。。
    //省略toString方法。。。
}    

4.5在实体类中配置映射关系

@Entity//表示这是一个实体类
@Table(name = "article") //建立实体类和表的映射关系
public class Article implements Serializable {
    @Id//声明当前私有属性为主键
    @GeneratedValue(strategy = GenerationType.IDENTITY) //配置主键的生成策略
    private Integer aid;
    //声明类的属性跟数据表字段的对应关系,如果属性名称和字段名称一致,可省略
    @Column(name = "title")
    private String title;
    private String author;
    private Date createTime;
}

4.6 加入 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">
    <!--持久化单元-->
    <persistence-unit name="springdata" transaction-type="RESOURCE_LOCAL">
        <!--配置 JPA 规范的服务提供商 -->
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
        <properties>
            <!-- 数据库驱动 -->
            <property name="javax.persistence.jdbc.driver" 
                      value="com.mysql.jdbc.Driver"/>
            <!-- 数据库地址 -->
            <property name="javax.persistence.jdbc.url"
                      value="jdbc:mysql:///springdata"/>
            <!-- 数据库用户名 -->
            <property name="javax.persistence.jdbc.user" value="root"/>
            <!-- 数据库密码 -->
            <property name="javax.persistence.jdbc.password" value="adminadmin"/>
            <!--jpa的核心配置中兼容hibernate的配置-->
            <property name="hibernate.show_sql" value="true"/>
            <property name="hibernate.format_sql" value="true"/>
            <property name="hibernate.hbm2ddl.auto" value="update"/>
        </properties>
    </persistence-unit>
</persistence>

4.7 测试

4.7.1 实现保存操作

@Test
public void testSave() {
    //1 创建持久化管理器工厂
    EntityManagerFactory factory = Persistence.createEntityManagerFactory("springdata");
    //2 创建持久化管理器
    EntityManager entityManager = factory.createEntityManager();
    //3 获取事务,并开启
    EntityTransaction transaction = entityManager.getTransaction();
    transaction.begin();
    //4 操作
    Article article = new Article();
    article.setTitle("测试文章");
    article.setAuthor("oldlu");
    article.setCreateTime(new Date());
    entityManager.persist(article);
    //5 事务提交
    transaction.commit();
    //6 关闭资源
    entityManager.close();
}

4.7.2 实现查询操作

@Test
public void testFindByAid() {
    EntityManagerFactory factory = Persistence.createEntityManagerFactory("springdata");
    EntityManager entityManager = factory.createEntityManager();
    EntityTransaction transaction = entityManager.getTransaction();
    transaction.begin();
    Article article = entityManager.find(Article.class, 1);
    System.out.println(article);
    transaction.commit();
    entityManager.close();
}

4.7.3 实现修改操作

@Test
public void testUpdate() {
    EntityManagerFactory factory = Persistence.createEntityManagerFactory("springdata");
    EntityManager entityManager = factory.createEntityManager();
    EntityTransaction transaction = entityManager.getTransaction();
    transaction.begin();
    Article article = entityManager.find(Article.class, 1);
    //修改
    article.setAuthor("oldlu程序员");
    transaction.commit();
    entityManager.close();
}

4.7.4 实现删除操作

@Test
public void testDelete() {
    EntityManagerFactory factory = Persistence.createEntityManagerFactory("springdata");
    EntityManager entityManager = factory.createEntityManager();
    EntityTransaction transaction = entityManager.getTransaction();
    transaction.begin();
    Article article = entityManager.find(Article.class, 1);
    //删除
    entityManager.remove(article);
    transaction.commit();
    entityManager.close();
}

5 JPA的重要API介绍

5.1 EntityManagerFactory

EntityManagerFactory接口主要用来创建EntityManager实例
EntityManagerFactory是一个线程安全的对象,并且其创建极其浪费资源,所以编程的时候要保持它是单例的。

5.2 EntityManager

在JPA规范中,EntityManager是操作数据库的重要API,他是线程不安全的,需要保持线程独有。
重要方法说明:
    getTransaction: 获取事务对象
    persist:保存操作
    merge:更新操作
    remove:删除操作
    find/getReference:根据id查询

5.3 save和saveAndFlush方法区别

On saveAndFlush, changes will be flushed to DB immediately in this command. With save, this is not necessarily true, and might stay just in memory, until flush or commit commands are issued.

在saveAndFlush上,此命令中的更改将立即刷新到DB。使用save,就不一定了,它可能只暂时保留在内存中,直到发出flush或commit命令。

But be aware, that even if you flush the changes in transaction and do not commit them, the changes still won’t be visible to the outside transactions until the commit in this transaction.

但是要注意的是,即使在事务中刷新了更改并且未提交它们,这些更改对于外部事务仍然不可见,直到,提交这个事务。

In your case, you probably use some sort of transactions mechanism, which issues commit command for you if everything works out fine.

在您的情况下,您可能使用某种事务机制,如果一切正常,它会为您发出commit命令。

5.3.1 总结

比如在我们得项目中,保存一条数据后,我又想立马用到这条数据得id,因为实体类是配置了uuid自动生成,所以使用saveAndFlush()方法就可以立即获取到这条数据得id。但是如果用sava()方法,你不flush()或者commit,你得数据是暂时只在内存中保存,所以此时这条数据是没有主键id的.

提交事务后数据插入进数据库,要想在事务提交之前避免缓存插入数据库需要在执行完save操作调用flush方法或者直接执行saveAndFlush方法即可

6 SpringData JPA简介

SpringData JPA是Spring Data家族的一个成员,是Spring Data对JPA封装之后的产物,目的在于简化基于JPA的数据访问技术。使用SpringData JPA技术之后,开发者只需要声明Dao层的接口,不必再写实现类或其它代码,剩下的一切交给SpringData JPA来搞定 。

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
SQL 安全 Java
SpringData JPA(2)
SpringData JPA(2)
117 1
|
12月前
|
Java
30SpringBoot整合SpringData JPA
30SpringBoot整合SpringData JPA
45 0
|
12月前
|
Java 数据库连接 mybatis
flowable项目启动项目报错:Consider defining a bean of type ‘org.mybatis.spring.SqlSessionTemplate‘ in ……
flowable项目启动项目报错:Consider defining a bean of type ‘org.mybatis.spring.SqlSessionTemplate‘ in ……
280 0
|
5月前
|
SQL Java 关系型数据库
SpringBoot整合SpringData与JPA
SpringBoot整合SpringData与JPA
58 0
|
JSON Java 数据库
SpringBoot整合SpringDataJPA
SpringBoot整合SpringDataJPA
133 0
|
SQL XML NoSQL
SpringData 基础篇
SpringData 基础篇
107 0
|
Java 数据库连接 mybatis
项目依赖问题导致No qualifying bean of type 'org.apache.ibatis.session.SqlSessionFactory' available: more tha...
项目依赖问题导致No qualifying bean of type 'org.apache.ibatis.session.SqlSessionFactory' available: more tha...
348 0
|
SQL Java 数据库
PageHelper在SpringBoot的@PostConstruct中不生效
PageHelper在SpringBoot的@PostConstruct中不生效
204 0
|
SQL Java 数据库连接
SpringData JPA(提升篇)
🍅程序员小王的博客:程序员小王的博客 🍅 欢迎点赞 👍 收藏 ⭐留言 📝 🍅 如有编辑错误联系作者,如果有比较好的文章欢迎分享给我,我会取其精华去其糟粕 🍅java自学的学习路线:java自学的学习路线
111 0
SpringData JPA(提升篇)
|
Java Maven Spring
SpringBoot中整合SpringDataJPA
SpringData:其实SpringData就是Spring提供了一个操作数据的框架。而SpringData JPA只是SpringData框架下的一个基于JPA标准操作数据的模块 SpringData JPA:基于JPA的标准数据进行操作。简化操作持久层的代码。只需要编写接口就可以
101 0