前面的学习我们了解到,想要使用C3P0必须加入c3p0-config.xml
那么C3P0内部是如何运作来获取数据库连接信息的呢?
其实,也是它是通过dom4j+xpath对xml文件进行了解析,从而获取到了想要的属性
这也就明确了为什么c3p0-config.xml的名字不能被修改,而且里面的配置格式也不可能调整,因为都是程序内定的!
下面通过案例来模拟模拟C3P0解析c3p0-config.xml的过程:
1.测试准备
项目工程
2.代码展示(这里会将解析出来的信息封装成对象)
***pom.xml
4.0.0
com.howie
parsexml_c3p0
1.0-SNAPSHOT
1.8
1.8
junit
junit
4.12
dom4j
dom4j
1.6.1
jaxen
jaxen
1.1.6
***c3p0-config.xml
com.mysql.jdbc.Driver
jdbc:mysql://localhost:3306/mysqlstudy?characterEncoding=utf8
root
root
10
***XmlConfigBuilder.java
package com.howie.utils;
import com.howie.pojo.Configuration;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.io.InputStream;
import java.util.List;
/**
* @Author weihuanwen
* @Date 2019/8/6 10:34
* @Version 1.0
*/
public class XmlConfigBuilder {
public static Configuration loadXmlConfig(InputStream is){
//8.封装Configuration对象
Configuration config = new Configuration();
//1.获取SAXReader对象
SAXReader saxReader = new SAXReader();
try {
//2.获取操作xml文件的document对象
Document document = saxReader.read(is);
//3.获取根节点对象
Element rootElement = document.getRootElement();
//4.通过xPath语法找到所有的property标签
List properties = rootElement.selectNodes("//property");
//5.非空判断
if (properties != null && properties.size() > 0){
//6.遍历proerty标签
for (Element property : properties) {
//7.获取标签的属性
String name = property.attributeValue("name");
String value = property.getText();
//9.匹配字段并为对象赋值
if ("driverClass".equals(name)){
config.setDriverClass(value);
}
if ("jdbcUrl".equals(name)){
config.setJdbcUrl(value);
}
if ("user".equals(name)){
config.setUser(value);
}
if ("password".equals(name)){
config.setPassword(value);
}
if ("initialPoolSize".equals(name)){
config.setInitialPoolSize(Integer.parseInt(value));
}
}
}
//关闭输入流
is.close();
} catch (Exception e) {
e.printStackTrace();
}
return config;
}
}
***Configuration.java
package com.howie.pojo;
/**
* @Author weihuanwen
* @Date 2019/8/6 10:32
* @Version 1.0
*/
public class Configuration {
private String driverClass;
private String jdbcUrl;
private String user;
private String password;
private Integer initialPoolSize;
public String getDriverClass() {
return driverClass;
}
public void setDriverClass(String driverClass) {
this.driverClass = driverClass;
}
public String getJdbcUrl() {
return jdbcUrl;
}
public void setJdbcUrl(String jdbcUrl) {
this.jdbcUrl = jdbcUrl;
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Integer getInitialPoolSize() {
return initialPoolSize;
}
public void setInitialPoolSize(Integer initialPoolSize) {
this.initialPoolSize = initialPoolSize;
}
@Override
public String toString() {
return "Configuration{" +
"driverClass='" + driverClass + '\'' +
", jdbcUrl='" + jdbcUrl + '\'' +
", user='" + user + '\'' +
", password='" + password + '\'' +
", initialPoolSize=" + initialPoolSize +
'}';
}
}
***SimulatedParseXml.java
package com.howie.textparsing;
import com.howie.pojo.Configuration;
import com.howie.utils.XmlConfigBuilder;
import org.junit.Test;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
/**
* @Author weihuanwen
* @Date 2019/8/6 10:30
* @Version 1.0
*/
public class SimulatedParseXml {
@Test
public void getDetail() throws FileNotFoundException {
String path = "src/main/resources/c3p0-config.xml";
InputStream is = new FileInputStream(path);
Configuration config = XmlConfigBuilder.loadXmlConfig(is);
System.out.println(config);
}
}
3.测试
①执行SimulatedParseXml的getDetail()
②控制台输出:
Configuration{driverClass='com.mysql.jdbc.Driver', jdbcUrl='jdbc:mysql://localhost:3306/mysqlstudy?characterEncoding=utf8', user='root', password='root', initialPoolSize=10}
1.DOM4j
①是一个易用的、开源的库,用于XML,XPath和XSLT
②通过其可以获取所有的结点
③支持XPath
2.Xpah
①一种用来确定XML文档中某部分位置的语言
②其相关表达式如下:
表达式 |
描述 |
---|---|
nodename |
选取此节点的所有子节点。 |
/ |
从根节点选取。 |
// |
从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。 |
. |
选取当前节点。 |
.. |
选取当前节点的父节点。 |
③路径表达式以及表达式的结果:
路径表达式 |
结果 |
---|---|
bookstore |
选取 bookstore 元素的所有子节点。 |
/bookstore |
选取根元素 bookstore。 注释:假如路径起始于正斜杠( / ),则此路径始终代表到某元素的绝对路径! |
bookstore/book |
选取属于 bookstore 的子元素的所有 book 元素。 |
//book |
选取所有 book 子元素,而不管它们在文档中的位置。 |
bookstore//book |
选择属于 bookstore 元素的后代的所有 book 元素,而不管它们位于 bookstore 之下的什么位置。 |
//@lang |
选取名为 lang 的所有属性。 |