dom4j是一個Java的XML API,同時也是一種解析XML文檔的開源軟件。由dom4j.org開發,具有性能優異、功能強大和極端易用的特點,大名鼎鼎的Hibernate就是用它來讀取配置文件滴。
開發環境:Eclipse
1、創建Web Project
用Web Project來演示的原因一是因為WEB-INF目錄下有一個lib目錄,例子中需要用到的jar包,直接放進去就行了,二是這個系列后面講的內容會需要。如果建Java Project則還要設置庫路徑,為了方便,就用Web Project吧。點擊"File"->"New"->"Project",選擇"Web Project",在"Project Name"中輸入demo,點擊"Finish"。然后我們把dom4j-
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文件中對應的配置都要作相應的改動!<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>
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();
}
}
這里有三點要說明一下: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方法是一個重載的方法,里面的參數可以為File、FileInputStream、URL等。所以這里還可以寫成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)
如果沒有問題的話,應該可以在控制臺看到下面的結果: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
url: jdbc:mysql://127.0.0.1:3306/mysql
username: root
password: 123
到此,我們已經成功使用dom4j從XML中讀取文件,下面我們對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接口* 這里使用的是單態模式
*/
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);
}
在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的,域自動的被定義為public、static和final的,因此不用顯式的聲明。String URL = "url";
String USERNAME = "username";
String PASSWORD = "password";
String DB_CONFIG = "DBConnect.xml";
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 String driver; //連接驅動
private static String url; //數據庫連接地址
private static String username; //用戶名
private static String password; //密碼
/**
* 加載數據源配置文件,取得根元素
*/
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方法靜態初始化:* 加載數據源配置文件,取得根元素
*/
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);
}
}
static{
load();
}
通過XPATH路徑得到對應的元素:load();
}
/**
* 通過XPATH得到元素對象
* @param xPath XPATH路徑
* @return 獲得Element對象
*/
public static Element getElement(String xPath){
return (Element)coreModel.selectSingleNode(xPath);
}
再寫一個方法,讀取數據源配置信息,將之放入HashMap中:* 通過XPATH得到元素對象
* @param xPath XPATH路徑
* @return 獲得Element對象
*/
public static Element getElement(String xPath){
return (Element)coreModel.selectSingleNode(xPath);
}
/**
* 取得數據源配置信息放入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;
}
構造函數:* 取得數據源配置信息放入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);
}
創建數據庫連接及關閉等操作,此處省略,請查看源碼。* 構造函數初始化
*/
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 的結果。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);
}
}
這里附上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>
<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>
本著對別人負責,同時也是對自己負責,全部代碼,大象都是親手寫出來在電腦上測試過,并且還模擬了產生異常的環境,請大家放心使用。<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包)
本文為菠蘿大象原創,如要轉載請注明出處。