270 likes | 380 Views
第八章. XML 和数据库. 课程目标. XML 的应用领域 XML 导入数据库 XML 导出数据库. 体验项目 ——< 将关于员工和客户信息的 XML 导入数据库 >. 将如下文档中的员工信息解析出来存入 company 数据库中的 employee 表中,将顾客信息解析出来存入 company 数据库中的 buyer 表中:. <?xml version="1.0" encoding="UTF-8"?> <company> <employee> <person id="DE001"> <name> 张三 </name>
E N D
第八章 XML和数据库
课程目标 • XML的应用领域 • XML导入数据库 • XML导出数据库
体验项目——<将关于员工和客户信息的XML导入数据库 > 将如下文档中的员工信息解析出来存入company 数据库中的employee表中,将顾客信息解析出来存入company 数据库中的buyer表中: <?xml version="1.0" encoding="UTF-8"?> <company> <employee> <person id="DE001"> <name>张三</name> <age>40</age> <pay>1800</pay> </person> <person id="DE002"> <name>小王</name> <age>20</age> <pay>1500</pay> </person> <person id="DE003"> <name>小周</name> <age>30</age> <pay>2000</pay> </person> </employee> 员工信息
<buyer> <person id="BY001"> <name>Marry</name> <age>33</age> <phone>13451348641</phone> <email>marrymm@163.com</email> </person> <person id="BY002"> <name>Sandenly</name> <age>20</age> <phone>13015252569</phone> <email>sandenlygg@163.com</email> </person> </buyer> </company> 顾客信息
XML的应用领域 XML的应用可以分为以下几个方面: 应用于数据转换 XML成为一种各种程序都能自动理解和处理数据的规范。 应用于将大量运算分布在客户端进行,以减少服务器的负载 客户可以根据自己的需求选择和制作不同的应用程序来处理数据,而服务器只须发出同一个XML文件 应用于将同一数据以不同的面貌展现给不同的用户 使用XML可以使得数据源与显示分离。这一应用将会使得网络用户界面趋向个性化、风格化。 XML应用于网络代理 同一个XML可以被多个用户进行编辑、增减以适应该用户的需要 ,类似于设置权限 。
XML导出数据库 XML导出单个表的数据 以SQL Server数据库为例,在一个名为“mydb”的数据库中,有一张关于person信息的表“mytable”,字段信息 和数据信息 如下: 字段信息表 数据信息表
import java.sql.*; import javax.xml.parsers.*; import org.apache.crimson.tree.*; import org.w3c.dom.*; import java.io.*; public class DBtoXML1{ static Connection con; public static void main(String args[ ]){ Document doc; try{ //建立数据库连接 String classforname= "com.microsoft.jdbc.sqlserver.SQLServerDriver"; String url="jdbc:microsoft:sqlserver://localhost:1433;" + "databasename=mydb"; Class.forName(classforname); Connection con=DriverManager.getConnection(url,"sa",""); Statement sta=con.createStatement(); ResultSet result=sta.executeQuery( "SELECT * FROM mytable"); //获取Document实例 DocumentBuilderFactory dbf= DocumentBuilderFactory.newInstance(); DocumentBuilder builder=dbf.newDocumentBuilder(); doc=builder.newDocument();
//创建根节点 Element people=doc.createElement("people"); while (result.next()) { Element person=doc.createElement("person"); people.appendChild(person); Element name=doc.createElement("name"); /* 获取数据库中name字段的值, 并作为xml文档中name元素的字符数据*/ name.appendChild(doc.createTextNode( result.getString("name"))); person.appendChild(name); Element age=doc.createElement("age"); age.appendChild(doc.createTextNode( result.getInt("age")+"")); person.appendChild(age); Element addr=doc.createElement("address"); addr.appendChild(doc.createTextNode( result.getString("address"))); person.appendChild(addr); Element phone=doc.createElement("phone"); phone.appendChild(doc.createTextNode( result.getString("phone"))); person.appendChild(phone); }
doc.appendChild(people); //将dom树导出到文件中 ((XmlDocument)doc).write( new FileOutputStream(new File("person.xml"))); }catch(Exception e){e.printStackTrace();} } } 程序运行完成后,使用记事本打开“person.xml”文件
XML导出多个表关联的数据 如“mydb”库中有表“mytable1”和“mytable2”,他们之间通过外键“personid”而相约束, 如下: 表mytable1字段信息 表mytable1数据信息 表mytable2字段信息 表mytable2字段信息
import java.sql.*; import javax.xml.parsers.*; import org.apache.crimson.tree.*; import org.w3c.dom.*; import java.io.*; public class DBtoXML2{ static Connection con; public static void main(String args[ ]){ Document doc; try{ //连接数据库 String classforname="com.microsoft.jdbc.sqlserver.SQLServerDriver"; String url="jdbc:microsoft:sqlserver://localhost:1433; " +"databasename=mydb"; Class.forName(classforname); Connection con=DriverManager.getConnection(url,"sa",""); Statement sta=con.createStatement(); ResultSet result=sta.executeQuery( "SELECT * FROM mytable1"); //获取Document实例 DocumentBuilderFactory dbf= DocumentBuilderFactory.newInstance(); DocumentBuilder builder=dbf.newDocumentBuilder(); doc=builder.newDocument(); Element people=doc.createElement("people");
while (result.next()){ Element person=doc.createElement("person"); String str=result.getString("personid"); person.setAttribute("id",str); people.appendChild(person); Element username=doc.createElement("username"); username.appendChild( doc.createTextNode(result.getString("username"))); person.appendChild(username); Element pass=doc.createElement("password"); pass.appendChild( doc.createTextNode(result.getString("password"))); person.appendChild(pass); //查询表mytable2并向XML文档中添加元素和字符数据 ResultSet rs=con.createStatement().executeQuery( "SELECT * FROM mytable2" + "where personid='"+str+"'"); while (rs.next()){ Element uname=doc.createElement("uname"); uname.appendChild( doc.createTextNode(rs.getString("uname"))); person.appendChild(uname); Element age=doc.createElement("age"); age.appendChild( doc.createTextNode(rs.getInt("age")+"")); person.appendChild(age);
Element addr=doc.createElement("address"); addr.appendChild( doc.createTextNode(rs.getString("address"))); person.appendChild(addr); Element phone=doc.createElement("phone"); phone.appendChild( doc.createTextNode(rs.getString("phone"))); person.appendChild(phone); } } doc.appendChild(people); ((XmlDocument)doc).write(new FileOutputStream(new File("person2.xml"))); }catch(Exception e){e.printStackTrace();} } } 程序运行完成后用记事本打开person2.xml
XML导入数据库 将简单的XML文档导入数据库 <?xml version="1.0" encoding="UTF-8"?> <people> <person id="a001"> <username>aa</username> <password>12345</password> <uname>张三</uname> <age>20</age> <address>北京</address> <phone>12461238</phone> </person> <person id="a002"> <username>bb</username> <password>987562</password> <uname>李四</uname> <age>22</age> <address>北京</address> <phone>98421354</phone> </person> </people> 需要导入数据库的XML文档person.xml
文档中有多个“person”元素,每个“person”元素包括一个属性和六个子元素,而这六个子元素除了有字符数据外,并不包含其他的任何子元素。经过分析,可以考虑将“person”元素对应到数据库中的一个表,而把它所包括的属性和子元素作为该表的字段,如下: “person”表的字段信息
import java.sql.*; import javax.xml.parsers.*; import org.apache.crimson.tree.*; import org.w3c.dom.*; import java.io.*; public class XMLtoDB1{ public static void main(String args[ ]){ String id,username,password,uname,address,phone,sql,agestr; int age; try{ //建立数据库连接 String classforname= "com.microsoft.jdbc.sqlserver.SQLServerDriver"; String url= "jdbc:microsoft:sqlserver://localhost:1433;" +"databasename=mydb"; Class.forName(classforname); Connection con=DriverManager.getConnection(url,"sa",""); //获取Document实例 DocumentBuilderFactory factory= DocumentBuilderFactory.newInstance(); DocumentBuilder builder=factory.newDocumentBuilder(); Document doc= builder.parse( new FileInputStream(new File("person.xml")));
NodeList nodes=doc.getElementsByTagName("person"); for(int i=0;i<nodes.getLength();i++){ Element node=(Element)nodes.item(i); id=node.getAttributes().getNamedItem("id").getNodeValue(); username= node.getElementsByTagName("username"). item(0).getFirstChild().getNodeValue(); password= node.getElementsByTagName("password"). item(0).getFirstChild().getNodeValue(); uname= node.getElementsByTagName("uname"). item(0).getFirstChild().getNodeValue(); agestr= node.getElementsByTagName("age"). item(0).getFirstChild().getNodeValue(); age=Integer.parseInt(agestr); address= node.getElementsByTagName("address"). item(0).getFirstChild().getNodeValue(); phone= node.getElementsByTagName("phone"). item(0).getFirstChild().getNodeValue(); //向数据库中添加数据 sql="insert into person values('"+id+"','"+username +"','"+password+"',"+"'"+uname+"','"+age +"','"+address+"','"+phone+"')"; con.createStatement().executeUpdate(sql); } }catch(Exception e){e.printStackTrace();} } }
将XML映射到数据库` 主要形式有: 基于表的映射 基于对象的映射 基于表的映射 所谓基于表的映射是指可以把文档看成一个单一的表或单一的组表。
基于表的映射 基于表映射的文档的结构必须是如下所示的两种类型的结构: 第一种: 第二种: 可以将文档看成是一个由一组表组成的库 <table> <row> <column1></column1> <columnn></columnn> </row> <row> <column1></column1> <columnn></columnn> </row> </table> <tables> <table1> <row> <column1></column1> <columnn></columnn> </row> </table1> <tablen> <row> <column1></column1> <columnm></columnm> </row> </tablen> </tables> 可以将文档看成是一个单一的表
基于表的映射的优缺点 这种映射的优点是它的简单性。因为它匹配在关系数据库中的表和结果集的结构非常简单,基于这种映射的XML和数据库转换的代码很容易编写,并对特定应用非常有用,比如在数据库之间一次只牵扯到一个表的数据传输。 这种映射有许多缺点,最显著的是它只能处理XML文档的非常小的节点集。
基于对象的映射 所谓基于对象的映射可以简单的理解为“对象与关系”,这种映射通常与关系数据库一起使用。该映射主要用于XML模式(主要指DTD)到数据库模式的映射。即将DTD先映射为对象模式,再由对象模式到数据库模式。 主要分为: 映射元素 映射属性
映射元素 映射元素首先将简单的元素类型映射为基本的数据类型,然后再将复杂的元素类型映射为类(class),该复杂元素类型中的简单元素类型相应的映射为该类的属性(变量)。 如下: 映射为对象模式 class Check{ CD cd; //一个CD类对象 } class CD { String title; String artist; String country; } <!ELEMENT Check (CD)> <!ELEMENT CD (title,artist,country)> <!ELEMENT title (#PCDATA)> <!ELEMENT artist (#PCDATA)> <!ELEMENT country (#PCDATA)> 映射为数据库模式 将Check类映射为库,将CD类映射为该库中的表,或者将Check类和CD类都映射为表,而用主键、外键将这两个表关联。将变量“title”、“artist”和“country”映射为该表中的字段。
对操作符的映射 如果一个DTD语句中提供了“+”或“*”操作符,则需要把该元素类型作为复杂类型,并将其映射成一个数组变量,它是一个未知大小的数组。这个数组也必须被映射成一个表,它将为每个值包含一行。通过主键、外键联系将该表与其他的表建立关系。 如下: 映射为对象模式 class A{ String[ ] b; String c; String d; } <!ELEMENT A (B+, C,D)> <!ELEMENT B (#PCDATA)> <!ELEMENT C (#PCDATA)> <!ELEMENT D (#PCDATA)> 映射为数据库模式 Table A: Column a_pk Column c Column d Table B: Column a_fk Column b
映射属性 CDATA、ID、IDREF、NMTOKEN、ENTITY、NOTATION和枚举这七种属于单值,通常将其映射为类中的变量,然后再映射到数据库中表的字段。 IDREFS、 NMTOKENS和ENTITIES这三种类型的属性可以是多值。通常将其映射为类中的数组变量,然后再映射到数据库中的表。 注意:有些文档使用ENTITY 和ENTITIES 属性把未分析的、外部数据(比如一个二进制文件)与XML 文档关联起来。在对它们映射时同任何其他属性一样,不同的是,在传输数据的时候,必须用实体替换属性值(在从XML传输数据到数据库的时候)。
ID和IDREF或IDREFS属性的映射 在数据库中一般使用主键和外键将其关联,如下: 数据库中表和字段信息 <A> <B id="1"></B> <C ref_id="1"></C> <D ref_id="1"></D> </A> Table A: Column a_pk Table B: Column a_fk Column ref_id Table C: Column a_fk Column ref_id Table D: Column a_fk Column id XML文档
实践项目——<将关于员工和客户信息的XML导入数据库 > 程序的实现要求如下: (1)创建两个表。 (2)使用DOM分别解析employee元素和buyer元素。
本章总结 • XML的应用领域 • XML导入数据库 • XML导出数据库