隨筆-67  評論-522  文章-0  trackbacks-0
              目前XML文件的應用越來越廣泛,而操作XML的技術更有不少,其中以dom4j強大的性能,豐富的API以及簡單的易用性,受到了很多人的喜愛,本文以一個讀取數據源的小例子,來說明一下dom4j的一些基本操作。
              dom4j一個JavaXML API,同時也是一種解析XML文檔的開源軟件。由dom4j.org開發,具有性能優異、功能強大和極端易用的特點,大名鼎鼎的Hibernate就是用它來讀取配置文件滴。本文只是對dom4j的一些基本操作進行說明,不包含深入分析。(本文最后有源碼和相關JAR包下載)
              開發環境:Eclipse 3.2.1 MyEclipse 5.1.0GA dom4j-1.6.1.jar jaxen-1.1-beta-7.jar
              1、創建Web Project
                 Web Project來演示的原因一是因為WEB-INF目錄下有一個lib目錄,例子中需要用到的jar包,直接放進去就行了,二是這個系列后面講的內容會需要。如果建Java Project則還要設置庫路徑,為了方便,就用Web Project吧。點擊"File"->"New"->"Project",選擇"Web Project",在"Project Name"中輸入demo,點擊"Finish"。然后我們把dom4j-1.6.1.jarjaxen-1.1-beta-7.jar還有MySQL的連接驅動放到WEB-INF\lib目錄下。
              2、創建DBConnect.xml
                 src目錄下建一個DBConnect.xml文件,內容如下:
          <?xml version="1.0" encoding="UTF-8"?>
          <demo>
              
          <database>
                  
          <driver>com.mysql.jdbc.Driver</driver>
                  
          <url>jdbc:mysql://127.0.0.1:3306/mysql</url>
                  
          <username>root</username>
                  
          <password>123</password>
              
          </database>
          </demo>
                 大象在這里用MySQL的數據庫,當然你也可以換成SQL Server或是Oracle,不過XML文件中對應的配置都要作相應的改動!
              3、創建DataBaseConnect.java
                 在src上點右鍵,選擇"New->Package",輸入:com.demo.database,在database下新建一個類,類名為:DataBaseConnect下面我們先寫一段簡單的代碼,測試一下,看看能否從這個XML文件中讀取到配置信息。在DataBaseConnect類中加入main函數,然后寫上如下代碼:
              public static void main(String[] args){
                  
          try{
                      SAXReader saxReader 
          = new SAXReader(); //使用SAXReader方式讀取XML文件
                      //加載數據庫XML配置文件,得到Document對象
                      Document document = saxReader.read(new File("src/DBConnect.xml")); 
                      Element root = document.getRootElement(); //獲得根節點
                      //得到database節點
                      Element database = (Element)root.selectSingleNode("//demo/database"); 
                      List list = database.elements(); //得到database元素下的子元素集合
                      /*
                       * 循環遍歷集合中的每一個元素
                       * 將每一個元素的元素名和值在控制臺中打印出來
                       
          */
                      
          for(Object obj:list){
                          Element element 
          = (Element)obj;
                          
          //getName()是元素名,getText()是元素值
                          System.out.println(element.getName()+""+element.getText());
                      }
                  }
          catch(Exception e){
                      e.printStackTrace();
                  }
              }
                 這里有三點要說明一下:
                   a、saxReader.read(new File("src/DBConnect.xml")),這個read方法是一個重載的方法,里面的參數可以為FileFileInputStreamURL等。所以這里還可以寫成new FileInputStream ("src/DBConnect.xml"),另外還可以用ClassLoader來加載:getClass().getClassLoader().getResourceAsStream("DBConnect.xml"),注意,這里不能加"src/",因為它是在WEB-INF\classes里面找文件,另外不能寫在靜態的main函數里,可以在main方法外,創建一方法,在main中通過實例化類對象來調用,這里不再詳述,大家自己去試下。
                   b、root.selectSingleNode("http://demo/database"),這里的"http://demo/database"其實是一個XPATH語法,關于XPATH請參考相關資料,這里不作討論。這樣寫的意思是指:demo根節點下的database節點,"selectSingleNode"是得到database這個單獨的元素,至于database下面是否還包含別的信息,則是通過其它的API來操作。
                    c、如果你在使用XPATH語法的時候沒有加入jaxen-1.1-beta-7.jar這個包,就會出現如下異常:
          Exception in thread "main" java.lang.NoClassDefFoundError: org/jaxen/JaxenException
              at org.dom4j.DocumentFactory.createXPath(DocumentFactory.java:230)
              at org.dom4j.tree.AbstractNode.createXPath(AbstractNode.java:207)
              at org.dom4j.tree.AbstractNode.selectSingleNode(AbstractNode.java:183)
              at com.demo.database.DataBaseConnect.main(DataBaseConnect.java:16)
                 如果沒有問題的話,應該可以在控制臺看到下面的結果:
          driver: com.mysql.jdbc.Driver
          url: jdbc:mysql://127.0.0.1:3306/mysql
          username: root
          password: 
          123

                 到此,我們已經成功使用dom4jXML中讀取文件,下面我們對DataBaseConnect作一下修改,畢竟上面這種寫法是測試用的,真正的類怎么可能這樣寫?
              4、創建ClassUtils.java
                 新建com.demo.util包,在util包下新建ClassUtils類,用來處理資源加載方面的事情,內容如下:

              /*
               * 這里使用的是單態模式
               
          */
              
          private static ClassUtils instance = new ClassUtils(); //實例化私有靜態對象
              
              
          /**
               * 通過資源名稱或資源路徑得到資源輸入流
               * 
          @param name 資源名稱或資源路徑
               
          */
              
          public static InputStream getResourceAsStream(String name) {
                  
          /*
                   * 這里用到了回調方法
                   * 使用靜態的私有對象,在靜態方法中調用非靜態的方法
                   * 并且loadResource是私有方法,對外不可見
                   
          */
                  
          return instance.loadResource(name);
              }
              
              
          /**
               * 私有構造函數,不能在外部被實例化
               
          */
              
          private ClassUtils() {}
              
              
          /**
               * 通過資源名稱或資源路徑加載資源
               * 
          @param name 資源名稱或資源路徑
               * 
          @return InputStream
               
          */
              
          private InputStream loadResource(String name) {
                  
          return getClass().getClassLoader().getResourceAsStream(name);
              }
              5、創建Constant接口
                 在util包下再建一個Constant接口,里面放的是數據源配置常量字符串,與XML文件中的元素名對應,在這里是將DBConnect.xml放在src目錄下,如果你想放到其它的目錄下,則要加上包名,比如放在database包下,那么應該寫成:com/demo/database/DBConnect.xml。
              String DRIVER = "driver";
              String URL 
          = "url";
              String USERNAME 
          = "username";
              String PASSWORD 
          = "password";
              String DB_CONFIG 
          = "DBConnect.xml";
                 在接口中,方法自動定義成public的,域自動的被定義為publicstaticfinal的,因此不用顯式的聲明。
              6、修改DataBaseConnect
                 最后我們來修改DataBaseConnect類,首先我們定義幾個靜態變量:
              private static Element coreModel; //根元素
              private static String driver; //連接驅動
              private static String url;    //數據庫連接地址
              private static String username; //用戶名
              private static String password; //密碼
                 讀取DBConnect.xml文件,獲得根元素:
              /**
               * 加載數據源配置文件,取得根元素
               
          */
              
          private static void load(){
                  SAXReader saxReader 
          = new SAXReader();
                  //加載數據庫XML配置文件
                  InputStream in 
          = ClassUtils.getResourceAsStream(Constant.DB_CONFIG); 
                  try{
                      Document document 
          = saxReader.read(in); //得到Document對象
                      coreModel = document.getRootElement(); //得到根元素
                  }catch(Exception e){
                      System.out.println(
          "XML配置文件未加載成功,請檢查");
                      
          throw new RuntimeException(e);
                  }
              }
                 將load方法靜態初始化:
              static{
                  load();
              }
                 通過XPATH路徑得到對應的元素:
              /**
               * 通過XPATH得到元素對象
               * 
          @param xPath XPATH路徑
               * 
          @return 獲得Element對象
               
          */
              
          public static Element getElement(String xPath){
                  
          return (Element)coreModel.selectSingleNode(xPath);
              }
                 再寫一個方法,讀取數據源配置信息,將之放入HashMap中:
              /**
               * 取得數據源配置信息放入HashMap中
               * 
          @param hashmap 存放取得的數據源鍵值對
               * 
          @return 返回存放信息的HashMap
               
          */
              
          public static HashMap<String,String> iterateXML(HashMap<String,String> hashmap){
                  
          try{
                      Element database 
          = getElement("//demo/database"); //得到database節點
                      List list = database.elements(); //得到database元素下的子元素集合
                      /*
                       * 循環遍歷集合中的每一個元素
                       * 將每一個元素的元素名和值作為鍵值對放入HashMap中
                       
          */
                      
          for(Object obj:list){
                          Element element 
          = (Element)obj;
                          
          //getName()是元素名,getText()是元素值
                          hashmap.put(element.getName(), element.getText());
                      }        
                  }
          catch(Exception e){
                      e.printStackTrace();
                  }
                  
          return hashmap;
              }
                 構造函數:
              /**
               * 構造函數初始化
               
          */
              
          public DataBaseConnect(){
                  HashMap
          <String,String> hashmap = new HashMap<String,String>();
                  hashmap 
          = iterateXML(hashmap);//取得數據源配置信息
                  driver = hashmap.get(Constant.DRIVER);
                  url 
          = hashmap.get(Constant.URL);
                  username 
          = hashmap.get(Constant.USERNAME);
                  password 
          = hashmap.get(Constant.PASSWORD);
              }
                 創建數據庫連接及關閉等操作,此處省略,請查看源碼。
                 最后我們寫一個main方法來測試一下是否能夠連接數據庫:

              public static void main(String[] args){
                  DataBaseConnect db 
          = new DataBaseConnect();
                  Connection con 
          = db.getConnection();
                  
          try{
                      PreparedStatement psmt 
          = con.prepareStatement("select count(*) from help_keyword");
                      ResultSet rs 
          = psmt.executeQuery();
                      rs.next();
                      System.out.println(rs.getString(
          1));
                      rs.close();
                      psmt.close();
                      db.close(con);
                  }
          catch(Exception e){
                      
          throw new RuntimeException(e);
                  }
              }
                 如果沒問題,控制臺將打印出:381 的結果。
                 這里附上DBConnect.xml中SQL Server 2000和Oracle的配置,其中SQL Server采用JTDS驅動。
          <?xml version="1.0" encoding="UTF-8"?>
          <demo>
              
          <database>
                  
          <driver>net.sourceforge.jtds.jdbc.Driver</driver>
                  
          <url>jdbc:jtds:sqlserver://127.0.0.1:1433/pubs</url>
                  
          <username>sa</username>
                  
          <password>自己密碼(無密碼就空著)</password>
              
          </database>
          </demo>

          <?xml version="1.0" encoding="UTF-8"?>
          <demo>
              
          <database>
                  
          <driver>oracle.jdbc.driver.OracleDriver</driver>
                  
          <url>jdbc:oracle:thin:@127.0.0.1:1521:自己的SID</url>
                  
          <username>system</username>
                  
          <password>自己密碼(無密碼就空著)</password>
              
          </database>
          </demo>
              本著對別人負責,同時也是對自己負責,全部代碼,大象都是親手寫出來在電腦上測試過,并且還模擬了產生異常的環境,請大家放心使用。
              點擊下載:dom4j-1.6.1.jar  jaxen-1.1-beta-7.jar  mysql-connector.jar  jtds.jar  classes12.jar
              點擊下載:demo  (直接導入即可,加入上面的jar包)
              本文為菠蘿大象原創,如要轉載請注明出處。
          posted on 2008-08-09 22:24 菠蘿大象 閱讀(7100) 評論(8)  編輯  收藏 所屬分類: dom4j&jdom

          評論:
          # re: dom4j實戰(一)——使用dom4j從XML中讀取數據源配置 2008-08-18 10:49 | 昨夜流星
          頂一下,呵呵,正想學習DOM4J,希望樓主能繼續寫下去!  回復  更多評論
            
          # re: dom4j實戰(一)——使用dom4j從XML中讀取數據源配置 2009-01-04 16:59 | 王維娜
          支持,謝謝摟主  回復  更多評論
            
          # re: dom4j實戰(一)——使用dom4j從XML中讀取數據源配置 2010-05-24 21:32 | 大灰狼
          我把你的demo下載后,導入myeclipse中,運行時出現如下的錯誤提示:
          XML配置文件未加載成功,請檢查
          java.lang.ExceptionInInitializerError
          Caused by: java.lang.RuntimeException: org.dom4j.DocumentException: null Nested exception: null
          at com.demo.database.DataBaseConnect.load(DataBaseConnect.java:50)
          at com.demo.database.DataBaseConnect.<clinit>(DataBaseConnect.java:36)
          Caused by: org.dom4j.DocumentException: null Nested exception: null
          at org.dom4j.io.SAXReader.read(SAXReader.java:484)
          at org.dom4j.io.SAXReader.read(SAXReader.java:343)
          at com.demo.database.DataBaseConnect.load(DataBaseConnect.java:46)
          ... 1 more
          Exception in thread "main"
          我把文件路徑改為了tring DB_CONFIG = "/DBConnect.xml";如果是原來的tring DB_CONFIG = "DBConnect.xml";則不提示出錯,但是輸出的,url,username,password等全是NUll  回復  更多評論
            
          # re: dom4j實戰(一)——使用dom4j從XML中讀取數據源配置 2010-05-25 08:47 | 菠蘿大象
          @大灰狼
          你的這個問題應該是把路徑設置錯了,你如果沒改動配置文件的位置,就不要改動常量中設置的值,這兩者一定要對應,我的例子都測試過的,不然我也不敢放上來。  回復  更多評論
            
          # re: dom4j實戰(一)——使用dom4j從XML中讀取數據源配置 2010-05-25 10:49 | 大灰狼
          我是把你的demo全部導入的,jar包是有的dom4j-1.6.1.jar,導進來直接運行的時候輸出的url,username,password等全是NULL  回復  更多評論
            
          # re: dom4j實戰(一)——使用dom4j從XML中讀取數據源配置 2010-05-25 10:59 | 大灰狼
          發現DataBaseConnect()這個構造函數沒有運行  回復  更多評論
            
          # re: dom4j實戰(一)——使用dom4j從XML中讀取數據源配置 2010-05-25 11:14 | 大灰狼
          現在好了,謝謝菠蘿大象同志,原因是我沒有導入jaxen-1.1-beta-6.jar,加入這個一切順利  回復  更多評論
            
          # re: dom4j實戰(一)——使用dom4j從XML中讀取數據源配置 2010-05-25 21:48 | 菠蘿大象
          @大灰狼
          呵呵,恭喜你,自己調試成功,又積累了一次經驗。  回復  更多評論
            
          主站蜘蛛池模板: 光泽县| 武平县| 灵川县| 富平县| 双峰县| 南召县| 阿城市| 崇州市| 哈密市| 固始县| 四会市| 唐海县| 景德镇市| 镇雄县| 青神县| 游戏| 包头市| 蒙城县| 电白县| 临沧市| 齐河县| 古丈县| 梁山县| 莱州市| 肇东市| SHOW| 商南县| 宿迁市| 乐清市| 宁强县| 昆山市| 海南省| 静乐县| 清涧县| 莱芜市| 江永县| 灵寿县| 乳山市| 胶州市| 潮安县| 新兴县|