J2EE 应用程序中的数据管理和数据持久性 |
时间:2014-05-04 10:04:10 来源:不详 作者:佚名 |
本文分析了在 Java 平 连接(JDBC)。尽管本质上 系统时,JDBC 轻而易举地 Shankar Itchapurapu 对序 JDBC 是您的最佳选择的原
| 台上可用的两个数据管理策略: 这两种数据管理策略并不存在孰 得以胜出。在本文中,Java 开 列化和 JDBC都进行了介绍,并 因。
| Java 对象序列化和 Java 数据库 优孰劣的问题,但在管理企业信息 发人员 G.V.B. Subrahmanyam 和 通过讨论和实例来向您展示了
|
当您正在建立企业信息 对于所有业务而言,数据都 重要性是无论如何强调都不
| 系统时,需要确保以某种有效的 是独一无二的最大资产。所有软 过分的。
| 方式存储、检索和显示企业数据。 件系统都涉及数据,因此,数据的
|
应用程序的数据管理功 们是:建立、检索、更新 范围之内,始终如一地、成 。换句话说,管理数据意味 CRUD 操作,在软件的生命
| 能包括四个基本操作,通常也需 和 删除(即 CRUD)。管理在企 功地执行 CRUD 操作,而不必频 着开发稳健的、可扩展和可维护 期中能够以一致的方式执行操作
| 要对企业数据执行这四个操作,它 业系统的数据涉及在很长一段时间 繁地更改实际执行这些操作的代码 的软件系统,以确保成功地进行 。
|
本文讨论了 J2EE 中的两种可用数据 JDBC)。我们将查看这两种方法的优缺点 定实现中,策略的可用性取决于项目的范 上下文(驱动系统/子系统运行时的值的 并不适合于企业系统,其数据需要用一种 速浏览 Java 对象序列化,然后查看 JDB 所缺乏的一些关键特性的。
| 管理策略:Java 对象序列化和 Java 数据库连接( 。这两种数据管理策略实质上不存在孰优孰劣。在特 围(出现在系统环境中的活动的活动范围),系统的 集合),以及其他的外部因素。然而,Java 序列化 定义良好的结构(如RDBMS)来组织。我们首先将快 C 更重要的一些方面,从而了解后者是如何实现前者
|
本文并不打算对 Java 对象序列化或 ,请回顾参考资料小节。
| 者 JDBC 进行全面介绍。有关这两项技术的更多信息
|
对象序列化是最简单的 的线性序列的过程。对象图 非暂态实例属性以字节的形 中的值。如果一个 Java 对 口,该接口具有如下所示的
| Java 持久性策略。对象序列化 是作为对象继承、关联和聚合的 式被写入到持久存储中。实例属 象是可序列化的,那么它至少必 结构:
| 是一个将对象图平面化为一个字节 结果而实现的一些关系式。对象的 性的值就是执行时间序列化时内存 须实现 java.io.Serializable 接
|
public interface Serializable |
您可以看到,java.io.Serializable 接口。它告诉 Java 运行时环境,该实现 例类。
| 接口并没有声明任何方法。它是一个记号或者标记 类是可序列化的。列表 1 显示实现该接口的一个示
|
列表 1. MySerializableObject.java |
import java.io.Serializable; |
public class MySeria
| lizableObject extends MySupe
| rClass implements Serializable
|
private String property1 = null; |
private String property2 = null; |
public String getProperty1() |
public void setProperty1(String val) |
public String getProperty2() |
public void setProperty2(String val) |
private void w
| riteObject(ObjectOutputStrea
| m out)
|
out.writeObject (getProperty1 ()); |
out.writeObject (getProperty2 ()); |
private void r
| eadObject (ObjectInputStream
| in)
|
throws IOException, ClassN
| otFoundException
|
setProperty1 ((String) in
| .readObject ());
|
setProperty2
| ((String) in.readObject ());
|
无需自己实现 writeOb 环境具有使这些方法可用的 您自己的实现。
| ject(...) 和 readObject(...) 默认实现。然而,您可以重写这
| 方法来执行序列化;Java 运行时 些方法,提供如何存储对象状态的
|
关于序列化,您需要记住一些要点。 被引用类)都将被序列化。其次, Seria ,除非已经特别声明它们为暂态,或者已 只序列化那些可序列化的实例变量。如果
| 首先,在序列化期间,整个对象图(即,所有父类和 lizable 类的所有实例变量自身都应该是可序列化的 经重写 writeObject(...) 和 readObject(...) 来 违反了后一规则,在运行时将出现一个异常。
|
每个后续 J2SE 版本都 ObjectOutputStream and O 法。通常,一个序列化的流 其他对象可以对它进行后向 用。非共享的读写方法允许 象克隆但开销更少的效果。
| 对对象序列化系统进行少量的增 bjectInputStream 增加 writeU 只包含任何给定对象的一个序列 引用。通常期望序列化一个对象 对象作为新的、独一无二的对象
| 加。J2SE 1.4 也相应地向 nshared() and readUnshared()方 化实例,并且共享对该对象引用的 独立于其他对象可能维护的任何引 被序列化,从而获得一个类似于对
|
序列化涉及到将对象图 销。通常,对应用程序而言
| 从内存具体化到持久存储(例如 ,序列化并不是最佳选择:
| 硬盘)中。这涉及到大量 I/O 开
|
序列化的字节流只对 Java 语言是可 的,许多应用程序要与其他应用程序共同
| 读的。这是一个重大缺陷,因为企业系统通常是异构 处理相同的数据。
|
没有一个用来从序列化对象图中检索获取数据的查询语言。 |
序列化本身并不提供任 API 的应用程序中使用它。
| 何事务控制机制,因此不能在那
| 些需要并发访问从而不使用辅助
|
Java 数据库连接(JDBC)是一个标 。诸如 JDBC 的调用级接口是编程接口, 中的数据。通过提供与数据库连接的库例 。特别是,JDBC 有一个使接口变得极其
| 准的 API,它使用 Java 编程语言与数据库进行交互 它们允许从外部访问 SQL 命令来处理和更新数据库 程,它们允许将 SQL 调用集成到通用的编程环境中 简单和直观的例程的丰富收集。
|
在下面几个小节中,我 关注与 Java 对象序列化相
| 们将查看通过 JDBC 与数据库连 比,JDBC 是如何成为一个企业
| 接所涉及的一些步骤。我们将特别 数据管理策略的。
|
在利用 JDBC 做任何其 且将该库添加到类路径中。 码来实现实际的连接。
| 他事情之前,需要从驱动程序供 一旦完这项工作,就可以在 Jav
| 应商那里获取数据库驱动程序,并 a 程序中使用类似于下面所示的代
|
Class.forName(<your driver class Name>); |
Java.sql.Connection conn = DriverManager.getConnection(<connection URL>); |
Java 对象序列化并不需要这个该步 DBMS。 序列化是一个基于文件的机制; 中打开一个 I/O 流。
| 骤,因为使用序列化来执行持久性操作并不需要 因此,在序列化一个对象之前,需要在目标文件系统
|
创建 JDBC Statement 和 PreparedStatement |
可以用 JDBC Statemen 将该对象与 SQL 语句混淆 的 SQL 语句有关联。可以 多个(您请求执行的)SQL
| t 对象将 SQL 语句发送到数据 。 JDBC Statement 对象是与打 将 JDBC Statement 对象看作是 语句传送给 DBMS。
| 库管理系统(DBMS),并且不应该 开连接有关联,而不是与任何单独 位于连接上的一个通道,将一个或
|
为了创建 Statement 对象,您需要 Connection 对象 con——下面的代码来
| 一个活动的连接。通过使用我们前面所创建的 完成这项工作。
|
Statement stmt = con.createState
| ment();
|
到目前为止,我们已经 SQL 语句。
| 有了一个 Statement 对象,但
| 是还没有将对象传递到 DBMS 的
|
当数据库接收到语句时 的分析,数据库就必须计算 查哪些索引可以提供帮助, 行。数据库针对数据进行统 以执行它。
| ,数据库引擎首先会分析该语句 出执行它的最有效方法。在计算 如果存在这样的索引的话,或者 计,找出最佳的执行方式。一旦
| 并查找句法错误。一旦完成对语句 上,这可能非常昂贵。数据库会检 检查是否应该完全读取表中的所有 创建好查询计划,数据库引擎就可
|
生成这样一个计划会占用 CPU 资源 库,那么我们希望数据库重用第一个语句 象来获得这种效果。
| 。理想情况是,如果我们两次发送相同的语句到数据 的访问计划,我们可以使用 PreparedStatement 对
|
这里有一个主要的特性是,将 Prepa Statement 不同,在创建 PreparedState 送给 DBMS,在那里编译该语句。因而, 和被编译的 SQL 语句相关联的。
| redStatement 与其超类 Statement 区别开来:与 ment 时,会提供一个 SQL 语句。然后了立即将它发 PreparedStatement 实际上是作为一 个通道与连接
|
那么,它的优势是什么 利用 PreparedStatement, Statement 相比,每次使用
| 呢?如果需要多次使用相同的查 语句,只需被 DBMS 编译和优化 相同的 SQL 语句都需要重新编
| 询或者不同参数的类似查询,那么 一次即可。与使用正常的 译一次。
|
还可以通过 Connectio 有三个输入参数的参数化了
| n 方法创建PreparedStatement 的 SQL 语句。
| 。下面代码显示了如何创建一个带
|
PreparedStatement
| prepareUpdatePrice = con.pr
| epareStatement(
|
"UPDATE Sells
| SET price = ? WHERE bar = ?
| AND beer = ?");
|
注意,Java 序列化不 惟一途径就是反序列化该对 整的对象在计算上可能很昂
| 支持类似于 SQL 的查询语言。 象,并调用该对象上的 getter/ 贵,尤其是在程序的生命期中,
| 使用 Java 序列化访问对象属性的 accessor 方法。反序列化一个完 应用程序需要重复执行它。
|
在执行 PreparedStatement 之前, 中定义的 setXXX() 方法可以实现它。最 setDouble(),以及 setString()。每次
| 需要向参数提供值。通过调用 PreparedStatement 常使用的方法是 setInt(),setFloat(), 执行已准备的声明之前,都需要设置这些值。
|
执行 JDBC 中的 SQL 言)语句(例如表建立和表 执行的。列表 2 中包含 ex
| 语句的方式是根据 SQL 语句的 更改语句)和更新表内容的语句 ecuteUpdate() 语句的实例。
| 目的而变化的。DDL(数据定义语 都是通过使用 executeUpdate()
|
列表 2. 实际运行中的 executeUpdate() |
Statement stmt =
| con.createStatement();
|
stmt.executeUpdate("CREATE TA
| BLE Sells " +
|
"(bar VARCHAR2
| (40), beer VARCHAR2(40), pri
| ce REAL)" );
|
stmt.executeUpdate("INSERT IN
| TO Sells " +
|
"VALUES ('Bar
| Of Foo', 'BudLite', 2.00)" )
| ;
|
String sqlString
| = "CREATE TABLE Bars " +
|
"(name VARCHAR2(40), addre
| ss VARCHAR2(80), license INT)" ;
|
stmt.executeUpdate(sqlString); |
我们将通过先前插入的 用 executeUpdate(),如下
| 参数值(如上所示)执行 Prepa 所示:
| redStatement ,然后在这之上调
|
int n = prepareUpdatePrice
| .executeUpdate() ;
|
相比之下,查询期望返回一个行作为 称为 executeQuery() 的相对应的方法,
| 它的结果,并且并不改变数据库的状态。这里有一个 它的返回值是 ResultSet 对象,如列表 3 所示。
|
ResultSet rs = st
| mt.executeQuery("SELECT * FR
| OM Sells");
|
bar = rs.getString("bar"); |
beer = rs.getString("beer"); |
price = rs.getFloat("price"); |
System.out.println(bar + " Dollars.");
| sells " + beer + " for " + price + "
|
由于查询而产生的行集包含在变量 r 我们来说并没有太大用处,除非我们可以 供了一个光标,可以用它依次访问每一个 每个方法调用都会导致光标向下一行移动 的行,则返回 false。
| s 中,该变量是 ResultSet 的一个实例。集合对于 访问每一个行以及每一个行中的属性。ResultSet 提 行。光标最初被设置在正好位于第一行之前的位置。 ,如果该行存在,则返回 true,或者如果没有剩余
|
我们可以使用适当类型的 getXXX() getString() 和 getFloat() 方法来访 数的列的名称;我们可以指定用列号来代 依次类推。
| 来检索某一个行的属性。在前面的实例中,我们使用 问列值。注意,我们提供了其值被期望用作方法的参 替列名。检索到的第一列的列号为 1,第二列为 2,
|
在使用 PreparedStatement 时,可 executeQuery(),如下所示:
| 以通过先前插入的参数值来执行查询,然后对它调用
|
ResultSet rs = prepareUpda
| tePrice.executeQuery() ;
|
JDBC 还提供一系列发 isBeforeFirst(),isLast(
| 现您在结果集中的位置的方法: ),以及 isAfterLast()。
| getRow(),isFirst(),
|
这里还有一些使可滚动 只向前滚动,并且是只读的 型更改为更为灵活的可滚动
| 光标能够自由访问结果集中的任 。在为 Connection 创建 State 或可更新模型,如下所示:
| 意行的方法。在默认情况下,光标 ment 时,可以将 ResultSet 的类
|
Statement stmt = con.creat ResultSet.CONCUR_READ_ONLY);
| eStatement(ResultSet.TYPE_FORWARD_ONLY,
|
ResultSet rs = stmt.execut
| eQuery("SELECT * FROM Sells");
|
不同的类型选项: TYPE_FORWARD_ON TYPE_SCROLL_SENSITIVE 。可以通过使用 择光标是只读的还是可更新的。对于默认 动的光标,您有更多的选项,如下所示:
| LY 、 TYPE_SCROLL_INSENSITIVE 和 CONCUR_READ_ONLY 和 CONCUR_UPDATABLE 选项来选 光标,可以使用 rs.next() 向前滚动它。对于可滚
|
rs.absolute(3); /
| / moves to the third retrieved row
|
rs.previous(); set
| // moves back one
| row in the retrieved result
|
rs.relative(2); / result set
| / moves forward two rows in the retrieved
|
rs.relative(-3); / result set
| / moves back three rows in the retrieved
|
对于可滚动光标的工作 是有用的,但是它导致极大 找到关于可滚动 ResultSet
| 方式,这里有更多的详细描述。 的性能损失,所以应该限制和谨 的更多信息。
| 尽管可滚动光标对于特定应用程序 慎使用。可以在 参考资料小节中
|
在序列化中不存在与 JDBC 的 Resul 据的角度不同。JDBC (通常)假定底层 对象图。两种技术的底层数据结构存在显 化的对象图结构,反之亦然。当通过使用 结构变成了一个字节流,该字节流展示了 。
| tSet 相对应的机制。序列化和 JDBC 观察底层的数 数据是关系型结构的;而序列化假定底层数据是一个 著差异。JDBC 的 Set 结构并不能自然地映射到序列 序列化语义将一个 Java 对象持久化时,数据的底层 已经序列化了的核心对象的各种内部对象之间的关联
|
JDBC 中的 ResultSet 中,这是不可能的,因为序 此,Java 对象序列化无法
| 导航是从一个 Set 元素移动到 列化涉及到对象关联,而不是将 向您提供用这种方式访问数据单
| 其他元素的过程,而在对象序列化 一组行封装到一个实体集合中。因 独某个部分的能力。
|
JDBC 允许将 SQL 语句组合到单独一 来确保 ACID 属性。
| 个事务中。因此,我们可以通过使用 JDBC 事务特性
|
Connection 对象执行事务控制。当 。这意味着每个 SQL 语句自身都被看作
| 建立连接时,在默认情况下,连接是自动提交模式下 是一个事务,并且一完成执行就会被提交。
|
con.setAutoCommit(false) ; |
con.setAutoCommit(true) ; |
一旦关闭了自动提交, SQL 语句(即,数据库将不 rollback() 回滚事务,并
| 除非通过调用 commit() 显式地 会被持久地更新)。在提交之前 恢复最近的提交值(在尝试更新
| 告诉它提交语句,否则无法提交 的任何时间,我们都可以调用 之前)。
|
我们还可以设置期望的事务隔离等级 TRANSACTION_READ_COMMITTED,这使得在 在 Connection 接口中为隔离等级提供了 。JDBC 允许我们发现数据库所设置的是 getTransactionIsolation() 方法)以及 setTransactionIsolation() 方法)。
| 。例如,我们可以将设置事务隔离等级为 提交值之前,不允许对它进行访问。并且禁止脏读。 五个这样的值。默认情况下,隔离等级是可序列化的 什么事务隔离等级(使用 Connection 的 设置适当的等级(使用 Connection 的
|
回滚通常与 Java 语言的异常处理能 一个简单高效的机制。在下一节中,我们
| 力结合在一起使用。这种结合为处理数据完整性提供 将研究如何使用 JDBC 进行错误处理。
|
注意,Java 对象序列 其他的 API,例如 JTA,来 一个更新操作时同步该序列
| 化并不直接支持事务管理。如果 获得这个效果。然而,为了获得 化对象,如下所示:
| 您正在使用序列化,则将需要借助 事务隔离的效果,可以选择在执行
|
Synchronized(my_deserialized_o
| bject) {
|
//Perform the updates etc... |
软件程序中总是出现一 处理错误是有必要的。程序 常处理程序结合使用是达到
| 些错误。通常,数据库程序是关 应该恢复并且让数据库处于某种 这种要求的一种简便方法。
| 键性应用程序,而且适当地捕获和 一致的状态下。将回滚与 Java 异
|
访问服务器(数据库)的客户(程序 过提供两种等级的错误条件来访问这种信 是 Java 异常,它(如果未被处理)将会 子类,但是它们代表的是非致命错误或意
| )需要能够识别从服务器返回的所有错误。JDBC 通 息:SQLException 和 SQLWarning。SQLException 终止该应用程序。SQLWarning 是 SQLException 的 想不到的条件,因此,可以忽略它们。
|
在 Java 代码中,希望抛出异常或者 句抛出异常或者警告,那么可以在对应的 它准备捕获的异常。
| 警告的语句包含于 try 块中。如果在 try 块中的语 某个 catch 语句中捕获它。每个捕获语句都指出了
|
换句话说,如果数据类 表,则可能会抛出一个异常 SQLWarning。每个对象都 行其他语句,则将放弃所有
| 型是正确的,但是数据库大小超 。 可以从 Connection,Statem 只是存储最近 SQLWarning。因 早期的警告。列表 4 举例说明
| 出其空间限制并且不能建立一个新 ent,以及 ResultSet 对象中获取 此,如果通过 Statement 对象执 了 SQLWarning 的使用。
|
ResultSet rs =
| stmt.executeQuery("SELECT b
| ar FROM Sells") ;
|
SQLWarning war
| n = stmt.getWarnings() ;
|
System.out.println("Mes
| sage: " + warn.getMessage()) ;
|
SQLWarning warning = rs.ge
| tWarnings() ;
|
warning = w
| arning.getNextWarning() ;
|
System.out.
| println("Message: " + warn.g
| etMessage()) ;
|
实际上,SQLWarning DataTruncation 警告,它
| 在某种程度上比 SQLException 表示在从数据库读或写数据时存
| 更为罕见。最常见的是 在问题。
|
Java 并没有提供序列 行的 I/O 操作有关,因此
| 化所使用的特定的异常类。使用 ,在这些情况中 I/O 异常类将
| 序列化时发生的大多数异常都与执 满足要求。
|
JDBC 2.0 提供一个用于批处理的强 一起发送并处理。一个典型的批处理就是 账号。在减少从 Java 代码到数据库的往
| 大API。批处理允许积累一组 SQL 语句,并且将它们 银行应用程序,该应用程序每隔一刻钟就要更新许多 返次数方面,批处理是一个强大功能。
|
Statement 接口提供 a 已经将所有的 SQL 语句都 们。
| ddBatch(String) 方法,将 SQL 增加到该批处理中,就可以使用
| 语句添加到一个批处理中。一旦 executeBatch() 方法一起执行它
|
然后,用executeBatch 受每条语句影响的行数。将 理中会导致 SQLException
| () 方法执行 SQL 语句,并返回 SELECT 语句或者其他返回 Res 。
| int 值的一个数组。该数组包含 ultSet 的 SQL 语句放在一个批处
|
列表 5 中列出了利用 java.sql.Sta
| tement 进行批处理的一个简单实例。
|
Statement stmt = con
| n.createStatement();
|
stmt.insert("DELETE FROM Users"); |
stmt.insert("INSERT
| INTO Users VALUES('rod', 37,
| 'circle')");
|
stmt.insert("INSERT
| INTO Users VALUES('jane', 33
| , 'triangle')");
|
stmt.insert("INSERT INTO Users V
| ALUES('freddy', 29, 'square')");
|
int[] counts = stmt.executeBatch(); |
在您不知道特定语句将运行的次数时 果在不使用批处理的情况下试图插入 100 脚本,增加 10000 条记录,那么情况会 能够提高代码的可读性。
| ,批处理是一个处理 SQL 代码的好方法。例如,如 条记录,那么性能可能会受到影响。如果编写一个 变得更糟。添加批处理可以帮助提高性能,后者甚至
|
Java 对象序列化并不支持批处理。 ,在这种情况下,批处理没有意义。因此 的灵活性,而这些对于序列化来说不一定
| 通常,会在某个对象的范围(联系图)上运用序列化 ,批处理在数据更新的定时和分组方面为您提供一定 是可用的。
|
存储过程是一组 SQL 语句,它们建 程来封装一个操作或者查询的集合,这些 程是在数据库服务器中被编译和存储的。 的二进制代码,因此执行速度会更快。
| 立了一个逻辑单元,并执行特定任务。可以用存储过 操作或查询都将在一个数据库服务器上执行。存储过 因此,每次调用存储过程时,DBMS 都将重用已编译
|
JDBC 允许您从 Java 应用程序中调 CallableStatement 对象。与 Statement 个打开的 Connection 对象完成的。Call 不包含存储过程自身。列表 6 中的第一 SHOW_ACCOUNT 的调用。波形括号中括住 {call SHOW_ACCOUNT} 时,它将该转义语 SHOW_ACCOUNT 的存储过程。
| 用数据库存储过程。第一步是创建 和 PreparedStatement 对象一样,这项操作是用一 ableStatement 对象包含对存储过程的调用;但它并 行代码使用 con 连接建立了对存储过程 的部分是存储过程的转义语法。当驱动程序遇到 法翻译成数据库所使用的本地 SQL,从而调用名为
|
CallableStatement cs = con.prepa
| reCall("{call SHOW_ACCOUNT(?)}");
|
cs.setInt(1,myaccountnumber); |
ResultSet rs = cs.executeQuery(); |
假设 Sybase 中的存储
| 过程 SHOW_ACCOUNT 包含列表 7
| 中所示的代码。
|
Listing 7. SHOW_ACCOUNT stored p
| rocedure
|
CREATE PROCEDURE SHOW_ACCOUNT (@
| Acc int)
|
Select balance from USER_ACCOUN
| TS where Account_no = @Acc
|
注意,用来执行 cs 的方法是 execu 询,所以只产生一个结果集。如果该过程 executeUpdate() 方法。然而,有时候存 下,它将产生多个结果集、多个更新计数 用 execute() 方法执行 CallableStatem
| teQuery(),由于 cs 调用的存储过程只包含一个查 只包含一个更新或者一个 DDL 语句,则将使用 在存储过程包含多个 SQL 语句的情况,在这种情况 ,或者结果集和更新计数的某种结合。因此,应该使 ent。
|
CallableStatement 类是 PreparedS 以接受与 PreparedStatement 对象相同 出参数,并将该参数用于输入和输出。IN 理 OUT 参数,需要通过使用 registerOu 过程。
| tatement 的子类,因此 CallableStatement 对象可 的参数。而且,CallableStatement 对象可以接受输 OUT 参数和 execute() 方法通常很少使用。要想处 tParameter(int, int) 方法将 OUT 参数注册到存储
|
举例说明,我们假设 GET_ACCOUNT 过程包含列表 8 中的代码。 |
CREATE PROCEDURE GET_ACCOUNT (@A
| cc int, @balance float OUTPUT)
|
Select @balance = balance from U
| SER_ACCOUNTS where Account_no = @Acc
|
在这个实例中,参数 b 如列表 9 所示。
| alance 被声明是一个 OUT 参数
| 。现在,调用该过程的 JDBC 代码
|
CallableStatement cs
| mt = con.prepareCall("{GET_A
| CCOUNT(?,?)");
|
csmt.setInt(1,youraccountnumber); |
csmt.registerOutParamter(2,java.
| sql.Types.FLOAT);
|
正使用 Java 序列化时 一个纯 Java 语言现象,它 在与 CallableStatement 者组件中,尽管这些系统或
| ,并不需要访问任何外部的系统 不涉及执行一个外部环境中的已 对象相对应的机制。这意味着您 者组件可能更适合它。
| ,如 DBMS。换句话说,序列化是 编译代码。因此,在序列化中不存 不能将数据处理转移到外部系统或
|
在读完本文之后,我们 序列化要好得多的方法。
| 希望您赞同:对于数据管理和持
| 久化而言, JDBC 是比 Java 对象
|
JDBC 是一个用来访问 集合来访问多种数据源。用 源可以是关系型的、层次型 接到目标数据源。JDBC 做 将程序员从供应商特定的桎
| 数据存储的极好的 API。 JDBC 户只需要学习一个 API 集合, 的或者任何其他格式。您需要的 了大量工作,将所有技术细节都 梏中解放出来。
| 最好的东西是它提供单一的 API 就可以访问任何数据源,这些数据 只是一个 JDBC 驱动程序,用它连 封装到了一个实现软件包中,从而
|
表 1 对比了 JDBC 和 Java 对象序列化的各种特性。 |
Java 对象序列化和 JDBC 是 Java 多个 JVM 之间以 Java 语言特定格式共 ,序列化最适合不过。然而,Java 序列 对这些数据进行组织。在这样的企业系统 系统并不一定都与 Java 语言兼容。在这
| 技术领域中许多数据持久化机制中的两种。在需要在 享数据(例如用 RMI 的按值传递机制共享数据)时 化并不适用于企业数据,需要以一种定义良好的结构 中,需要在多个系统和子系统之间共享数据,而这些 种情况中,对象序列化根本不能工作。
|
JDBC 提供一个公用 API来访问异构 。它提供了一个使用 Java 平台访问数据 CRUD 操作所需的所有代码都是由开发人
| 的数据存储。它是 JVM 和目标 DBMS 之间的粘合剂 存储和维护企业数据的纲领性方法。然而,执行 员编写。
|
为了在企业环境中最有 一个用于数据持久性的框架 关,因此强烈建议将数据持 常有帮助。
| 效地使用 JDBC,架构设计人员 。由于使用 JDBC 持久化数据的 久性层与应用程序的商业逻辑相
| 需要分析其企业中的数据,并开发 机制与系统想要解决的商业问题无 分离。设计模式对设计这种框架非 |
|
|
|
|