Java 中数据的读写与 XML 处理
1. 使用 JDBC 读写数据
在 Java 编程中,我们可以使用 Java 数据库连接(JDBC)或者 JDBC 与开放数据库连接(ODBC)的组合,将现有的数据存储解决方案集成到 Java 程序中。通过 JDBC 或 ODBC 以及结构化查询语言(SQL),可以将多种不同的关系型数据库集成到 Java 程序中。
以下是一些相关问题及解答:
|问题|选项|答案|
| ---- | ---- | ---- |
|在数据库程序中,Statement 对象代表什么?|a. 与数据库的连接
b. 用结构化查询语言编写的数据库查询
c. 数据源|b. 该类是 java.sql 包的一部分,代表一个 SQL 语句。|
|Java 2 SDK 1.4 不包含哪种驱动程序?|a. JDBC 驱动程序
b. JDBC - ODBC 驱动程序
c. 两者|a. 许多关系型数据库程序包含 JDBC 驱动程序,但在编写本文时,SDK 未附带该驱动程序。|
|哪个 Java 类代表在执行前编译的 SQL 语句?|a. Statement
b. PreparedStatement
c. ResultSet|b. 由于 PreparedStatement 是编译后的,当你要多次执行相同的 SQL 查询时,它是更好的选择。|
此外,还有一个认证练习题:
public class ArrayClass {
public static ArrayClass newInstance() {
count++;
return new ArrayClass();
}
public static void main(String arguments[]) {
new ArrayClass();
}
int count = -1;
}
问:此程序中哪一行会阻止其成功编译?
选项:
a. count++;
b. return new ArrayClass();
c. public static void main(String arguments[]) {
d. int count = -1;
答案可在相关网站查询。
为了扩展对这些主题的了解,还可以尝试以下练习:
- 修改 CoalTotals 应用程序,从“Country Oil Totals”表而不是“Coal”表中提取字段。
- 编写一个使用图形用户界面的应用程序,通过 ODBC 或 JDBC 将用户输入保存到关系型数据库中。
2. XML 数据的读写
Java 的一个主要卖点是其程序可以在不同的操作系统上无需修改即可运行。大约在 Java 推出 18 个月后,一种用于数据的可移植标准——可扩展标记语言(XML)被引入。XML 使数据能够完全可移植,不同操作系统上的不同软件可以读取和写入数据,而不会出现兼容性问题。
2.1 使用 XML
XML 是一种用于存储和组织数据的格式,它独立于处理该数据的任何软件程序。符合 XML 的数据更易于重用,原因如下:
-
数据结构化
:数据以标准方式结构化,只要软件程序支持 XML,就可以读取和写入数据。例如,创建一个代表公司员工数据库的 XML 文件,有几十个 XML 解析器可以读取该文件并理解其内容,无论数据库包含哪些员工信息。
-
自文档化
:数据是自文档化的,人们只需在文本编辑器中查看文件,就可以理解文件的用途。例如下面的 XML 文件示例:
<?xml version="1.0"?>
<!DOCTYPE Library SYSTEM "librml.dtd">
<Library>
<Book>
<Author>Joseph Heller</Author>
<Title>Catch-22</Title>
<PublicationDate edition="Trade" isbn="0684833395">09/1996</PublicationDate>
<Publisher>Simon and Schuster</Publisher>
<Subject>Fiction</Subject>
<Review>heller-catch22.html</Review>
</Book>
<Book>
<Author>Kurt Vonnegut</Author>
<Title>Slaughterhouse-Five</Title>
<PublicationDate edition="Paperback" isbn="0440180295">12/1991</PublicationDate>
<Publisher>Dell</Publisher>
<Subject>Fiction</Subject>
</Book>
</Library>
XML 文件以
<?xml>
标签开头,该标签有一个版本属性。数据被标签元素包围,标签可以嵌套,形成 XML 数据的层次结构。XML 还支持单标签元素,标签元素可以包含属性。
XML 的开发动机之一是 HTML 的不一致性。HTML 是一种广泛用于向用户呈现数据的方式,但网页设计师经常不遵循 HTML 的所有规则,而网页浏览器仍然可以正常加载页面。这给收集网页数据和与互联网服务交互的软件开发者带来了问题。
2.2 设计 XML 方言
XML 实际上是一种定义如何定义标记语言的标记语言。“X”代表可扩展,意味着可以根据自己的目的组织数据。例如:
- 电话营销公司的程序员可以使用 XML 存储每个外拨电话的数据,包括通话时间、号码、操作员和结果。
- 业余爱好者可以使用 XML 记录收到的烦人电话营销信息,包括通话时间、公司和推销的产品。
- 政府机构的程序员可以使用 XML 跟踪对电话营销人员的投诉,包括营销公司的名称和投诉数量。
当创建新的 XML 方言时,正式的定义方式是创建文档类型定义(DTD)。例如,下面是一个图书数据库的 DTD:
<!ELEMENT Library (Book?)+ >
<!ELEMENT Book (Author?, Title, PublicationDate?, Publisher?, Subject?, Review?)* >
<!ELEMENT Author (#PCDATA)>
<!ELEMENT Title (#PCDATA)>
<!ELEMENT PublicationDate (#PCDATA)>
<!ATTLIST PublicationDate edition CDATA "" isbn CDATA "">
<!ELEMENT Publisher (#PCDATA)>
<!ELEMENT Subject (#PCDATA)>
<!ELEMENT Review (#PCDATA)>
在 XML 文件中,可以使用
<!DOCTYPE>
标签来标识应用于数据的 DTD。当存在 DTD 时,许多 XML 工具可以读取为该 DTD 创建的 XML 并确定数据是否遵循所有规则,这个过程称为验证 XML。
下面是一个使用 mermaid 绘制的流程图,展示了 XML 数据处理的基本流程:
graph LR
A[开始] --> B[创建 XML 文件]
B --> C[定义 DTD]
C --> D[编写 XML 数据]
D --> E[验证 XML 数据]
E --> F[使用 Java 处理 XML 数据]
F --> G[结束]
3. 使用 Java 处理 XML
随着 Java 2 版本 1.4 的发布,Sun Microsystems 使对 XML 的支持成为 Java 类库的标准部分。通过 Java 应用程序编程接口(API)进行 XML 处理,这是一组用于读取、写入和操作 XML 数据的 Java 类,目前版本为 1.1。
Java API for XML Processing 包括九个包:
- javax.xml.parsers
- javax.xml.transform
- javax.xml.transform.dom
- javax.xml.transform.sax
- javax.xml.transform.stream
- org.w3c.dom
- org.xml.sax
- org.xml.sax.ent
- org.xml.sax.helpers
其中,javax.xml.parsers 包是所有其他包的入口点,可以使用该包中的类通过两种技术解析和验证 XML 数据:简单 XML API(SAX)和文档对象模型(DOM)。
3.1 读取 XML 文件
使用 SAX 和 javax.xml.parsers 包解析 XML 文件的步骤如下:
1. 创建一个 SAXParserFactory 对象:
SAXParserFactory factory = SAXParserFactory.newInstance();
- 设置是否使用 DTD 验证 XML:
factory.setValidating(true);
- 创建一个 SAXParser 对象:
SAXParser sax = factory.newSAXParser();
- 调用解析方法:
sax.parse(File, DefaultHandler);
这个方法可能会抛出 IOException 和 SAXException 异常。
DefaultHandler 类是一个空操作类,实现了 org.xml.sax 包的四个接口:ContentHandler、DTDHandler、EntityResolver 和 ErrorHandler。为了处理 XML 数据,可以创建 DefaultHandler 的子类并覆盖所需的方法。
3.2 统计 XML 标签
以下是一个 Java 应用程序 CountTag,用于统计 XML 文件中起始标签元素出现的次数:
import javax.xml.parsers.*;
import org.xml.sax.*;
import org.xml.sax.helpers.*;
import java.io.*;
public class CountTag extends DefaultHandler {
public static void main(String[] arguments) {
if (arguments.length > 1) {
CountTag ct = new CountTag(arguments[0], arguments[1]);
} else {
System.out.println("Usage: java CountTag filename tagName");
}
}
CountTag(String xmlFile, String tagName) {
File input = new File(xmlFile);
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setValidating(false);
try {
SAXParser sax = factory.newSAXParser();
CountTagHandler cth = new CountTagHandler(tagName);
sax.parse(input, cth);
System.out.println("The " + cth.tag + " tag appears " + cth.count + " times.");
} catch (ParserConfigurationException pce) {
System.out.println("Could not create that parser.");
System.out.println(pce.getMessage());
} catch (SAXException se) {
System.out.println("Problem with the SAX parser.");
System.out.println(se.getMessage());
} catch (IOException ioe) {
System.out.println("Error reading file.");
System.out.println(ioe.getMessage());
}
}
}
class CountTagHandler extends DefaultHandler {
String tag;
int count = 0;
CountTagHandler(String tagName) {
super();
tag = tagName;
}
public void startElement(String uri, String localName, String qName, Attributes attributes) {
if (qName.equals(tag))
count++;
}
}
如果 CountTag.class 和 collection.librml 在同一文件夹中,可以使用以下命令运行:
java CountTag collection.librml Book
输出应该是:
The Book tag appears 2 times.
3.3 读取 XML 数据
从 XML 标签中检索数据是一个三步过程:
1. 覆盖 startElement() 方法,以了解何时解析新的起始标签。
2. 覆盖 characters() 方法,以了解标签包含的内容。
3. 覆盖 endElement() 方法,以了解何时到达结束标签。
例如,下面是一个覆盖 characters() 方法的示例:
public void characters(char[] text, int first, int length) {
String data = new String(text, first, length);
System.out.println(data);
}
3.4 验证 XML 数据
最后,有一个名为 ReadLibrary 的 Java 应用程序,用于读取使用前面介绍的方言创建的 XML 文件。该应用程序使用验证解析器,因为有对应的 DTD。以下是其完整代码:
import javax.xml.parsers.*;
import org.xml.sax.*;
import org.xml.sax.helpers.*;
import java.io.*;
public class ReadLibrary extends DefaultHandler {
public static void main(String[] arguments) {
if (arguments.length > 0) {
ReadLibrary read = new ReadLibrary(arguments[0]);
} else {
System.out.println("Usage: java ReadLibrary filename");
}
}
ReadLibrary(String libFile) {
File input = new File(libFile);
SAXParserFactory factory = SAXParserFactory.newInstance();
factory.setValidating(true);
try {
SAXParser sax = factory.newSAXParser();
sax.parse(input, new LibraryHandler());
} catch (ParserConfigurationException pce) {
System.out.println("Could not create that parser.");
System.out.println(pce.getMessage());
} catch (SAXException se) {
System.out.println("Problem with the SAX parser.");
System.out.println(se.getMessage());
} catch (IOException ioe) {
System.out.println("Error reading file.");
System.out.println(ioe.getMessage());
}
}
}
class LibraryHandler extends DefaultHandler {
static int READING_TITLE = 1;
static int READING_AUTHOR = 2;
static int READING_PUBLISHER = 3;
static int READING_PUBLICATION_DATE = 4;
static int READING_SUBJECT = 5;
static int READING_REVIEW = 6;
static int READING_NOTHING = 0;
int currentActivity = READING_NOTHING;
Book libraryBook = new Book();
LibraryHandler() {
super();
}
public void startElement(String uri, String localName, String qName, Attributes attributes) {
if (qName.equals("Title"))
currentActivity = READING_TITLE;
else if (qName.equals("Author"))
currentActivity = READING_AUTHOR;
else if (qName.equals("Publisher"))
currentActivity = READING_PUBLISHER;
else if (qName.equals("PublicationDate"))
currentActivity = READING_PUBLICATION_DATE;
else if (qName.equals("Subject"))
currentActivity = READING_SUBJECT;
else if (qName.equals("Review"))
currentActivity = READING_REVIEW;
if (currentActivity == READING_PUBLICATION_DATE) {
libraryBook.isbn = attributes.getValue("isbn");
libraryBook.edition = attributes.getValue("edition");
}
}
public void characters(char[] ch, int start, int length) {
String value = new String(ch, start, length);
if (currentActivity == READING_TITLE)
libraryBook.title = value;
if (currentActivity == READING_AUTHOR)
libraryBook.author = value;
if (currentActivity == READING_PUBLISHER)
libraryBook.publisher = value;
if (currentActivity == READING_PUBLICATION_DATE)
libraryBook.publicationDate = value;
if (currentActivity == READING_SUBJECT)
libraryBook.subject = value;
if (currentActivity == READING_REVIEW)
libraryBook.review = value;
}
public void endElement(String uri, String localName, String qName) {
if (qName.equals("Book")) {
System.out.println("\nTitle: " + libraryBook.title);
System.out.println("Author: " + libraryBook.author);
System.out.println("Publisher: " + libraryBook.publisher);
System.out.println("Publication Date: " + libraryBook.publicationDate);
System.out.println("Edition: " + libraryBook.edition);
System.out.println("ISBN: " + libraryBook.isbn);
System.out.println("Review: " + libraryBook.review);
libraryBook = new Book();
}
}
}
class Book {
String title;
String author;
String publisher;
String publicationDate;
String edition;
String isbn;
String subject;
String review;
}
这个应用程序通过一系列步骤,从 XML 文件中读取图书信息并显示出来,为我们展示了如何在 Java 中有效地处理和验证 XML 数据。
Java 中数据的读写与 XML 处理
4. 总结与拓展
在前面的内容中,我们详细探讨了使用 JDBC 读写数据以及使用 Java 处理 XML 数据的相关知识。下面我们对这些内容进行总结,并探讨一些拓展应用。
4.1 知识总结
| 技术领域 | 关键知识点 |
|---|---|
| JDBC 读写数据 |
- 使用 JDBC 或 JDBC 与 ODBC 组合集成现有数据存储解决方案到 Java 程序。
- 理解 Statement、PreparedStatement 等类的作用。 - 解答了关于 JDBC 驱动程序和数据库程序中对象代表含义的常见问题。 |
| XML 基础 |
- XML 是独立于软件程序的数据存储和组织格式,具有数据结构化和自文档化的优点。
- 可以设计 XML 方言,通过创建 DTD 来定义规则。 - XML 标签有起始标签、结束标签和单标签,标签可嵌套且能包含属性。 |
| Java 处理 XML |
- Java 2 版本 1.4 使 XML 支持成为标准,通过 Java API for XML Processing 进行处理。
- 使用 SAX 解析 XML 文件,包括创建解析器工厂、解析器,处理异常等步骤。 - 统计 XML 标签、读取 XML 数据和验证 XML 数据的具体实现方法。 |
4.2 拓展应用
-
数据交换
:XML 可用于不同系统之间的数据交换。例如,在企业级应用中,不同部门的系统可能使用不同的数据库和编程语言,但可以通过 XML 格式进行数据传输和共享。具体操作步骤如下:
- 确定需要交换的数据内容和结构。
- 根据数据结构创建相应的 XML 文档和 DTD(可选)。
- 使用 Java 程序将数据转换为 XML 格式。
- 通过网络传输 XML 文件到目标系统。
- 目标系统使用 Java 程序解析 XML 文件,提取所需数据。
-
配置文件管理
:许多 Java 应用程序使用 XML 文件作为配置文件。例如,Web 应用程序的配置文件通常使用 XML 格式,包含数据库连接信息、Servlet 映射等。使用 XML 作为配置文件的好处是易于阅读和修改。操作步骤如下:
- 创建 XML 配置文件,定义所需的配置项和结构。
- 在 Java 程序中使用 SAX 或 DOM 解析器读取配置文件。
- 根据配置文件中的信息进行相应的配置和初始化。
下面是一个简单的 mermaid 流程图,展示了数据交换的基本流程:
graph LR
A[源系统] --> B[生成 XML 数据]
B --> C[传输 XML 文件]
C --> D[目标系统]
D --> E[解析 XML 数据]
E --> F[使用数据]
5. 常见问题解答
在使用 JDBC 和处理 XML 数据的过程中,可能会遇到一些常见问题,下面为大家解答:
5.1 JDBC 相关问题
-
JDBC - ODBC 桥驱动能否在 applet 中使用?
默认情况下,applet 的安全机制不允许使用 JDBC - ODBC 桥,因为桥驱动的 ODBC 端使用本地代码而非 Java 代码,无法保证其安全性。完全用 Java 实现的 JDBC 驱动可以在 applet 中使用,并且无需在客户端计算机上进行配置。 -
Java 2 SDK 1.4 不包含哪种驱动程序?
Java 2 SDK 1.4 不包含 JDBC 驱动程序,许多关系型数据库程序会包含自己的 JDBC 驱动,但 SDK 本身在编写时未附带。
5.2 XML 相关问题
-
没有 DTD 的 XML 数据能否处理?
可以处理。即使 XML 数据没有使用 DTD 定义,只要数据格式正确(格式良好),就可以使用解析器进行解析。但无法验证数据是否符合特定的规则。 -
如何处理 XML 解析过程中的异常?
在使用 SAX 解析 XML 文件时,可能会抛出 ParserConfigurationException、SAXException 和 IOException 等异常。可以使用 try - catch 块捕获这些异常,并进行相应的处理,如输出错误信息。例如:
try {
SAXParser sax = factory.newSAXParser();
sax.parse(input, handler);
} catch (ParserConfigurationException pce) {
System.out.println("Could not create that parser.");
System.out.println(pce.getMessage());
} catch (SAXException se) {
System.out.println("Problem with the SAX parser.");
System.out.println(se.getMessage());
} catch (IOException ioe) {
System.out.println("Error reading file.");
System.out.println(ioe.getMessage());
}
6. 实践建议
为了更好地掌握这些知识,建议大家进行以下实践:
-
编写练习程序
:按照前面介绍的示例代码,自己动手编写一些练习程序,如修改现有程序的功能、处理不同格式的 XML 文件等。
-
参与开源项目
:查找一些使用 JDBC 和 XML 技术的开源项目,参与其中,学习他人的代码和实践经验。
-
阅读官方文档
:深入阅读 Java API for XML Processing 和 JDBC 的官方文档,了解更多的类和方法的使用。
通过不断的实践和学习,相信大家能够熟练掌握 Java 中数据的读写和 XML 处理技术,为开发更复杂的应用程序打下坚实的基础。
超级会员免费看
170万+

被折叠的 条评论
为什么被折叠?



