一篇文章理清Java持久化脉络(关于JDBC、JPA、Hibernate、Spring Data JPA)
Java持久化
- 一、JDBC、JPA、Spring Data JPA 的定义及关系
- 二、JDBC(古老的东西,只需简单知道是啥)
- 1.1 JDBC概念
- 1.2 JDBC示例
- 三、JPA(第二代持久化,代表是Hibernate等框架)
- 3.1 JPA概念
- 3.2 JPA示例
- 四、Spring Data JPA(第三代,只需学习这个的使用)
- 五、总结
JDBC、JPA、Hibernate、Spring Data JPA,这个经常听到的词汇,具体是什么,他们是什么关系,以及如何通过他们实现java的持久化,一文带你理清Java持久化的脉络。
一、JDBC、JPA、Spring Data JPA 的定义及关系
JDBC,是一组Java接口,是Java提供的面向关系的持久化规范。各个数据库厂商(Oracle、MySQL等)提供实现,JDBC是面向SQL的,就是在代码力去执行SQL语句。
JPA,也是一组接口,是Java提供的面向对象的持久化规范。各个ORM(也就是Hibernate,MyBatis等)提供实现,JPA是面向对象的,也就是我们熟知的,定义一个实体,然后就可以和关系型数据库进行交互。
Spring Data JPA,ORM的又一层抽象,可以通过方法名约定进一步简化样板代码,底层是通过调用Hibernate等ORM实现的。Spring Data JPA默认是通过调用Hibernate实现的。
二、JDBC(古老的东西,只需简单知道是啥)
1.1 JDBC概念
JDBC是一组java api,只是接口没有实现,各数据库厂商提供实现。开发只需要面向jdbc api即可。
要使用不同的数据库,只需要切换不同的实现类即可。也就是使用不同的驱动包。
jdbc就是建立在sql之上的,sql能干的,它都能干,例如DDL、DML、DQL等,能更好的对数据进行调优,允许使用数据的所有特性,而这是其他框架不鼓励甚至禁止的。
1.2 JDBC示例
不用管具体代码含义,只大概看看,简单一条查询,都干了什么。创建数据库连接–先写SQL语句–关闭连接处理异常等。每一个操作都需要这样执行一遍。
Musician georgeHarrison = new Musician(0, "George Harrison");<br><br> // 建立数据库连接等String myDriver = "org.gjt.mm.mysql.Driver";
String myUrl = "jdbc:mysql://localhost/test";
Class.forName(myDriver);
Connection conn = DriverManager.getConnection(myUrl, "root", "");
// 纯SQL语句
String query = " insert into users (id, name) values (?, ?)";
PreparedStatement preparedStmt = conn.prepareStatement(query);
preparedStmt.setInt (1, 0);
preparedStmt.setString (2, "George Harrison");
preparedStmt.setString (2, "Rubble");
preparedStmt.execute();<br><br>// 必须手动关闭连接
conn.close();
// 还有一些异常处理
每一个查询、操作,即使只查询一条数据,也需要写这一堆代码,极其繁琐。因此催生了JPA的诞生。
三、JPA(第二代持久化,代表是Hibernate等框架)
3.1 JPA概念
JPA是面向对象的持久化规范。不用像JPA一样手动创建连接,编写SQL等,只需要创建与表对应的实体,并给实体打上相应的标记,JPA的实现框架就能自动生成SQL,进行持久化相关操作。
不过它的底层也是通过JDBC实现的。

JPA与HIbernate的关系?
题外话,现在我们都知道Hibernate是JPA的实现,但是追随历史,这是一个先有鸡还是先有蛋的问题。
Hibernate是2002年发布的,而JPA是2006年发布的,所以JPA的很多规范其实是参考了Hibernate,JPA发布后,Hibernate 3.0又根据JPA规范进行调整,最终被认证为JPA的实现之一。由此可见Hibernate 的江湖地位。
3.2 JPA示例
- ORM简单示例
简单演示一下使用Hibernate等这种ORM后,保存数据只需要定义一个Entity,然后保存即可。
// 定义实体,标记上相应的注解
@Entity
public class Musician {@Idprivate Long id;
}Musician georgeHarrison = new Musician(0, "George Harrison");
// 直接一行皆可,不需要处理数据库连接,不需要写一堆SQL
musicianManager.save(georgeHarrison);
- Spring继承Hibernate的详细配置
业务操作很简单,下面演示一下spring怎样继承Hibernate。
实现ORM,需要配置三个东西:数据源DataSource、SessionFactory、事务。
通过xml配置:
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><!-- 数据源配置 --><bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"><property name="driverClassName" value="com.mysql.cj.jdbc.Driver" /><property name="url" value="jdbc:mysql://localhost:3306/yourdb" /><property name="username" value="username" /><property name="password" value="password" /></bean><!-- Hibernate SessionFactory 配置 --><bean id="sessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean"><property name="dataSource" ref="dataSource" /><property name="packagesToScan" value="com.yourpackage.model" /><property name="hibernateProperties"><props><prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop><prop key="hibernate.show_sql">true</prop><prop key="hibernate.hbm2ddl.auto">update</prop></props></property></bean><!-- 事务管理器 --><bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager"><property name="sessionFactory" ref="sessionFactory" /></bean></beans>
通过代码配置:
@Configuration
@EnableTransactionManagement
public class HibernateConfig {@Beanpublic DataSource dataSource() {DriverManagerDataSource dataSource = new DriverManagerDataSource();dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");dataSource.setUrl("jdbc:mysql://localhost:3306/yourdb");dataSource.setUsername("username");dataSource.setPassword("password");return dataSource;}@Beanpublic LocalSessionFactoryBean sessionFactory() {LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();sessionFactory.setDataSource(dataSource());sessionFactory.setPackagesToScan("com.yourpackage.model");sessionFactory.setHibernateProperties(hibernateProperties());return sessionFactory;}private Properties hibernateProperties() {Properties properties = new Properties();properties.put("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");properties.put("hibernate.show_sql", "true");properties.put("hibernate.hbm2ddl.auto", "update");return properties;}@Beanpublic HibernateTransactionManager transactionManager(SessionFactory sessionFactory) {HibernateTransactionManager txManager = new HibernateTransactionManager();txManager.setSessionFactory(sessionFactory);return txManager;}
}
Hibernate 有一个称为上下文会话的功能,其中 Hibernate 本身管理Session每个事务的一个当前会话。一般会通过为每一个实体再创建一个Dao类来调用SessionFactory。
public class ProductDaoImpl implements ProductDao {private SessionFactory sessionFactory;public void setSessionFactory(SessionFactory sessionFactory) {this.sessionFactory = sessionFactory;}public Collection loadProductsByCategory(String category) {return this.sessionFactory.getCurrentSession().createQuery("from test.Product product where product.category=?").setParameter(0, category).list();}
}
四、Spring Data JPA(第三代,只需学习这个的使用)
JPA构建在JDBC之上,帮我们省略了数据库连接的管理、sql编写等繁琐的样板代码。而Spring Data JPA是构建在JPA之上的,能够进一步减少样板代码的编写,让我们尽量只关注业务逻辑。
看上面的Hibernate,Dao层其实也有许多样板代码,通过使用SessionFactory 来执行查询和操作等,而这在spring data jpa中进一步做了简化。其中包括:
1、简化配置
一般通过spring boot使用spring data jpa,其中配置项只有这些。
spring:datasource:url: jdbc:mysql://localhost:3306/yourdbusername: usernamepassword: passworddriver-class-name: com.mysql.cj.jdbc.Driverjpa:hibernate:ddl-auto: updateshow-sql: trueproperties:hibernate:dialect: org.hibernate.dialect.MySQLDialect
可以发现少了事务的配置,这是因为默认使用spring data 的JpaTransactionManager,它可以满足大部分需求,无需再单独配置。
2、Repository 模式极大精简传统Dao层操作
其中包括,直接写接口声明方法,就可以实现数据库访问;自动化CEUD操作,findById(), save(), delete()这些无需手动编写;支持通过方法名称自动生成查询(如 findByLastName(String lastName))。还包括分页排序、自动创建表等。
Spring Data 进一步简化了这一过程,并可以完全删除 DAO 实现。DAO 的接口现在是我们唯一需要明确定义的工件。
传统的Dao层,可以直接使用以下接口实现。
public interface IFooRepository extends JpaRepository<Foo, Long> {Foo findByName(String name);
@Query("SELECT f FROM Foo f WHERE LOWER(f.name) = LOWER(:name)")@Query("SELECT f FROM Foo f WHERE LOWER(f.name) = LOWER(:name)")Foo retrieveByName(@Param("name")String name);
}
五、总结
java的持久化也是经历了从自行车到汽车的转变,从JDBC直接调用sql,到jpa封装jdbc,使用面向对象的思想处理持久化,再到spring data jpa进一步对jpa进行抽象,目前的学习成本和编码成本已经很低了,只需要学习spring data jpa即可。
了解这些发现,有助于我们理解底层实现,
相关文章:
一篇文章理清Java持久化脉络(关于JDBC、JPA、Hibernate、Spring Data JPA)
Java持久化 一、JDBC、JPA、Spring Data JPA 的定义及关系二、JDBC(古老的东西,只需简单知道是啥)1.1 JDBC概念1.2 JDBC示例 三、JPA(第二代持久化,代表是Hibernate等框架)3.1 JPA概念3.2 JPA示例 四、Spri…...
【数学分析笔记】第2章第1节实数系的连续性(1)
2. 数列极限 2.1 实数系的连续性 人类对数系认识的历史: 人类最早对数系的认识是自然数集合 N \mathbb{N} N,自然数系对加法和乘法是封闭的(这里的封闭是指:若 m ∈ N , n ∈ N ⇒ m n ∈ N , m n ∈ N m\in\mathbb{N},n\in\ma…...
Speech Synthesis (LASC11062)
大纲 Module 1 – introductionModule 2 - unit selectionModule 3 - unit selection target cost functionsModule 4 - the databaseModule 5 - evaluationModule 6 - speech signal analysis & modellingModule 7 - Statistical Parametric Speech Synthesis (SPSS)Modu…...
拟合与插值|线性最小二乘拟合|非线性最小二乘拟合|一维插值|二维插值
挖掘数据背后的规律是数学建模的重要任务,拟合与插值是常用的分析方法 掌握拟合与插值的基本概念和方法熟悉Matlab相关程序实现能够从数据中挖掘数学规律 拟合问题的基本提法 拟合问题的概念 已知一组数据(以二维为例),即平面上n个点 ( x i , y i ) …...
《python语言程序设计》2018版第7章第05题几何:正n边形,一个正n边形的边都有同样的长度。角度同样 设计RegularPolygon类
结果和代码 这里只涉及一个办法 方法部分 def main():rX, rY eval(input("Enter regular polygon x and y axis:"))regular_num eval(input("Enter regular number: "))side_long eval(input("Enter side number: "))a exCode07.RegularPol…...
使用Virtio Driver实现一个计算阶乘的小程序——QEMU平台
目录 一、概述 二、代码部分 1、Virtio 前端 (1) User Space (2) Kernel Space 2、Virtio 后端 三、运行 QEMU Version:qemu-7.2.0 Linux Version:linux-5.4.239 一、概述 本篇文章的主要内容是使用Virtio前后端数据传输的机制实现一个计算阶乘的…...
【PyCharm】配置“清华镜像”地址
文章目录 前言一、清华镜像是什么?二、pip是什么?三、具体步骤1.复制镜像地址2.打开PyCharm,然后点击下图红框的选项3.在弹出的新窗口点击下图红框的选项进行添加4.在URL输入框中粘贴第一步复制的地址,名字可以不更改,…...
IO器件性能评估
整体逻辑:需要先了解到读写速率的差异,在明确使用场景。比如应用启动过程中的IO主要是属于随机读的io 评估逻辑: UFS 与 eMMC主要差别在io读写能力: 1,对比UFS、eMMC的规格书标注的io读写能力 ufs spec : sequentia…...
在js中判断对象是空对象的几种方法
使用 Object.keys() 方法 Object.keys() 方法返回对象自身的可枚举属性名称组成的数组。如果数组的长度为 0,那么对象是空的。 function isEmptyObject(obj) {return Object.keys(obj).length 0 && obj.constructor Object; }const obj1 {}; const obj2…...
【整理】后端接口设计和优化相关思路汇总
文章目录 明确的接口定义和文档化使用RESTful设计规范分页和过滤合理使用缓存限流与熔断机制安全性设计异步处理与后台任务接口参数校验(入参和出参)接口扩展性考虑核心接口,线程池隔离关键接口,日志打印接口功能单一性原则接口查…...
docker 部署 sql server
众所周知,sql server不好装,本人之前装了两次,这个数据库简直是恶心。 突然想到,用docker容器吧 果然可以 记得放开1433端口 还有 记得docker加速,不然拉不到镜像的最后工具还是要装的,这个就自己研究吧。 …...
微信云开发云存储 下载全部文件
一、安装 首先按照这个按照好依赖,打开cmd 安装 | 云开发 CloudBase - 一站式后端云服务 npm i -g cloudbase/cli 安装可能遇到的问题 ‘tcb‘ 不是内部或外部命令,也不是可运行的程序或批处理文件。-CSDN博客 二、登录 在cmd输入 tcb login 三、…...
1、巡线功能实现(7路数字循迹)
一、小车运行 1.PWM初始化函数 (pwm.c中编写) 包括四个轮子PWM通道使用的GPIO接口初始化、定时器初始化、PWM通道初始化。 void PWM_Init(uint16_t arr,uint16_t psc); 2.PWM占空比设置函数 (pwm.c中编写) 此函数调用了四个通道设置占空比的函数,作用是方便修改四…...
来了...腾讯内推的软件测试面试PDF 文档(共107页)
不多说,直接上干货(展示部分以腾讯面试纲要为例)完整版文末领取 通过大数据总结发现,其实软件测试岗的面试都是差不多的。常问的有下面这几块知识点: 全网首发-涵盖16个技术栈 第一部分,测试理论&#x…...
Android大脑--systemserver进程
用心坚持输出易读、有趣、有深度、高质量、体系化的技术文章,技术文章也可以有温度。 本文摘要 系统native进程的文章就先告一段落了,从这篇文章开始写Java层的文章,本文同样延续自述的方式来介绍systemserver进程,通过本文您将…...
python项目部署:Nginx和UWSGI认识
Nginx: HTTP服务器,反向代理,静态资源转发,负载均衡,SSL终端,缓存,高并发处理。 UWSGI: Python应用程序服务器,WSGI兼容,多进程管理,快速应用部署,多种协议支…...
【区块链+金融服务】农业大宗供应链线上融资平台 | FISCO BCOS应用案例
释放数据要素价值,FISCO BCOS 2024 应用案例征集 粮食贸易受季节性影响显著。每年的粮收季节,粮食收储企业会根据下游订单需求,从上游粮食贸易商或粮农手 里大量采购粮食,并分批销售给下游粮食加工企业(面粉厂、饲料厂…...
2025ICASSP Author Guidelines
Part I: General Information Procedure ICASSP 2025 论文提交与评审过程将与往届会议类似: 有意参加会议的作者需提交一份完整描述其创意和相关研究成果的文件,技术内容(包括图表和可能的参考文献)最多为4页&…...
Openstack 所需要的共享服务组件及核心组件
openstack 共享服务组件: 数据库服务(Database service):MariaDB及MongoDB 消息传输服务(messages queues):RabbitMQ 缓存(cache):Memcache 时间同步(time sync)&…...
解密Linux中的通用块层:加速存储系统,提升系统性能
通用块层 通用块层是Linux中的一个重要组件,用于管理不同块设备的统一接口,减少不同块设备的差异带来的影响。它位于文件系统和磁盘驱动之间,类似于Java中的适配器模式,让我们无需关注底层实现,只需提供固定接口即可。…...
MPNet:旋转机械轻量化故障诊断模型详解python代码复现
目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...
19c补丁后oracle属主变化,导致不能识别磁盘组
补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...
2025年能源电力系统与流体力学国际会议 (EPSFD 2025)
2025年能源电力系统与流体力学国际会议(EPSFD 2025)将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会,EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...
基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容
基于 UniApp + WebSocket实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...
对WWDC 2025 Keynote 内容的预测
借助我们以往对苹果公司发展路径的深入研究经验,以及大语言模型的分析能力,我们系统梳理了多年来苹果 WWDC 主题演讲的规律。在 WWDC 2025 即将揭幕之际,我们让 ChatGPT 对今年的 Keynote 内容进行了一个初步预测,聊作存档。等到明…...
页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...
GC1808高性能24位立体声音频ADC芯片解析
1. 芯片概述 GC1808是一款24位立体声音频模数转换器(ADC),支持8kHz~96kHz采样率,集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器,适用于高保真音频采集场景。 2. 核心特性 高精度:24位分辨率,…...
代理篇12|深入理解 Vite中的Proxy接口代理配置
在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...
MySQL 知识小结(一)
一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库,分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷,但是文件存放起来数据比较冗余,用二进制能够更好管理咱们M…...
区块链技术概述
区块链技术是一种去中心化、分布式账本技术,通过密码学、共识机制和智能合约等核心组件,实现数据不可篡改、透明可追溯的系统。 一、核心技术 1. 去中心化 特点:数据存储在网络中的多个节点(计算机),而非…...
