前面的学习我们了解到,想要使用C3P0必须加入c3p0-config.xml
那么C3P0内部是如何运作来获取数据库连接信息的呢?
其实,也是它是通过dom4j+xpath对xml文件进行了解析,从而获取到了想要的属性
这也就明确了为什么c3p0-config.xml的名字不能被修改,而且里面的配置格式也不可能调整,因为都是程序内定的!
下面通过案例来模拟模拟C3P0解析c3p0-config.xml的过程:
一.案例展示
1.测试准备
项目工程
2.代码展示(这里会将解析出来的信息封装成对象)
***pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.howie</groupId>
<artifactId>parsexml_c3p0</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<!--单元测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!--dom4j-->
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
<!--xpath-->
<dependency>
<groupId>jaxen</groupId>
<artifactId>jaxen</artifactId>
<version>1.1.6</version>
</dependency>
</dependencies>
</project>
***c3p0-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<default-config>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/mysqlstudy?characterEncoding=utf8</property>
<property name="user">root</property>
<property name="password">root</property>
<property name="initialPoolSize">10</property>
</default-config>
</c3p0-config>
***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<Element> 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 的所有属性。 |