1.?? 在業務層使用JDBC直接操作數據庫-最簡單,最直接的操作
1)數據庫url,username,password寫死在代碼中
????Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
????String url="jdbc:oracle:thin:@localhost:1521:orcl";
????String user="scott";
????String password="tiger";
????Connection conn= DriverManager.getConnection(url,user,password);??
????Statement stmt=conn.createStatement(
ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
????String sql="select * from test";
????ResultSet rs=stmt.executeQuery(sql);
2)采用Facade和Command模式,使用DBUtil類封裝JDBC操作;
??????數據庫url,username,password可以放在配置文件中(如xml,properties,ini等)。
??????這種方法在小程序中應用較多。
2.DAO(Data Accessor Object)模式-松耦合的開始
DAO = data + accessor + domain object
例如User類-domain object (javabean)
UserDAO類-accessor ,提供的方法getUser(int id),save(User user)內包含了JDBC操作
在業務邏輯中使用這兩個類來完成數據操作。
使用Factory模式可以方便不同數據庫連接之間的移植。
3.數據庫資源管理模式
3.1 數據庫連接池技術
資源重用,避免頻繁創建,釋放連接引起大大量性能開銷;
更快的系統響應速度;
通過實現JDBC的部分資源對象接口( Connection, Statement, ResultSet ),可以使用Decorator設計模式分別產生三種邏輯資源對象: PooledConnection, PooledStatement和 PooledResultSet。
一個最簡單地數據庫連接池實現:
public class ConnectionPool {
?????? private static Vector pools;
?????? private final int POOL_MAXSIZE = 25;
?????? /**
????????* 獲取數據庫連接
????????* 如果當前池中有可用連接,則將池中最后一個返回;若沒有,則創建一個新的返回
????????*/
?????? public synchronized Connection getConnection() {
??????????????Connection conn = null;
??????????????if (pools == null) {
???????????????????? pools = new Vector();
??????????????}
??????????????if (pools.isEmpty()) {
???????????????????? conn = createConnection();
??????????????} else {
???????????????????? int last_idx = pools.size() - 1;
???????????????????? conn = (Connection) pools.get(last_idx);
???????????????????? pools.remove(last_idx);
??????????????}
??????????????return conn;
?????? }
?????? /**
????????* 將使用完畢的數據庫連接放回池中
????????* 若池中連接已經超過閾值,則關閉該連接;否則放回池中下次再使用
????????*/
?????? public synchronized void releaseConnection(Connection conn) {
??????????????if (pools.size() >= POOL_MAXSIZE)
???????????????????? try {
????????????????????????????conn.close();
???????????????????? } catch (SQLException e) {
????????????????????????????// TODO自動生成 catch 塊
????????????????????????????e.printStackTrace();
???????????????????? } else
???????????????????? pools.add(conn);
?????? }
?????? public static Connection createConnection() {
??????????????Connection conn = null;
??????????????try {
???????????????????? Class.forName("oracle.jdbc.driver.OracleDriver").newInstance();
???????????????????? String url = "jdbc:oracle:thin:@localhost:1521:orcl";
???????????????????? String user = "scott";
???????????????????? String password = "tiger";
???????????????????? conn = DriverManager.getConnection(url, user, password);
??????????????} catch (InstantiationException e) {
???????????????????? // TODO自動生成 catch 塊
???????????????????? e.printStackTrace();
??????????????} catch (IllegalAccessException e) {
???????????????????? // TODO自動生成 catch 塊
???????????????????? e.printStackTrace();
??????????????} catch (ClassNotFoundException e) {
???????????????????? // TODO自動生成 catch 塊
???????????????????? e.printStackTrace();
??????????????} catch (SQLException e) {
???????????????????? // TODO自動生成 catch 塊
???????????????????? e.printStackTrace();
??????????????}
??????????????return conn;
?????? }
}
注意:利用getConnection()方法得到的Connection,程序員很習慣地調用conn.close()方法關閉了數據庫連接,那么上述的數據庫連接機制便形同虛設。在調用conn.close()方法方法時如何調用releaseConnection()方法?這是關鍵。這里,我們使用Proxy模式和java反射機制。
public synchronized Connection getConnection() {
??????????????Connection conn = null;
??????????????if (pools == null) {
???????????????????? pools = new Vector();
??????????????}
??????????????if (pools.isEmpty()) {
???????????????????? conn = createConnection();
??????????????} else {
???????????????????? int last_idx = pools.size() - 1;
???????????????????? conn = (Connection) pools.get(last_idx);
???????????????????? pools.remove(last_idx);
??????????????}
????????
????????ConnectionHandler handler=new ConnectionHandler(this);
??????????????return handler.bind(con);
?????? }
public class ConnectionHandler implements InvocationHandler {
???? private Connection conn;
???? private ConnectionPool pool;
????
???? public ConnectionHandler(ConnectionPool pool){
????????????this.pool=pool;
???? }
????
???? /**
??????* 將動態代理綁定到指定Connection
??????* @param conn
??????* @return
??????*/
???? public Connection bind(Connection conn){
????????????this.conn=conn;
Connection proxyConn=(Connection)Proxy.newProxyInstance(
conn.getClass().getClassLoader(), conn.getClass().getInterfaces(),this);
??????????return proxyConn;
???? }
????
?????? /* (非 Javadoc)
????????* @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
????????*/
?????? public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
??????????????// TODO自動生成方法存根
??????????????Object obj=null;
??????????????if("close".equals(method.getName())){
???????????????????? this.pool.releaseConnection(this.conn);
??????????????}
??????????????else{
???????????????????? obj=method.invoke(this.conn, args);
??????????????}
??????????????
??????????????return obj;
?????? }
}
??????在實際項目中,并不需要你來從頭開始來設計數據庫連接池機制,現在成熟的開源項目,如C3P0,dbcp,Proxool等提供了良好的實現。一般推薦使用Apache dbcp,基本使用實例:
DataSource ds = null;
?? try{
???? Context initCtx = new InitialContext();
???? Context envCtx = (Context) initCtx.lookup("java:comp/env");
???? ds = (DataSource)envCtx.lookup("jdbc/myoracle");
????????if(ds!=null){
????????????????out.println("Connection is OK!");
????????????????Connection cn=ds.getConnection();
????????????????if(cn!=null){
????????????????????????out.println("cn is Ok!");
????????????????Statement stmt = cn.createStatement();
???????????????? ResultSet rst = stmt.executeQuery("select * from BOOK");
????????????????out.println("<p>rst is Ok!" + rst.next());
????????????????while(rst.next()){
????????????????????????out.println("<P>BOOK_CODE:" + rst.getString(1));
??????????????????}
????????????????????????cn.close();
????????????????}else{
????????????????????????out.println("rst Fail!");
????????????????}
????????}
????????else
????????????????out.println("Fail!");
?????????? }catch(Exception ne){ out.println(ne);
???????? }
3.2 Statement Pool
普通預編譯代碼:
String strSQL=”select name from items where id=?”;
PreparedStatement ps=conn.prepareStatement(strSQL);
ps.setString(1, “2”);
ResultSet rs=ps.executeQuery();
但是PreparedStatement 是與特定的Connection關聯的,一旦Connection關閉,則相關的PreparedStatement 也會關閉。
為了創建PreparedStatement 緩沖池,可以在invoke方法中通過sql語句判斷池中還有沒有可用實例。
4. 持久層設計與O/R mapping 技術
1) Hernate:適合對新產品的開發,進行封閉化的設計
Hibernate 2003年被Jboss接管,通過把java pojo對象映射到數據庫的table中,采用了xml/javareflection技術等。3.0提供了對存儲過程和手寫sql的支持,本身提供了hql語言。
開發所需要的文件:
hibernate配置文件: hibernate.cfg.xml 或 hibernate.properties
hibernate 映射文件: a.hbm.xml
pojo類源文件: a.java
導出表與表之間的關系:
a. 從java對象到hbm文件:xdoclet
b. 從hbm文件到java對象:hibernate extension
c. 從數據庫到hbm文件:middlegen
d. 從hbm文件到數據庫:SchemaExport
2)Iatis :適合對遺留系統的改造和對既有數據庫的復用,有很強的靈活性 3) Apache OJB:優勢在于對標準的全面支持 4)EJB:適合集群服務器,其性能也不象某些人所詬病的那么差勁 5) JDO (java data object)
設置一個Properties對象,從而獲取一個JDO的PersistenceManagerFactory(相當于JDBC連接池中的DataSource),進而獲得一個PersistenceManager對象(相當于JDBC中的Connection對象),之后,你可以用這個PersistenceManager對象來增加、更新、刪除、查詢對象。
JDOQL是JDO的查詢語言;它有點象SQL,但卻是依照Java的語法的。
5. 基于開源框架的Struts+Spring+Hibernate實現方案
示例:這是一個3層架構的web 程序,通過一個Action 來調用業務代理,再通過它來回調 DAO類。下面的流程圖表示了MyUsers是如何工作的。數字表明了流程的先后順序,從web層(UserAction)到中間層(UserManager),再到數據層(UserDAO),然后返回。
Spring是AOP, UserManager和UserDAO都是接口.
1)?????? web層(UserAction) :調用中間層的接口方法,將UserManager作為屬性注入。
???????????? 采用流行的Struts框架,雖然有很多人不屑一顧,但是這項技術在業界用的比較普遍,能滿足基本的功能,可以減少培訓學習成本。
2)?????? 中間層(UserManager):將UserDAO作為屬性注入,其實現主要是調用數據層接口的一些方法;它處于事務控制中。
????????????采用Spring框架實現,IOC與AOP是它的代名詞,功能齊全,非常棒的一個架構。
3)?????? 數據層(UserDAO):實現類繼承HibernateDaoSupport類,在該類中可以調用getHibernateTemplate()的一些方法執行具體的數據操作。
????????????采用Hibernate做O/R mapping,從種種跡象可以看出,Hibernate就是EJB3.0的beta版。
Java總有它的千般好處使你選擇它,但這些隨便翻翻書或在網上逛一圈就能找到答案。在本文中,筆者把自己學習Java的一些切身體會和過程寫出來,供初學者做個參考。
我在學習Java的過程中主要圍繞以下幾個方面來學習:
1.時刻提醒自己Java是一種OOP語言工具,而不僅僅是編碼,只有這樣才能總體把握和運用Java。
2.在學習的過程中,最好能夠了解Java的底層機制,而不是僅僅停留在表層,不是抄書上的例子運行出結果就可以。要注意,即便對一個簡單的例子也要有耐心去琢磨、調試、改動。
3.在學習的過程中一定要動手做、寫代碼,而不是抱一本書看看就行。很多東西和體會必須自己動手才能真正屬于自己,最好能參與一些實際的項目。
4.在學到一定階段后,你開始希望用學過的東西做些什么。這時的你應該開始學習一些更多、更復雜的知識,比如J2EE平臺的構建、EJB的開發等。對于這一部分,我建議最好找一本較薄的書先了解一個大概,心里有個總體的認識,對更多的技術術語做個初步掌握。我認為這個階段看看《J2EE技術實踐》很不錯,它可以讓你了解J2EE包含的各種技術和框架,同時提供很多實際的例子來加深對J2EE的整體了解。
學習Java的興趣和決心起了很關鍵的作用。在有了上述基礎后,我便開始一步一步地學習Java。
Java環境的搭建
要運行Java程序,必須安裝JDK。JDK是整個Java的核心,其中包括了Java編譯器、JVM、大量的Java工具以及Java基礎API。
可以從http://Java.sun.com下載JDK,有1.4版本和1.31版本。我的學習環境中首先,采用的是1.31版本。
解壓安裝。然后,進行環境設置。
1.對于Windows平臺要進行以下設置:
set PATH=YOUR_INSTALL_ DIR\bin; C:\Windows;C:\Windows\Command
set classpath=. ;YOUR_INSTALL_DIR\lib\tools.jar
2.對于Linux平臺要編輯/etc/profile文件:
JAVA_HOME=your_install_dir/JDK/j2sdk
CLASSPATH=$JAVA_HOME/lib/tools.jar:$JAVA_HOME/lib/td.jar:$JAVA_HOME/jr??
-e/lib/rt.jar:.
PATH=$PATH:$JAVA_HOME/bin
export PATH PS1 USER LOGNAME MAIL HOSTNAME HISTSIZE HISTFILESIZE??
INPUTRC JAVA_HOME CLASSPATH RESIN_HOME
最后,在終端上輸入Java看能不能找到這個命令,如果能找到安裝就成功了。
下面介紹一下JDK的幾個重要的命令:
◆Java執行工具,是啟動JVM(虛擬機)并執行class(BYTE CODE)文件的命令;
◆javac 編譯器,由.java文件生成.class文件;
◆jar Java壓縮打包工具;
◆Javadoc 文檔生成器。
最后就是JDK Documentation,這是JDK的聯機幫助文檔,是最有用和最重要的學習參考文檔,應該多看。
開始寫自己的代碼
現在環境有了,應該寫個簡單的代碼進行測試了。還是從經典的“hello word”開始。
1. 先用編輯器寫一代碼(我用的是Linux的vi):
[stone@coremsg work]$ vi Hello.Java
??public class Hello{
????????public static void main(String []argc){
????????????????System.out.println("Hello Word!");
????????}
??}
2. 編譯:
[stone@coremsg work]$ Javac Hello.Java
3. 執行:
[stone@coremsg work]$ Java Hello
???? Hello Word!
成功了!這就是我的第一個Java程序。從那時起我知道已開始走進Java的世界,接下來就靠自己的努力了。在這個過程中,筆者認為有幾點需要注意。
學習一門新的語言,參考書是離不開的。我的建議是開始最好找一本篇幅較短的入門書來學習那些最簡單、最基本的東西,包括學習Java語法等。同時,對一個最簡單的程序也應該多去調試,多想想如果改動一下會出現什么結果?為什么必須那樣寫?多去想想這些問題然后去操作,會讓你有更多的收獲。這樣反復地思考是很有用的。此外,在這一階段還應該多看JDK的聯機幫助,盡量多地掌握JDK提供的Java基本類庫API。
在有一定基礎、能夠寫一些簡單的程序后,可以開始看《Thinking in Java》這本書。它比較完整地介紹了Java的語法、面向對象的特性、核心類庫等。通過這一層次的學習能夠加深對Java的理解和底層原理的運用,同時又可以完整地了解Java的整個體系。在這一階段,應該重點學習Java的面向對象編程語言的特性,比如繼承、構造器、抽象類、接口、方法的多態、重載、覆蓋、Java的異常處理機制等,要對上述概念有非常清楚的了解。這樣做的目的,是要讓自己把這些技術應用到實踐中進行合理的程序設計(比如,你會考慮一個類是用抽象還是接口來設計等)。這就要求必須在大量的實踐中去應用和學習。這也是當初很多朋友給我的建議。
學習更多
如果要用Java來完成各種功能更強大的任務,那么就要學習語言以外的更多的東西。
1.Java Web編程
對于Java Web 編程來說,應該而且必須熟悉和掌握HTTP協議,可以參考 Stevens的《TCP/IP 詳解》第三卷。Java Servlet技術提供了生成動態Web頁面內容的能力,這在你的Java項目中是最基本的功能之一,所以必須學習。通過這一階段的學習應該掌握Servlet/JSP的Web編程。
2. J2EE的學習
J2EE包含的技術太多了。如果你想坐在桌子旁邊抱著一大堆書來學習的話,效果不大的。我建議在開始這一階段的學習的時候,可以按以下步驟來做,總的思想是“總體把握,各個擊破”。
◆ 了解J2EE中的技術術語的含義。
我的感覺是J2EE標準中涉及到的各種技術很多,如果一開始就一個一個去學習的話是不現實的,也是沒效果的。我的建議是,先對其中的技術有個大概的了解,比如EJB、JavaIDL、JTA等。可能你不知道怎么去寫一個EJB,但是要知道什么是EJB、它能做什么,當有了這樣的概念后,再去有目的地學習它就會快很多。我還要再重復一句——必須要在實踐中動手去做才行。
◆ 了解J2EE中的設計模式,這樣能幫助你對J2EE做個整體把握。
MVC開發模式被證明是有效的處理方法之一。它可以分離數據訪問和數據表現。你可以開發一個有伸縮性的、便于擴展的控制器,來維護整個流程。通過這一層次的學習,當你面對一個項目的時候,應該首先把握它的總體架構的設計,以及決定采用J2EE標準中的哪些技術。
◆ 了解一些J2EE平臺的典型案列,加深對這一技術的概念和理解。
平時可以多留意這方面,熟悉一些典型案例,分析它為什么要采用那個時間?那樣做能達到什么樣的目的?然后聯系到自己身邊的項目是否可以作為參考。
◆ 學習J2EE下的各種技術。
在有了前幾階段的學習后,可以自己搭建一個J2EE平臺開始具體學習每一種技術。你可以參與公司相關項目進行學習,也可以自己搭建一個平臺進行學習。這時候應該找點相關的書來一步一步學習,沒有捷徑可走。如果你不滿足于這些,那么還應該更深入地學習UML、設計模式等方面的東西
別人對你說Thank you,你總是回答You're welcome嗎?
美國人有時回答“yeah”,非常短促的發音。
no problem
At your service (對女孩子一定要芥末說!!!)
My plessure
I am more than happy to do so.
在英國的回答大多是cheers mate。。或者直接就cheers。。既有謝謝的意思,又有不用謝的意思。。
no worries經常聽年輕人用
還有,美國人好像對thank u 的回答是uhun(很隨意,但是感覺多少有點不禮貌……)
一、關于XML解析
XML在Java應用程序里變得越來越重要, 廣泛應用于數據存儲和交換. 比如我們常見的配置文件,都是以XML方式存儲的. XML還應用于Java Message Service和Web Services等技術作為數據交換.
因此,正確讀寫XML文檔是XML應用的基礎.
Java提供了SAX和DOM兩種方式用于解析XML,但即便如此,要讀寫一個稍微復雜的XML,也不是一件容易的事.
二、XMLBean簡介
Hibernate已經成為目前流行的面向Java環境的對象/關系數據庫映射工具.
在Hibernate等對象/關系數據庫映射工具出現之前,對數據庫的操作是通過JDBC來實現的,對數據庫的任何操作,開發人員都要自己寫SQL語句來實現. 對象/關系數據庫映射工具出現后,對數據庫的操作轉成對JavaBean的操作,極大方便了數據庫開發. 所以如果有一個類似的工具能夠實現將對XML的讀寫轉成對JavaBean的操作,將會簡化XML的讀寫,即使對XML不熟悉的開發人員也能方便地讀寫XML. 這個工具就是XMLBean.
三、準備XMLBean和XML文檔
XMLBean是Apache的一個開源項目,可以從http://www.apache.org下載,最新的版本是2.0. 解壓后目錄如下:
xmlbean2.0.0
+---bin
+---docs
+---lib
+---samples
+---schemas
另外還要準備一個XML文檔(customers.xml),在本文的例子里,我們將對這個文檔進行讀寫操作. 文檔源碼如下:
<?xml version="1.0" encoding="UTF-8"?><Customers>
<customer>
<id>1</id>
<gender>female</gender>
<firstname>Jessica</firstname>
<lastname>Lim</lastname>
<phoneNumber>1234567</phoneNumber>
<address>
<primaryAddress>
<postalCode>350106</postalCode>
<addressLine1>#25-1</addressLine1>
<addressLine2>SHINSAYAMA 2-CHOME</
addressLine2>
</primaryAddress>
<billingAddress>
<receiver>Ms Danielle</receiver>
<postalCode>350107</postalCode>
<addressLine1>#167</addressLine1>
<addressLine2>NORTH TOWER HARBOUR CITY</addressLine2>
</billingAddress>
</address>
</customer>
<customer>
<id>2</id>
<gender>male</gender>
<firstname>David</firstname>
<lastname>Bill</lastname>
<phoneNumber>808182</phoneNumber>
<address>
<primaryAddress>
<postalCode>319087</postalCode>
<addressLine1>1033 WS St.</addressLine1>
<addressLine2>Tima Road</addressLine2>
</primaryAddress>
<billingAddress>
<receiver>Mr William</receiver>
<postalCode>672993</postalCode>
<addressLine1>1033 WS St.</addressLine1>
<addressLine2>Tima Road</addressLine2>
</billingAddress>
</address>
</customer></Customers>
這是一個客戶的數據模型,每個客戶都有客戶編號(ID),姓名,性別(gender),電話號碼(phoneNumber)和地址,其中地址有兩個: 首要地址(PrimaryAddress)和帳單地址(BillingAddress),每個地址有郵編,地址1,和地址2組成.其中帳單地址還有收件人(receiver).
此外,還要準備一個配置文件(文件名customer.xsdconfig),這個文件的作用我后面會講,它的內容如下:
<xb:config xmlns:xb="http://xml.apache.org/xmlbeans/2004/02/xbean/config">
<xb:namespace>
<xb:package>sample.xmlbean</xb:package>
</xb:namespace></xb:config>
四、XMLBean使用步驟
和其他面向Java環境的對象/關系數據庫映射工具的使用步驟一樣,在正式使用XMLBean前,我們要作兩個準備.
1. 生成XML Schema文件
什么是XML Schema文件? 正常情況下,每個XML文件都有一個Schema文件,XML Schema文件是一個XML的約束文件,它定義了XML文件的結構和元素.以及對元素和結構的約束. 通俗地講,如果說XML文件是數據庫里的記錄,那么Schema就是表結構定義.
為什么需要這個文件? XMLBean需要通過這個文件知道一個XML文件的結構以及約束,比如數據類型等. 利用這個Schema文件,XMLBean將會產生一系列相關的Java Classes來實現對XML的操作. 而作為開發人員,則是利用XMLBean產生的Java Classes來完成對XML的操作而不需要SAX或DOM.
怎樣產生這個Schema文件呢? 如果對于熟悉XML的開發人員,可以自己來寫這個Schema文件,對于不熟悉XML的開發人員,可以通過一些工具來完成.
比較有名的如XMLSPY和Stylus Studio都可以通過XML文件來生成Schema文件. 加入我們已經生成這個Schema文件(customer.xsd):
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<xs:element name="Customers">
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" name="customer"
type="customerType"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:complexType name="customerType">
<xs:sequence>
<xs:element name="id" type="xs:int"/>
<xs:element name="gender" type="xs:string"/>
<xs:element name="firstname" type="xs:string"/>
<xs:element name="lastname" type="xs:string"/>
<xs:element name="phoneNumber" type="xs:string"/>
<xs:element name="address" type="addressType"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="addressType">
<xs:sequence>
<xs:element name="primaryAddress" type="primaryAddressType"/>
<xs:element name="billingAddress" type="billingAddressType"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="primaryAddressType">
<xs:sequence>
<xs:element name="postalCode" type="xs:string"/>
<xs:element name="addressLine1" type="xs:string"/>
<xs:element name="addressLine2" type="xs:string"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="billingAddressType">
<xs:sequence>
<xs:element name="receiver" type="xs:string"/>
<xs:element name="postalCode" type="xs:string"/>
<xs:element name="addressLine1" type="xs:string"/>
<xs:element name="addressLine2" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:schema>
2. 利用scomp來生成Java Classes
scomp是XMLBean提供的一個編譯工具,它在bin的目錄下. 通過這個工具,我們可以將以上的Schema文件生成Java Classes.
scomp的語法如下:-
scomp [options] [dirs]* [schemaFile.xsd]* [service.wsdl]* [config.xsdconfig]*
主要參數說明:
-src [dir] -- 生成的Java Classes存放目錄
-srconly -- 不編譯Java Classes,不產生Jar文件
-out [jarFileName] -- 生成的Jar文件,缺省是xmltypes.jar
-compiler -- Java編譯器的路徑,即Javac的位置
schemaFile.xsd -- XML Schema文件位置
config.xsdconfig -- xsdconfig文件的位置, 這個文件主要用來制定生成的Java Class
的一些文件名規則和Package的名稱,在本文,package是sample.xmlbean
在本文,我是這樣運行的:
scomp -src build\src -out build\customerXmlBean.jar schema\customer.xsd
-compiler C:\jdk142_04\bin\javac customer.xsdconfig
這個命令行的意思是告訴scomp生成customerXmlBean.jar,放在build目錄下,同時
生成源代碼放在build\src下, Schema文件是customer.xsd,xsdconfig文件是customer.xsdconfig.
其實, 生成的Java源代碼沒有多大作用,我們要的是jar文件.我們先看一下build\src\sample\xmlbean下生成的Classes.
CustomersDocument.java
-- 整個XML文檔的Java Class映射
CustomerType.java
-- 節點sustomer的映射
AddressType.java
-- 節點address的映射
BillingAddressType.java
-- 節點billingAddress的映射
PrimaryAddressType.java
-- 節點primaryAddress的映射
好了,到此我們所有的準備工作已經完成了. 下面就開始進入重點:利用剛才生成的jar文件讀寫XML.
五、利用XMLBean讀XML文件
新建一個Java Project,將XMLBean2.0.0\lib\下的Jar文件和剛才我們生成的customerXmlBean.jar加入
到Project的ClassPath.
新建一個Java Class: CustomerXMLBean. 源碼如下:
package com.sample.reader;
import java.io.File;
import sample.xmlbean.*;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.xmlbeans.XmlOptions;
public class CustomerXMLBean {
private String filename = null;
public CustomerXMLBean(String filename) {
super();
this.filename = filename;
}
public void customerReader() {
try {
File xmlFile = new File(filename);
CustomersDocument doc = CustomersDocument.Factory.parse(xmlFile);
CustomerType[] customers = doc.getCustomers().getCustomerArray();
for (int i = 0; i < customers.length; i++) {
CustomerType customer = customers[i];
println("Customer#" + i);
println("Customer ID:" + customer.getId());
println("First name:" + customer.getFirstname());
println("Last name:" + customer.getLastname());
println("Gender:" + customer.getGender());
println("PhoneNumber:" + customer.getPhoneNumber());
// Primary address
PrimaryAddressType primaryAddress = customer.getAddress().getPrimaryAddress();
println("PrimaryAddress:");
println("PostalCode:" + primaryAddress.getPostalCode());
println("AddressLine1:" + primaryAddress.getAddressLine1());
println("AddressLine2:" + primaryAddress.getAddressLine2());
// Billing address
BillingAddressType billingAddress = customer.getAddress().getBillingAddress();
println("BillingAddress:");
println("Receiver:" + billingAddress.getReceiver());
println("PostalCode:" + billingAddress.getPostalCode());
println("AddressLine1:" + billingAddress.getAddressLine1());
println("AddressLine2:" + billingAddress.getAddressLine2());
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
private void println(String str) {
System.out.println(str); } public static void main(String[] args) {
String filename = "F://JavaTest//Eclipse//XMLBean//xml//customers.xml";
CustomerXMLBean customerXMLBean = new CustomerXMLBean(filename);
customerXMLBean.customerReader();
}
}
運行它,參看輸出結果:
Customer#0
Customer ID:1
First name:Jessica
Last name:Lim
Gender:female
PhoneNumber:1234567
PrimaryAddress:
PostalCode:350106
AddressLine1:#25-1
AddressLine2:SHINSAYAMA 2-CHOME
BillingAddress:
Receiver:Ms Danielle
PostalCode:350107
AddressLine1:#167
AddressLine2:NORTH TOWER HARBOUR CITY
Customer#1
Customer ID:2
First name:David
Last name:Bill
Gender:male
PhoneNumber:808182
PrimaryAddress:
PostalCode:319087
AddressLine1:1033 WS St.
AddressLine2:Tima Road
BillingAddress:
Receiver:Mr William
PostalCode:672993
AddressLine1:1033 WS St.
AddressLine2:Tima Road
怎么樣,是不是很輕松? XMLBean的威力.
六、利用XMLBean寫XML文件
利用XMLBean創建一個XML文檔也是一件輕而易舉的事.我們再增加一個Method,
請看一下的Java Class:
public void createCustomer() {
try {
// Create Document
CustomersDocument doc = CustomersDocument.Factory.newInstance();
// Add new customer
CustomerType customer = doc.addNewCustomers().addNewCustomer();
// set customer info
customer.setId(3);
customer.setFirstname("Jessica");
customer.setLastname("Lim");
customer.setGender("female");
customer.setPhoneNumber("1234567");
// Add new address
AddressType address = customer.addNewAddress();
// Add new PrimaryAddress
PrimaryAddressType primaryAddress = address.addNewPrimaryAddress();
primaryAddress.setPostalCode("350106");
primaryAddress.setAddressLine1("#25-1");
primaryAddress.setAddressLine2("SHINSAYAMA 2-CHOME");
// Add new BillingAddress
BillingAddressType billingAddress = address.addNewBillingAddress();
billingAddress.setReceiver("Ms Danielle");
billingAddress.setPostalCode("350107");
billingAddress.setAddressLine1("#167");
billingAddress.setAddressLine2("NORTH TOWER HARBOUR CITY");
File xmlFile = new File(filename);
doc.save(xmlFile); } catch (Exception ex) {
ex.printStackTrace(); } }
修改main method.
public static void main(String[] args) {
String filename = "F://JavaTest//Eclipse//XMLBean//xml//customers_new.xml";
CustomerXMLBean customerXMLBean = new CustomerXMLBean(filename);
customerXMLBean.createCustomer();
}
運行,打開customers_new.xml:
<?xml version="1.0" encoding="UTF-8"?>
<Customers>
<customer>
<id>3</id>
<gender>female</gender>
<firstname>Jessica</firstname>
<lastname>Lim</lastname>
<phoneNumber>1234567</phoneNumber>
<address>
<primaryAddress>
<postalCode>350106</postalCode>
<addressLine1>#25-1</addressLine1>
<addressLine2>SHINSAYAMA 2-CHOME</addressLine2>
</primaryAddress>
<billingAddress>
<receiver>Ms Danielle</receiver>
<postalCode>350107</postalCode>
<addressLine1>#167</addressLine1>
<addressLine2>NORTH TOWER HARBOUR CITY</addressLine2>
</billingAddress>
</address>
</customer>
</Customers>
七、利用XMLBean修改XML文件
我們再增加一個Method:
public void updateCustomer(int id,String lastname) {
try {
File xmlFile = new File(filename);
CustomersDocument doc = CustomersDocument.Factory.parse(xmlFile);
CustomerType[] customers = doc.getCustomers().getCustomerArray();
for (int i = 0; i < customers.length; i++) {
CustomerType customer = customers[i];
if(customer.getId()==id){
customer.setLastname(lastname);
break;
}
}
doc.save(xmlFile);
} catch (Exception ex) {
ex.printStackTrace();
}
}
main method:
public static void main(String[] args) {
String filename = "F://JavaTest//Eclipse//XMLBean//xml//customers_new.xml";
CustomerXMLBean customerXMLBean = new CustomerXMLBean(filename);
customerXMLBean.updateCustomer(3,"last"); }
運行之后,我們將會看到客戶編號為3的客戶的lastname已經改為last.
八、利用XMLBean刪除一個customer
再增加一個Method:
public void deleteCustomer(int id) {
try {
File xmlFile = new File(filename);
CustomersDocument doc = CustomersDocument.Factory.parse(xmlFile);
CustomerType[] customers = doc.getCustomers().getCustomerArray();
for (int i = 0; i < customers.length; i++) {
CustomerType customer = customers[i];
if(customer.getId()==id){
customer.setNil() ;
break;
}
}
doc.save(xmlFile);
} catch (Exception ex) {
ex.printStackTrace();
}
}
main method:
public static void main(String[] args) {
String filename = "F://JavaTest//Eclipse//XMLBean//xml//customers_new.xml";
CustomerXMLBean customerXMLBean = new CustomerXMLBean(filename);
customerXMLBean.deleteCustomer(3);
}
運行,我們將會看到客戶編號為3的客戶的資料已經被刪除.
九、查詢XML
除了本文在以上講述的,利用XMLBean能輕輕松松完成XML的讀寫操作外,結合XPath和XQuery,
XMLBean還能完成象SQL查詢數據庫一樣方便地查詢XML數據. 關于XML查詢以及如何創建XML數據庫, 我將在另一篇文章里討論.
十、結束語
XMLBean能幫助我們輕易讀寫XML,這將有助于我們降低XML的學習和使用,有了這個基礎,開發人員將為學習更多地XML相關技術和Web Services,JMS等其他J2EE技術打下良好地基礎.
摘要: 利用(二)中我寫的兩個函數(放在package src中),這次實現web頁面的操作。index.html:<%@?page?language="java"?pageEncoding="GB2312"%><body><p> </p><p> </p><p> <...
閱讀全文
摘要: 這是讀取xml文件的java程序,我調試好的。采用的是dom方式讀取xml文件到Vector中。
?1
package
?src;
?2
import
?java.io.
*
;
?3
import
...
閱讀全文
JAXP API--嵌入不同的解釋器
SAX解釋器+DOM解釋器+XSL轉換器
javax.xml.parsers中加載XML文檔的類:
DocumentBuilder
DocumentBuildrFactory
SAXParser
SAXParserFactory
=====================================
SAX API
SAX的XML解釋器:Apache的Xerces或Crimson
處理XML文檔的接口:
ContentHandler
EntityResolver
ErroHandler
DTDHandler
DeclHandler
LexicalHandler
======================================
DOM API
兩個DOM標準:DOM Level1 DOM Level 2 Core
節點
Node-節點類型接口層次結構的根。
Document-樹結構的根
Element-XML元素
Text-元素內的文本
Attr-元素的特性
CDATA Sectionn-CDATA
NodeList-子節點的集合
ProcessingInstruction-指令
Comment-包含注釋的信息
DocumentFragment-Document的消減版,用于在樹中移動節點
DocumentType-文檔類型定義的子集。
Entity-DTD中的實體標記
EntityReference-XML文檔中的實體引用
Notation-DTD中的符號標記
從程序中讀取X M L文檔基本上有三種方式:
1把X M L只當做一個文件讀取,然后自己挑選出其中的標簽。這是黑客們的方法,我們不推薦這種方式。
你很快會發現處理所有的特殊情況(包括不同的字符編碼,例外約定,內部和外部實體,缺省屬性等)比想象的困難得多;
你可能不能夠正確地處理所有的特殊情況,這樣你的程序會接收到一個非常規范的X M L文檔,卻不能正確地處理它。
要避免這種想法:XML解析器似乎并不昂貴(大多數是免費的)。
2可以用解析器分析文檔并在內存里創建對文檔內容樹狀的表達方式:解析器將輸出傳遞給文檔對象模型,即DOM。
這樣程序可以從樹的頂部開始遍歷,按照從一個樹單元到另一個單元的引用,從而找到需要的信息。
3也可以用解析器讀取文檔,當解析器發現標簽時告知程序它發現的標簽。
例如它會告知它何時發現了一個開始標簽,何時發現了一些特征數據,以及何時發現了一個結束標簽。
這叫做事件驅動接口,因為解析器告知應用程序它遇到的有含義的事件。
如果這正是你需要的那種接口,可以使用SAX。
SAX是只讀的
DOM可以從XML原文件中讀取文檔,也可以創建和修改內存中的文檔。相比較而言,SAX是用來讀取XML文檔而不是書寫文檔。
可擴展樣式語言(XSL,eXtensible Sytlesheet Language)是一種基于XML的語言,
它被設計用來轉換XML文檔到另一種XML文檔或轉換XML文檔為可翻譯對象。
原始的XSL語言已經被分割成三種不同的語言:
1轉換工具(XSLT)是一種轉換XML文檔到其他XML文檔的語言
2翻譯工具(XSLF—可以包括X S LT的使用)
3XML分級命令處理工具(XPath)
XSL有它自已的根,不管是在層疊樣式表(CSS)中還是在一種叫DSSSL(文檔樣式語義和規格語言—讀為'deessel')的語言中。
隨著它的發展,XSL的樣式表現變得更接近于CSS和遠離DSSSL
注意事項:
1。本試卷分第I卷(選擇貼)和第II卷(非選擇題)兩部分。考試結束后,將本試卷和答題卡一并交回。
2。本試卷采取魔獸爭霸3冰封王座1.18版本。
第I卷
一。選擇題:(共12道題,每題5分)
(1)不死女妖能不能夠占據空軍?(?? )
A.不網下來不可以,網下來可以。
B.不網下來不可以,網下來也不可以。
C.不網下來可以,網下來不可以。
D.不網下來可以,網下來也可以。
(2)被釋放妖術的不死單位是否可以用死亡纏繞加血?( )
A.不能。
B.能。
C.一級妖術可以。
D.完全看人品。
(3)下面哪種方法不可以用來探隱形?( )
A.造哨塔,并升級探隱形。
B.先知的透視。
C.地精研究所探照燈。
D.抓住對手脖子猛搖,導致對手操作失誤。
(4)下面哪種傷害性技能會打斷恢復性藥品(比如獸族的補血藥膏)? (?? )
A.惡魔獵手的Mana Burn,
B.叢林守護者的纏繞,
C.毒素傷害。
D.死亡纏繞。
(5)下面四組技能中哪一組不全能打斷對手? ( )
A.戰爭踐踏,須根纏繞,颶風。
B.睡眠,變羊,放逐。
C.風暴之錘,沉默,重擊。
D.巫術,靜止陷阱,雷霆一擊。
(6)什么辦法可以加快農民采礦速度?( )
A.加速卷軸。
B.耐久光環。
C.提高工資。
D.現在的版本任何增加速度的光環和魔法效果都不會改變采金速度。
(7)下面四組技能中哪一組不全是持續性魔法技能? ( )
A.占據,地震,巫毒
B.食尸,流星群,寧靜之雨
C.烈焰風暴,暴風雪,放逐。
D.火雨,萬獸驚襲,火山
(8)下列什么情況下戰場上的單位光環不會失效? ( )
A.隱形;
B.上飛艇;
C.被吹上天;
D.英雄掛掉。
(9)下面哪些技能能夠躲避已經投出的風暴之錘? ( )
A.劍圣疾風步。
B.蜘蛛鉆地。
C.女巫隱形。
D.熊貓分身。
(10)哪個1級英雄最貧血?( )
A.巫妖
B.先知
C.test師。
D.娜迦。
(11)下列哪種技能不能夠被破法者盜取? ( )?
A.嗜血。
B.須根纏繞。
C.靜止陷阱。
D.颶風。
(12)農民能否修理第精飛艇? ( )
A.不能。
B.能。
C.必須用颶風權杖將農民吹上天才能修理。
D.必須用穿刺將農民插上天才能修理。
第II卷
二。計算:[ne]弓箭手攻擊升級了自然祝福的暗夜基地傷害是百分之多少?如果基地站起,傷害又是百分之多少?(10分)
三。計算:[orc]3級閃電鏈和3級震蕩波打在滿血獸人步兵身上,問需要用1級的治療波治療幾次方可滿血?(10分)
四。計算:[hum]一個滿魔的破法者能否占據一個半血的3級水元素?計算數據說明理由。(10分)
五。計算:[ud]三級的死亡纏繞二級的霜之新星加一級的穿刺對普通兵可以造成多少傷害?(10分)