回顾Java与数据库的30年历程

当 Java 1.0 于 1996 年推出时,语言和互联网都与今天大不相同。当时,网络主要是静态的,而 Java 承诺通过注入交互式游戏和动画来为网络注入活力,这一承诺极具前景。根据 1995 年写给《连线》杂志的 David Banks 的说法,Java 是自 Netscape 以来最热门的技术。

为了更好地理解,Java 的起源可以追溯到 1990 年,当时 Sun Microsystems 在消费市场中的定位举步维艰。在那个时期,他们开发了 Oak,一种旨在实现平台无关、轻量级且非常适合网络环境的编程语言。他们的首次尝试是将 Oak 商业化,用于交互式电视。

到 1994 年,互联网开始普及,Sun 公司认识到 Oak 是其完美的应用程序。与传统软件不同,Oak 允许小程序(小型可移植程序)在任何带有解释器的机器上运行,使其非常适合网络应用程序。Oak 被重新命名为 Java,其解释器被命名为 Java 虚拟机,并创建了一个原型浏览器 HotJava 来展示其功能。

然而,Java 1.0 缺乏标准化的数据库连接。当时互联网仍处于起步阶段,数据库主要应用于企业级应用而非基于网络的软件。因此,Java 的初始设计重点在于创建能够在不同平台上无缝运行的应用程序,而非与后端数据存储系统集成。考虑到当时的背景——数据库领域由 Oracle 7、IBM DB2、Sybase SQL Server 和 Informix 等重型关系型数据库系统主导。这些系统是为传统客户端-服务器架构和企业工作负载设计的,具备复杂的交易处理能力和查询优化器。虽然存在 ObjectStore 和 GemStone 等面向对象数据库,但它们仍属于小众产品,主要用于专门的工程和电信应用。"网络规模"数据库的概念还有数年时间才会出现。

Java 的跨平台性和架构中立设计使其对程序员和企业都具有吸引力。1997 年,在 IBM 工作的 Eli Javier 写信给多伦多的用户组杂志,表示程序员喜爱 Java 是因为它是第一个真正的网络编程语言,而企业喜爱它是因为它可以通过简化应用程序的实施和分发来帮助他们降低成本,因为它可以在任何地方运行,并且可以从中央服务器部署。

就连 IBM 也在 1996 年 Java 1.0 发布后不久,认识到 Java 是网络计算的基础。这一转变在 1997 年得到公开强化,当时 IBM AS/400 部门的总经理比尔·齐特勒明确表示,Java 是 AS/400 业务在网络计算中的关键使能者。

1996年JDBC(Java DataBase Connectivity)诞生

尽管 Java 被迅速采用,但它需要一个统一的方式来与数据库交互。如果没有标准,开发者必须编写特定数据库的代码,这威胁到了 Java 的可移植性。为此,Sun Microsystems 在 Java 1.0 发布后的三个月内推出了 Java 数据库连接 API(JDBC)。受 Microsoft 的 ODBC 启发,JDBC 允许应用程序使用单一接口与数据库交互。到 1996 年年中,JDBC 1.0 最终确定,标志着向企业计算迈出了重要一步。

借助 JDBC,Java 不再仅仅是 applet 和交互式 Web 应用程序的语言,它现在成为企业软件开发的一个可行选项。到 20 世纪 90 年代末,像 Oracle、IBM、Sybase、SAS 和 Borland 等主要数据库厂商已经全面拥抱 Java,并为他们的数据库提供了官方的 JDBC 驱动程序。

虽然 JDBC 是一个突破,但它并非完美解决方案——随着 Java 应用程序的复杂性增加,开发者开始遇到限制。开发者不得不编写大量重复代码来执行简单查询。每次数据库操作都需要手动管理连接、语句和结果集。同时,异常处理既冗长又繁琐,需要使用 try-catch-finally 块进行正确的清理。

对象-关系映射不匹配的弊端开始显现。数据库表和对象是两种截然不同的数据存储介质。关系型数据库通过关系和约束来关注数据的规范化和完整性,而面向对象编程则强调封装、继承和多态。这种根本性的脱节意味着开发者必须不断在这两种范式之间进行转换。具有丰富层次结构和复杂关系的对象必须被扁平化为表格,而规范化的数据库模式则必须被重新组装成相互连接的对象图。在一个世界中的简单概念在另一个世界中变得复杂——Java 中的一个基本继承层次结构可能需要在数据库中通过多个连接表来实现,而一个简单的数据库视图可能需要多个相互关联的类来在对象世界中正确表示。这种阻抗不匹配不仅使开发更加复杂,还影响了性能,因为每次范式之间的转换都会给数据库操作增加额外开销。

1998年EJB(Enterprise JavaBeans)诞生

为了应对这些挑战,J2EE(Java 2 企业版)在 1998 年引入了企业 JavaBeans(EJB)。正如 Cliff Berg 在 1999 年给 Info World 写信中所说,EJB 的主要目标是简化企业应用开发,让软件开发者能够专注于业务逻辑,而不是构建自定义的基础设施。EJB 通过内置的事务管理、安全和可扩展性简化了企业开发。

该模型区分了不同类型的 Bean:会话 Bean,用于管理业务逻辑和用户交互;实体 Bean,用于表示持久化数据。EJB 的一个主要创新是容器管理持久化(CMP),它允许数据库交互由应用服务器自动处理,而无需开发者编写显式的 SQL 查询。

通过 CMP,开发者可以定义表示数据库记录的实体 Bean,而 EJB 容器会自动处理这些对象的持久化、更新和检索。这不仅减少了样板代码的量,还提高了数据库可移植性,因为应用程序不再需要与特定的 SQL 语法或数据库供应商紧密耦合。

EJB 还引入了声明式事务管理,这是对传统数据库事务处理的重要改进。它不再需要开发者手动管理事务(如在代码中调用 commit() 和 rollback()),而是允许通过部署描述符以声明方式配置事务。

EJB 旨在解决的另一个数据库相关挑战是连接池。建立数据库连接是一项耗时的操作,为每个请求打开新的连接会导致严重的性能瓶颈。

但尽管 EJB 的数据库管理方法取得了进步,但它也存在问题。实体 Bean 模型常因其性能低效而受到批评,特别是在处理大规模持久化方面。CMP 虽然方便,但引入了显著的开销,因为容器必须动态生成 SQL 并在后台管理数据库操作。有时开发者发现,为了性能调优,需要使用 Bean 管理持久化(BMP),即显式编码数据库操作。

2001年Hibernate诞生

因 EJB 的复杂性而感到沮丧,Gavin King 于 2001 年开发了 Hibernate,这是一个对象关系映射(ORM)框架。他对 Hibernate 的目标是创建一个开源的对象关系映射(ORM)框架,提供透明的持久化,允许开发者使用普通的 Java 对象(POJOs),而不是管理手动 SQL 查询和数据库事务。

与 JDBC 不同,在 JDBC 中,数据库查询作为字符串嵌入在代码中,Hibernate 引入了一种声明式映射系统,允许开发人员在 XML 配置文件中定义数据库关系。这种方法将数据库逻辑与应用程序代码分离,使得在不破坏应用程序逻辑的情况下更容易修改模式。

Hibernate 最显著的贡献之一,正如 Mario Aquino 在 2003 年所写的那样,是通过映射配置实现了一对一、一对多和多对一的关系,从而消除了开发人员手动处理代码中的连接和外键的需要。此外,Hibernate 支持懒加载、级联删除和外连接抓取,允许应用程序通过减少与数据库的往返次数来优化数据库交互。

Hibernate 的另一个主要优势是代码生成和自动化。Hibernate 可以根据对象关系映射定义生成 Java 源文件。这消除了传统 JDBC 应用中所需的大部分手动编码。与 Hibernate 集成的工具(如 Middlegen)甚至可以分析数据库模式并自动生成 Hibernate 映射文件。相比之下,EJB 实体 Bean 需要手动部署描述符和冗长的 XML 配置,这使得它们难以维护和部署。

为了进一步简化应用架构,Hibernate 还引入了一种轻量级且灵活的事务模型。它提供了内置的事务管理,允许开发人员在不直接管理 JDBC 事务的情况下持久化、更新和删除对象。这与 EJB 的容器管理事务形成了鲜明对比,后者迫使开发人员必须在 Java EE 服务器的约束下工作。通过 Hibernate,事务可以通过编程方式或声明式进行处理,提供了更多的控制和灵活性。

到 2003 年,Hibernate 已经成为数据持久化的首选替代方案,取代了 EJB 实体 Bean。它的成功影响了 Java 的官方 ORM 标准。

2006年JPA(Java Persistence API)规范制定

2006 年,鉴于 Hibernate 等 ORM 框架的成功,Java 社区进程(JCP)成立了 JSR 220,该规范将 Java 持久化 API 作为 EJB 3.0 的一部分引入,而 EJB 3.0 又是 Java EE 5 的一部分。

JPA 标准化了 ORM 的不同实现,如 Hibernate、TopLink 和 JDO。它用注解取代了冗长的 XML 配置,引入了 Java 持久化查询语言(JPQL),并允许开发者使用轻量级的 POJO 代替重量级的实体 Bean。JPA 迅速使 EJB 实体 Bean 过时。

注解取代了 XML 配置的需求,使得持久化映射更加清晰。EJB 2.1 需要冗长的 XML 描述符来定义实体映射,但通过 JPA,像@Entity、@Id 和@OneToMany 这样的简单注解使得定义持久化规则变得容易得多。此外,JPA 引入了 Java 持久化查询语言(JPQL),这是一种面向对象的查询语言,改进了传统 SQL 和有限的 EJB QL。

与需要 Java EE 容器的 EJB 实体 Bean 不同,JPA 可以在独立的 Java SE 应用程序中使用。这种灵活性使开发人员能够在企业应用程序和小型 Java 项目中使用 JPA,而无需应用程序服务器的额外开销。此外,JPA 提供了自动事务管理,使开发人员无需手动处理提交和回滚操作。

JPA 的另一个关键优势是其供应商独立性。API 定义了一个标准的持久化模型,但开发人员可以选择任何 JPA 提供者,例如 Hibernate、EclipseLink 或 OpenJPA。这种解耦提供了更多的灵活性,并减少了依赖特定的 ORM 实现。

尽管 Hibernate 已经得到广泛使用,JPA 的标准化为企业应用带来了统一性。许多项目继续将 Hibernate 作为 JPA 提供者使用,但现在他们可以依赖一个通用的 API,而不是被锁定在单一的 ORM 框架中。Hibernate 的许多创新最终都融入了 JPA 标准:通过代理对象实现的透明懒加载、处理实体生命周期状态(临时、持久和分离)的解决方案、用于跟踪实体变化的持久化上下文概念,以及其复杂的缓存机制。

就连 JPA 的查询语言(JPQL)也深受 Hibernate 的 HQL(Hibernate 查询语言)影响,采用了面向对象的查询方法。其他塑造了 JPA 的关键 Hibernate 特性还包括其用于管理实体关系的级联操作、用于并发控制的乐观锁策略,以及其请求会话模式,这一模式最终演变成了 JPA 的 EntityManager 概念。

随着 JPA 在 2006 年的引入,EJB 实体 Bean 迅速过时。开发者现在可以访问一个更简单、更直观的持久化模型,而无需 EJB 的重重量特性。JPA 也加速了 Java EE 5 的采用,使企业开发更加便捷。

JPA 简化了数据库访问,但管理仓库和编写查询仍然繁琐。开发者仍然需要为仓库管理编写样板代码。获取、更新和删除记录需要定义自定义查询或编写大量代码。

除此之外,到了 21 世纪头十年末,NoSQL 数据库的兴起正在重塑数据存储格局。虽然关系型数据库在几十年间一直是主流选择,但网络应用、大数据和实时处理的爆炸式增长带来了传统关系型数据库难以满足的新需求。MongoDB、Cassandra、Redis 和 Neo4j 等 NoSQL 数据库因其为特定场景提供了更好的可扩展性、灵活性和性能而广受欢迎。与强制执行严格模式的关系型数据库不同,NoSQL 数据库允许更动态的数据模型,使其成为云原生应用和分布式系统的理想选择。

2010年Spring Data诞生

认识到需要一种更简单、更统一的方式来与关系型和非关系型数据库交互,Spring Data 于 2010 年作为 Spring 生态系统的一部分被引入。其目标是为数据访问提供一致的、高级的抽象,消除重复的样板代码,并让开发者能够专注于业务逻辑而不是基础设施。Spring Data 不再需要手动定义查询或实现仓库模式,而是引入了仓库的概念,这些仓库根据方法名自动生成查询,减少了开发者需要编写的代码量。

在 Spring Data 旗下发布的第一个模块是 2011 年 4 月发布的 Spring Data Neo4j,仅仅几个月后,在 2011 年 7 月,Spring Data JPA 1.0 发布了。

虽然 JPA 已经简化了 ORM,但 Spring Data JPA 更进一步,引入了自动查询生成、分页和声明式事务管理。开发者不再需要为简单查询编写 SQL 或 JPQL——Spring Data JPA 可以从方法名中推导出查询,使数据库访问更加直观,并减少了样板代码的需求。

2011年Spring Data MongoDB诞生

2011 年 10 月,Spring Data MongoDB 1.0 发布。此时,MongoDB 已成为主流的 NoSQL 文档数据库,为开发者提供了灵活的无模式数据模型。与需要复杂迁移才能更改模式的传统关系型数据库不同,MongoDB 允许应用程序动态演进。

2012年Spring Data Redis 诞生

下一个重要里程碑出现在 2012 年 5 月,Spring Data Redis 1.0 发布。与传统数据库不同,Redis 是一个以内存优先的键值数据库,以其卓越的速度和多功能性而闻名。最初于 2009 年开发,Redis 迅速成为现代架构的关键组成部分,支持缓存层、实时分析、会话存储,甚至消息代理系统。

未来展望

在接下来的几年里,新的 Spring Data 集成不断发布,而随着多模型数据库、无服务器数据库和边缘计算的出现,该领域继续快速发展。这让我们不禁思考:当面对不断变化的数据世界时,Java 将何去何从?

未来并非在于选择 SQL 还是 NoSQL,而在于为合适的任务选择合适的数据模型。这一理念体现在像 CockroachDB 和 FaunaDB 这类现代数据库中,它们模糊了传统分类的界限,同时提供 SQL 接口和分布式 NoSQL 般的可扩展性。

Java 数据访问库的演进似乎也遵循这一趋势。Project Loom 的虚拟线程承诺将革新 Java 处理数据库连接的方式,可能使反应式编程模式在高吞吐量应用中从必要条件变为可选条件。我们可以预期 Java 平台上的数据访问将演进为在不同数据模型之间提供一致体验,同时利用 Java 的新并发特性。

人工智能和机器学习的兴起也在推动 Java 进行适应。数据领域的新宠是向量数据库。尽管向量数据库已经存在一段时间,但新获得的能力——即寻找 AI 模型为任何非结构化数据创建向量表示——提升了数据库有效处理向量和向量操作(如通过 KNN/ANN 进行语义搜索)的需求。

我们正看到 Java 应用程序对无缝交互向量数据库和大型语言模型的需求日益增长,同时保持 Java 开发人员所期望的类型安全性和可靠性。我们将看到针对这些用例的新标准出现吗?就像 JPA 标准化 ORM 一样。Java 将如何演变以应对边缘实时数据处理需求的增长?随着无服务器数据库的普及,Java 的传统连接池和事务管理模式将如何适应这些新范式?这一趋势已经在 Spring AI 等项目中有可见迹象。

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

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

相关文章

simulink有无现成模块可以实现将三个分开的输入合并为一个[1*3]的行向量输出?

提问 simulink有无现成模块可以实现将三个分开的输入合并为一个[1*3]的行向量输出? 回答 Simulink 本身没有一个单独的模块能够直接将三个分开的输入合并成一个 [13] 行向量输出,但是可以通过 组合模块实现你要的效果。 ✅ 推荐方式:Mux …

代码训练LeetCode(24)数组乘积

代码训练(24)LeetCode之数组乘积 Author: Once Day Date: 2025年6月5日 漫漫长路,才刚刚开始… 全系列文章可参考专栏: 十年代码训练_Once-Day的博客-CSDN博客 参考文章: 238. 除自身以外数组的乘积 - 力扣(LeetCode)力扣 (LeetCode) 全…

NLP学习路线图(十七):主题模型(LDA)

在浩瀚的文本海洋中航行,人类大脑天然具备发现主题的能力——翻阅几份报纸,我们迅速辨别出"政治"、"体育"、"科技"等板块;浏览社交媒体,我们下意识区分出美食分享、旅行见闻或科技测评。但机器如何…

vue对axios的封装和使用

在 Vue 项目中,使用 axios 进行 HTTP 请求是非常常见的做法。为了提高代码的可维护性、统一错误处理和请求拦截/响应拦截逻辑,对axios进行封装使用。 一、基础封装(适用于 Vue 2 / Vue 3) 1. 安装 axios npm install axios2. 创…

HTML实现端午节主题网站:龙舟争渡,凭吊祭江诵君赋。

名人说:龙舟争渡,助威呐喊,凭吊祭江诵君赋。——苏轼《六幺令天中节》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 目录 一、项目概览:传统与现代的技术碰撞1. 核心特性一览2. 网站结构设计二、技术亮点深度解析1. 响应式布局的精妙设计2. CSS动画系统的…

【Redis】笔记|第9节|Redis Stack扩展功能

Redis Stack 扩展功能笔记(基于 Redis 7) 一、Redis Stack 概述 定位:Redis OSS 扩展模块(JSON、搜索、布隆过滤器等),提供高级数据处理能力。核心模块: RedisJSON:原生 JSON 支持…

如何选择专业数据可视化开发工具?为您拆解捷码全功能和落地指南!

分享大纲: 1、捷码核心功能:4维能力支撑大屏开发 2、3步上手:可视化大屏开发操作路径 3、适配场景:8大行业已验证方案 在各行各业要求数字化转型时代,数据可视化大屏已成为众多企业数据驱动的核心工具。面对市场上繁杂…

测试W5500的第11步_使用ARP解析IP地址对应的MAC地址

本文介绍了基于W5500芯片的ARP协议实现方法,详细阐述了ARP请求与回复的工作机制。ARP协议通过广播请求和单播回复实现IP地址与MAC地址的映射,确保局域网设备间的可靠通信。文章提供了完整的STM32F10x开发环境下的代码实现,包括网络初始化、SP…

在树莓派上添加音频输入设备的几种方法

在树莓派上添加音频输入设备可以通过以下步骤完成,具体方法取决于设备类型(如USB麦克风、3.5mm接口麦克风或HDMI音频输入)。以下是详细指南: 1. 连接音频输入设备 USB麦克风/声卡:直接插入树莓派的USB接口。3.5mm麦克…

IDEA 打开文件乱码

问题:文件乱码 底部编码无法切换 解决方案: 第一步 使用Nodepad 查询文件编码 本项目设置为 转为 UTF-8 无 BOM 第二步:在 IntelliJ IDEA 中:右键点击文件 → File Encoding → 选择目标编码(如 UTF-8) 最…

float、double 这类 浮点数 相比,DECIMAL 是另一种完全不同的数值类型

和 float、double 这类**“浮点数”**相比,DECIMAL 是另一种完全不同的数值类型,叫做: ✅ DECIMAL 是什么? DECIMAL 是“定点数”类型(fixed-point),用于存储精确的小数值,比如&…

Java应用10(客户端与服务器通信)

Java客户端与服务器通信 Java提供了多种方式来实现客户端与服务器之间的通信,下面我将介绍几种常见的方法: 1. 基于Socket的基本通信 服务器端代码 import java.io.*; import java.net.*;public class SimpleServer {public static void main(String…

pytorch基本运算-范数

引言 前序学习进程中,已经对pytorch基本运算有了详细探索,文章链接有: 基本运算 广播失效 乘除法和幂运算 hadamard积、点积和矩阵乘法 上述计算都是以pytorch张量为运算元素,这些张量基本上也集中在一维向量和二维矩阵&#x…

EasyRTC音视频实时通话助力新一代WebP2P视频物联网应用解决方案

一、方案背景​ 物联网技术深刻变革各行业,视频物联在智慧城市、工业监控等场景广泛应用。传统方案依赖中心服务器中转,存在传输效率低、网络负载大的问题。新一代WebP2P视频物联技术实现设备直连,降低网络压力并提升传输效率,成…

DAY 15 复习日

浙大疏锦行 数据使用爬虫爬取weibo数据,下面是代码 import datetime import os import csv import timeimport numpy as np import random import re import urllib.parse import requests from fake_useragent import UserAgentdef init():if not os.path.exists…

SSL/TLS 协议详解:安全通信的基石

一、概述 SSL(Secure Sockets Layer) 及其继任者 TLS(Transport Layer Security) 是位于 传输层(TCP)与应用层之间 的加密协议,用于在网络通信中实现 机密性、身份认证和数据完整性。 核心目标…

使用子树合并策略更新git项目的部分目录

背景 正在开发的一个项目中引用了第三方库的源码,由于历史原因,源码的引用并不是很规范(直接下载下来后作为自己项目的部分源码使用,还进行了一些修改),具体如下: 我有一个本地git项目project…

pikachu通关教程-CSRF

CSRF(get) 用bp进行抓包 选择action value值的修改 点击test in browser copy然后放在bp代理的浏览器上,会出现一个提交按钮,这时候点击之后信息就被修改了。 CSRF(post) 请求的方式不同,其他都是一样 CSRF Token 存在cookie 首先要先下载一…

AI驱动游戏开发:Unity与ML-Agents结合

AI驱动游戏开发:Unity与ML-Agents结合 系统化学习人工智能网站(收藏):https://www.captainbed.cn/flu 文章目录 AI驱动游戏开发:Unity与ML-Agents结合摘要引言技术架构与开发流程1. Unity与ML-Agents协同机制2. 开发…

如何给windos11 扩大C盘容量

动不动C盘就慢了,苹果逼着用户换手机,三天两头更新系统,微软也是毫不手软。c盘 从10个G就够用,到100G 也不够,看来通货膨胀是部分行业的。 在 Windows 11 中扩大 C 盘容量,主要取决于磁盘分区布局和可用空…