SpringData 基础篇

news2025/1/12 1:55:24

Spring Data

  • 故事背景
  • 一:基础概念
    • 1.1 什么是SpringData
    • 1.2 为什么要用SpringData
  • 二:JPA与Hibernate、MyBatis关系
    • 2.1 JPA与JDBC
      • 2.1.1 特点
      • 2.1.2 JPA规范提供
      • 2.1.3 JDBC的不足
    • 2.2 Hibernate与JPA
      • 2.2.1 关系
    • 2.3 mybatis 和Hibernate
  • 三:Hibernate与JPA快速搭建
    • 3.1 新建一个Maven项目并引入对应Pom依赖
    • 3.2 hibernate具体配置
    • 3.3. 具体使用Hibernate实现操作
      • 3.3.1 项目结构
      • 3.3.2 User类
      • 3.3.3 HibernateTest 实现
    • 3.4 JPA具体配置
    • 3.5 具体使用JPA进行实现
      • 3.5.1 添加配置文件
      • 3.5.2 测试类
  • 四:JPA中对象的四种状态
    • 4.1 jpa的对象4种状态
    • 4.2 persist方法
    • 4.3 merge方法
    • 4.4 refresh方法
    • 4.5 remove方法
  • 五:总结&提升

故事背景

最近学习SpringData,系统的总结一下SpringData的相关知识,此篇为算是一篇前言,主要介绍一下SpringData,先讲一个JPA和Hibernate,讲一讲他们的关系,并且给出对应的示例,希望大家可以通过这个示例,了解到这些概念以及其基本的用法。

一:基础概念

1.1 什么是SpringData

Spring Data是Spring Framework的一个子项目,它提供了一种简化数据访问层的方式。它的目标是提供一种统一的、易于使用的编程模型,用于与不同类型的数据存储进行交互,包括关系型数据库、NoSQL数据库、图数据库等。
在这里插入图片描述

1.2 为什么要用SpringData

  1. 其统一和简化了对不同数据库类型的持久化。通过使用SpringData我们可以简化开发,提升开发效率。
  2. springData是一个伞型项目,有多个子项目,不同的子项目针对不同的数据库的实现。

二:JPA与Hibernate、MyBatis关系

2.1 JPA与JDBC

2.1.1 特点

  1. 二者都是与数据库交互的规范。数据库实现了JDBC的规范。ORM(Object、Relational、mapping)框架实现了JPA的规范。
  2. JDBC通过sql语句与数据库通信。JPA用面向对象的方式,通过ORM生成SQL,进行操作。
  3. JPA 是需要 JDBC的,是依赖于JDBC的。

2.1.2 JPA规范提供

  1. ORM映射元数据,注解和xml两种方式
  2. JPA的API,用来操作对象,执行对应的CRUD的操作,让开发者从JDBC和SQL代码中解脱出来
  3. JPQL查询语言,通过面向对象的方式,面向数据库查询

2.1.3 JDBC的不足

  1. 学习成本高
  2. 修改不同数据库时,不容易移植
  3. JAVA对象和数据库的映射比较麻烦

2.2 Hibernate与JPA

2.2.1 关系

  1. Hibernate实现了JPA规范。是JPA的一种实现。

2.3 mybatis 和Hibernate

  1. MyBatis是一个半自动的ORM框架,需要自己写sql。而Hibernate是全自动的ORM框架
  2. MyBatis更加小巧,是对JDBC的封装。Hibernate根据ORM直接生成不同的SQL
  3. MyBatis在国内比较流行,关系比较复杂。Hibernate在国外更加流行,Hibernate不是很适合复杂的关系

三:Hibernate与JPA快速搭建

3.1 新建一个Maven项目并引入对应Pom依赖

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>5.4.32.Final</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.13</version>
        </dependency>

3.2 hibernate具体配置

需要在我们的Resource目录下,添加对应的配置,这里先添加Hibernate对应的配置

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>

        <!-- 数据库连接配置 -->
        <property name="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/jpa</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.password">root666</property>
        <property name="hibernate.connection.characterEncoding">UTF-8</property>
        <property name="hibernate.connection.useUnicode">true</property>
        
        <!--        日志中记录sql-->
        <property name="show_sql">true</property>
        <!--        格式化sql-->
        <property name="format_sql">true</property>
        <!--        表的生成策略,自动生成-->
        <property name="hbm2ddl.auto">update</property>

        <!-- 数据库方言,注意版本 -->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQL57Dialect</property>

        <!-- 映射文件位置 -->
        <mapping class="org.example.entity.User"/>

    </session-factory>
</hibernate-configuration>

此配置文件主要是配置我们对应的数据库,以及一些对应的主要功能的配置,我将重要配置都加上了注释。

3.3. 具体使用Hibernate实现操作

3.3.1 项目结构

首先宏观看一下项目结构,这样有利于下面的讲解:
在这里插入图片描述

3.3.2 User类

User类是一个实体类,对应数据库表

@Entity
@Table(name = "user")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private long id;

    private String userName;

    private String email;
	//get与set 略 

}
这里主要是几个注解来进行标识:

  1. @Entity注解
    表示我们的User类是一个实体类,其应该在数据库内对应一张表
  2. @Table注解
    通过Table注解可以指定对应的表的名称
  3. @Id注解
    每个实体类必须要有一个主键Id,对应数据库表的主键,Id有多种生成策略
  4. @GeneratedValue注解
    指定主键的生成策略,这里使用的是自增的形式

3.3.3 HibernateTest 实现

public class HibernateTest {

    //Session工厂 代码持久化到数据库的一个桥梁
    private SessionFactory sf;

    @Before
    public void  init() {

        StandardServiceRegistry registry = new StandardServiceRegistryBuilder().configure("/hibernate.cfg.xml").build();

        sf = new MetadataSources(registry).buildMetadata().buildSessionFactory();
    }

    @Test
    public void test(){
        //session 进行持久化操作
        try(Session session = sf.openSession()){

            Transaction tx = session.beginTransaction();

            User user = new User();
            user.setUserName("郝立琢");
            user.setEmail("123456@163.com");

            session.save(user);

            tx.commit();

        }

    }

    @Test
    public void test1(){
        try(Session session = sf.openSession()){

            Transaction tx = session.beginTransaction();

            User user = session.find(User.class,1L);
            tx.commit();

            System.out.println(user.getUserName());

        }
    }

通过Session会话实现数据库的插入和查询两种操作。

3.4 JPA具体配置

3.5 具体使用JPA进行实现

3.5.1 添加配置文件

首先在Resource下新增一个名为 MEAT-INF的文件夹,然后再其内部增添一个名为persistence的xml文件

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0">
    <!-- 需要配置persistence-unit节点
    持久化单元:
    name:持久化单元名称
    transaction-type:事务管理的方式
    JTA:分布式事务管理
    RESOURCE_LOCAL:本地事务管理 -->
    <persistence-unit name="hibernateJPA" transaction-type="RESOURCE_LOCAL">
        <!-- jpa的实现方式 -->
        <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>

        <class>org.example.entity.User</class>


        <!-- 可选配置:配置jpa实现方的配置信息 -->
        <properties>
            <!-- 数据库信息
            用户名,javax.persistence.jdbc.user
            密码,javax.persistence.jdbc.password
            驱动,javax.persistence.jdbc.driver
            数据库地址,javax.persistence.jdbc.url -->
            <property name="javax.persistence.jdbc.user" value="root"/>
            <property name="javax.persistence.jdbc.password" value="root666"/>
            <property name="javax.persistence.jdbc.driver" value="com.mysql.cj.jdbc.Driver"/>
            <property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/jpa?serverTimezone=UTC"/>

            <!-- 配置jpa实现方(hibernate)的配置信息
            显示sql:false|true
            自动创建数据库表:hibernate.hbm2ddl.auto
            create:程序运行时创建数据库表(如果有表,先删除表再创建)
            update:程序运行时创建表(如果有表,不会创建表)
            none:不会创建表 -->
            <property name="hibernate.show_sql" value="true"/>
            <property name="hibernate.hbm2ddl.auto" value="update"/>
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect"/>
        </properties>
    </persistence-unit>
</persistence>

此处为JPA对应的配置,主要定义了持久化单元、指定了JPA实现的提供者、配置实体类、配置了相关属性。

3.5.2 测试类

public class JpaTest {

        //EntityManagerFactory类型的属性,用于创建EntityManager对象。
    private EntityManagerFactory factory;

    //是EntityManager类型的属性,用于执行JPA操作,包括实体的持久化、更新、查询等。
    EntityManager em;


    @Before
    public void inti(){
        //加载配置文件
        factory = Persistence.createEntityManagerFactory("hibernateJPA");
        //获取EntityManager对象
        em = factory.createEntityManager();
    }

    /**
     * 查询全部
     * jqpl:from cn.itcast.domain.Customer
     * sql:SELECT * FROM cst_customer
     */
    @Test
    public void testR_HQL() {
        //2.开启事务
        EntityTransaction tx = em.getTransaction();
        tx.begin();
        //3.查询全部
        String jpql = "select c from User c";
        Query query = em.createQuery(jpql);//创建Query查询对象,query对象才是执行jqpl的对象

        //发送查询,并封装结果集
        List list = query.getResultList();

        for (Object obj : list) {
            User user = (User)obj;
            System.out.print(user.getUserName());
        }

        //4.提交事务
        tx.commit();
        //5.释放资源
        em.close();
    }

    @Test
    public void testR() {
        //2.开启事务
        EntityTransaction tx = em.getTransaction();
        tx.begin();

        User user = em.getReference(User.class, 1L);
        System.out.println("===========================");
        System.out.println(user);
        //4.提交事务
        tx.commit();
        //5.释放资源
        em.close();
    }
}

使用JPA的规范进行的调用,我们可以更好的移植其他对JPA的实现。

四:JPA中对象的四种状态

4.1 jpa的对象4种状态

  • 临时状态:刚创建出来,∙没有与entityManager发生关系,没有被持久化,不处于entityManager中的对象
  • 持久状态:∙与entityManager发生关系,已经被持久化,您可以把持久化状态当做实实在在的数据库记录。
  • 删除状态:执行remove方法,事物提交之前
  • 游离状态:游离状态就是提交到数据库后,事务commit后实体的状态,因为事务已经提交了,此时实体的属
    性任你如何改变,也不会同步到数据库,因为游离是没人管的孩子,不在持久化上下文中。

4.2 persist方法

public void persist(Object entity)
persist方法可以将实例转换为managed(托管)状态。在调用flush()方法或提交事物后,实
例将会被插入到数据库中。
对不同状态下的实例A,persist会产生以下操作:

  1. 如果A是一个new状态的实体,它将会转为managed状态;
  2. 如果A是一个managed状态的实体,它的状态不会发生任何改变。但是系统仍会在数据库执行INSERT操作;
  3. 如果A是一个removed(删除)状态的实体,它将会转换为受控状态;
  4. 如果A是一个detached(分离)状态的实体,该方法会抛出IllegalArgumentException异常,具体异常根据不同的
    JPA实现有关。

4.3 merge方法

public void merge(Object entity)
merge方法的主要作用是将用户对一个detached状态实体的修改进行归档,归档后将产生
一个新的managed状态对象。
对不同状态下的实例A,merge会产生以下操作:

  1. 如果A是一个detached状态的实体,该方法会将A的修改提交到数据库,并返回一个新的managed状态的实例A2;
  2. 如果A是一个new状态的实体,该方法会产生一个根据A产生的managed状态实体A2;
  3. 如果A是一个managed状态的实体,它的状态不会发生任何改变。但是系统仍会在数据库执行UPDATE操作;
  4. 如果A是一个removed状态的实体,该方法会抛出IllegalArgumentException异常。

4.4 refresh方法

public void refresh(Object entity)
refresh方法可以保证当前的实例与数据库中的实例的内容一致。
对不同状态下的实例A,refresh会产生以下操作:

  1. 如果A是一个new状态的实例,不会发生任何操作,但有可能会抛出异常,具体情况根据不同JPA实现有关;
  2. 如果A是一个managed状态的实例,它的属性将会和数据库中的数据同步;
  3. 如果A是一个removed状态的实例,该方法将会抛出异常: Entity not managed
  4. 如果A是一个detached状态的实体,该方法将会抛出异常。

4.5 remove方法

public void remove(Object entity)
remove方法可以将实体转换为removed状态,并且在调用flush()方法或提交事物后删除数据库中的数据。
对不同状态下的实例A,remove会产生以下操作:

  1. 如果A是一个new状态的实例,A的状态不会发生任何改变,但系统仍会在数据库中执行DELETE语句;
  2. 如果A是一个managed状态的实例,它的状态会转换为removed;
  3. 如果A是一个removed状态的实例,不会发生任何操作;
  4. 如果A是一个detached状态的实体,该方法将会抛出异常

五:总结&提升

本文主要讲解了SpringData的基本概念,以及什么是JPA,JPA与我们熟知的Hibernate、MyBatis之间的关系。并且给出了Hibernate和JPA的具体示例代码,通过此文,我们可以了解到什么是JPA,了解JPA规范的作用,为我们接下来深入学习SpringData打下基础。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/602064.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

裁剪与复原

目录 模型假设 模型建立 模型求解 通过建立匹配模型实现对破碎文件的拼接复原。 模型假设 模型建立 首先对每个图片按像素值进行二值化量化&#xff0c;可以得到19个1980*72的矩阵&#xff0c;再提取每个举证最左和最右的像素值采用绝对距离法建立像素匹配模型。 二值化是图…

大数据时代——生活、工作与思维的重大变革

最近读了维克托迈尔 – 舍恩伯格的《大数据时代》&#xff0c;觉得有不少收获&#xff0c;让我这个大数据的小白第一次理解了大数据。 作者是大数据的元老级先驱。 放一张帅照&#xff0c;膜拜下。 不过这本书我本人不推荐从头读一遍&#xff0c;因为书中的核心理念并不是特…

Django实现接口自动化平台(二)认证授权登录【持续更新中】

上一章&#xff1a; Django实现接口自动化平台&#xff08;一&#xff09;日志功能【持续更新中】_做测试的喵酱的博客-CSDN博客 下一章&#xff1a; Django实现接口自动化平台&#xff08;三&#xff09;实现注册功能【持续更新中】_做测试的喵酱的博客-CSDN博客 一、认证与…

FineBI6.0基础学习第二课 集团毛利率下滑的原因

【案例背景】 在本期分析案例中,您将扮演一个大型商品零售集团的数据分析师,应对经理交给你的任务——发现集团毛利率下滑的原因,并给出建议; 随着您一步一步的探索分析,您将通过对商品和订单的相关历史数据的分析,逐步找出影响毛利率的关键要素,并给出相应的分析结论,…

静态误差分析

分类 随机误差、系统误差、粗大误差。 随机误差&#xff1a; 大部分随机误差满足正态分布&#xff0c;具有对称性、单峰性、有界性、抵偿性。 对称性&#xff1a;绝对值相等的正负误差出现的次数相等。 单峰性&#xff1a;绝对值越小的误差出现次数越多。 有界性&#xff1…

GIS在地质灾害危险性评估与灾后重建中的实践

第一章 基本概念与平台介绍 1、基本概念 地质灾害类型 地质灾害发育特征与分布规律 地质灾害危害特征 地质灾害孕灾地质条件分析 地质灾害诱发因素与形成机理 ​ 2、GIS原理与ArcGIS平台介绍 GIS简介 ArcGIS基础 空间数据采集与组织 空间参考 空间数据的转换与处理 …

ReID专栏(三) 注意力的应用

前言 本文中提出了一种用于行人重识别的注意感知特征学习方法。该方法由一个部分注意分支&#xff08;PAB&#xff09;和一个整体注意分支&#xff08;HAB&#xff09;组成&#xff0c;并与基础再识别特征提取器进行了联合优化。由于这两个分支建立在主干网络上&#xff0c;因此…

NumPy 数值计算基础

NumPy 数值计算基础 Numpy简介Numpy创建数组对象第一种:利用array函数创建ndarray数组第二种:利用arange函数:创建等差一维数组第三种:利用linspace函数:创建等差一维数组&#xff0c;接收元素数量作为参数。第三种:利用linspace函数:创建等差━维数组&#xff0c;接收元素数量…

剑指 Offer 18. 删除链表的节点解题思路

文章目录 题目解题思路 题目 给定单向链表的头指针和一个要删除的节点的值&#xff0c;定义一个函数删除该节点。 返回删除后的链表的头节点。 注意&#xff1a;此题对比原题有改动 示例 1: 输入: head [4,5,1,9], val 5 输出: [4,1,9] 解释: 给定你链表中值为 5 的第二…

Windows程序设计 学习笔记 第九章 子窗口控件

目录&#xff1a; 文章目录 一&#xff0c;按钮类1.创建子窗口拓展1——获取对话框字符尺寸的方法拓展2——获取实例句柄的方法2.子窗口传递消息给父窗口3.父窗口传递信息给子窗口拓展3 窗口句柄与ID 的相互获取① 已知窗口句柄 获取 ID②已知子窗口ID 获取 子窗口句柄 4. 按钮…

仙境传说RO怎样创建一个NPC rAthena脚本语言的hello word

仙境传说RO怎样创建一个NPC rAthena脚本语言的hello word 大家好&#xff0c;我是艾西。上一篇文章中我们有教大家怎么编译仙境传说RO服务端和客户端&#xff0c;当我们自己可以搭建架设游戏时&#xff0c;那么这个游戏在某种意义上就是我们说的算了。比如增加一些特色功能等&…

数据隐私为先:EMQX Cloud BYOC 架构解析

随着物联网的飞速发展&#xff0c;保护数据隐私和安全变得愈发重要。构建一个安全、可靠、可扩展的物联网基础设施成为企业的首要任务。 EMQ 近期推出了 EMQX Cloud BYOC&#xff0c;采用了以数据隐私为先的架构&#xff0c;为解决这些问题提供了一个理想的方案。用户可以在自…

JavaEE-Servlet的使用

目录 显示 HttpServletRequest 的常用属性获取GET请求中的query string 的内容获取 POST 请求中 body 的内容实现自动刷新构造重定向页面 显示 HttpServletRequest 的常用属性 能够返回一个页面, 显示以下内容: URL方法版本号query stringcontext path所有的 header import …

Shell脚本攻略:通配符、正则表达式

目录 一、理论 1.通配符 2.正则表达式 二、实验 1.通配符 2.正则表达式 一、理论 1.通配符 &#xff08;1&#xff09;概念 通配符只用于匹配文件名、目录名等&#xff0c;不能用于匹配文件内容&#xff0c;而且是已存在的文件或者目录。 各个版本的shell都有通配符&…

MySQL遇到的问题

注意&#xff1a;当前遇到问题都是MySQL5.7.33版本和Windows10的系统&#xff0c;MySQL服务的名称是MySQL57&#xff0c;以下出现的MySQL57只是我的MySQL服务名称&#xff0c;要根据自己的MySQL服务的名称来 可以通过“服务”&#xff0c;找到自己的MySQL服务名称&#xff0c;…

SpringBoot测试——高级配置

个人简介&#xff1a;Java领域新星创作者&#xff1b;阿里云技术博主、星级博主、专家博主&#xff1b;正在Java学习的路上摸爬滚打&#xff0c;记录学习的过程~ 个人主页&#xff1a;.29.的博客 学习社区&#xff1a;进去逛一逛~ SpringBoot测试——高级配置 一、SpringBoot加…

电容器基础原理知识

电容器基础知识 电容器是一种储能元件&#xff0c;在电路中用于调谐、滤波、耦合、旁路、能量转换和延时。电容器通常叫做电容。按其结构可分为固定电容器、半可变电容器、可变电容器三种。 常用电容的结构和特点 常用的电容器按其介质材料可分为电解电容器、云母电容器、瓷介…

什么是RabbitMQ?

RabbitMQ是一个由erlang开发的消息队列。消息队列用于应用间的异步协作。 2.RabbitMQ的组件 Message&#xff1a;由消息头和消息体组成。消息体是不透明的&#xff0c;而消息头则由一系列的可选属性组成&#xff0c;这些属性包括routing-key、priority、delivery-mode&#xff…

ChatGPT与软件架构(2) - 基于Obsidian和GPT实现解决方案架构自动化

磨刀不误砍柴工&#xff0c;良好的工具可以有效提高效率。本文介绍基于Obsidian和GPT打造架构知识库的思路&#xff0c;为架构师提供整理、分享、原文: Solution Architecture Automation With Obsidian and GPT Stas Parechyn Unsplash 本文介绍的ArchVault是一个旨在帮助架构…

【100个 Unity实用技能】 | Unity 的 LOD技术(多细节层次)

&#x1f3ac; 博客主页&#xff1a;https://xiaoy.blog.csdn.net &#x1f3a5; 本文由 呆呆敲代码的小Y 原创&#xff0c;首发于 CSDN&#x1f649; &#x1f384; 学习专栏推荐&#xff1a;Unity系统学习专栏 &#x1f332; 游戏制作专栏推荐&#xff1a;游戏制作 &…