关于早期的一小段代码的解析

时间:2021-03-28 15:49:28

代码的来源已不记得,只是在分析代码的时候觉得学到了很多的思路,特此记录:)

点击下载此资源

源代码的目录结构:

|--java
|--bean
|--bll
|--dal
|--dao
|--db
|--struts
|--tld
|--util
|--util
|--ApplicationResource.properties
|--connector.properties

connector.properties配置文件的格式为:

<properties>
<entry key="defaultName" value="mysql"></entry>
<entry key="mysql" packageName="" connString="" driverClass="" ></entry>
--其他数据库配置信息--
</properties>

在接下来陆续解析里面的一些思想与巧妙之处…

底层可适配多种数据库的设计

代码是这样的(里面加了少量的注释):

/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/


package db;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

/**
*
* @author Jonllen
*/

public class DbManager {

private DbManager(){}

//得到的时资源文件的路径
private static String propFileName = DbManager.class.getClassLoader().getResource("").getPath()+"connector.properties";

//存放默认的数据库的名称
private String defaultName;

private DbItem defaultItem;

private List<DbItem> list;

private static DbManager instance = null;

public String getDefaultName() {
return defaultName;
}

public void setDefaultName(String defaultName) {
//遍历集合
for(DbItem item : this.list)
{
//搜索配置文件中配置的,默认的数据库
if (item.getDbName().equalsIgnoreCase(defaultName))
{
System.out.println("修改设置当前数据库为:" + defaultName );

this.defaultName = defaultName;
this.defaultItem = item;

dal.DataAccess.daoPackageName = item.getPackageName();
db.SqlHelper.ConnString = item.getConnString();
db.SqlHelper.DriverClass = item.getDriverClass();
}
}
}

public Boolean IsDefault(String dbName)
{
return dbName.equalsIgnoreCase(this.defaultName);
}

public DbItem getDefaultItem() {
return defaultItem;
}

public void setDefaultItem(DbItem defaultItem) {
this.defaultItem = defaultItem;
}

public List<DbItem> getList() {
return list;
}

public void setList(List<DbItem> list) {
this.list = list;
}

//读取配置文件的相关设置
public synchronized static DbManager GetConfig(){

if (instance!=null ) return instance;

System.out.println("--读取 " + propFileName + "资源配置文件开始--");

instance = new DbManager();

DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
NodeList nodelist = null;
try {
DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
Document doc = docBuilder.parse (new File(propFileName));
nodelist = doc.getElementsByTagName("entry");

} catch (Exception e) {
e.printStackTrace();
}

if (nodelist==null || nodelist.getLength()==0 )
{
try {
throw new Exception("文件" + propFileName + "找不到entry节点");
} catch (Exception ex) {
ex.printStackTrace();
}
}

String defaultName = null;

List<DbItem> list = new ArrayList<DbItem>();//存放不同数据库的连接信息
for(int i = 0;i<nodelist.getLength();i++)
{
//该部分内容与XML的读取操作有关
Node node = nodelist.item(i);
String keyName = node.getAttributes().getNamedItem("key").getNodeValue();
if ( keyName.equalsIgnoreCase("defaultName") )
{
defaultName = node.getAttributes().getNamedItem("value").getNodeValue();//此时defaultName=“mysql”
}else {
//每一个数据库连接信息封装到一个item中
//然后将每一item,添加到集合中
DbItem item = new DbItem();
item.setDbName(keyName);
item.setPackageName(node.getAttributes().getNamedItem("packageName").getNodeValue());
item.setConnString(node.getAttributes().getNamedItem("connString").getNodeValue());
item.setDriverClass(node.getAttributes().getNamedItem("driverClass").getNodeValue());
list.add(item);
}
}

instance.setList(list);
instance.setDefaultName(defaultName);

return instance;
}

}

此类的作用是读取数据库的配置文件connector.properties,并将当前使用的数据库的连接信息保存在beanDbItem中,现在只需了解beanDbItem中包含的属性即可,即:数据库的名称dbname、数据库的连接字符串connString、数据库驱动的名字driverClass、以及packageName现在暂时不展开描述。

此类使用了单例设计模式,很明显的可以看到代码中包含有一个私有的类型为DbManager的属性instance和公共用的静态方法public synchronized static DbManager GetConfig(){}

类中的属性:

  • propFileName,用来的到配置文件的路径。

  • list,类型为List<DbItem>,用来保存配置文件中配置的所有entry,key为defaultName的entry除外。

  • defaultName,类型为String,用来保存配置文件中key为defaultName的entry所配置的value,就是默认的数据库的名称。

  • defaultItem,类型为DbItem,用来保存默认数据库所对应的entry的连接信息。

defaultName和defaultItem的设置:

​ 通过遍历list,然后判断每个list.getDbName()是否与defaultName相同,若相同,则将当前的item设置给defaultItem。

那末list中的值是怎么来的呢?

  • 我们可以保证可以得到peopFileName,即配置文件的位置。类中将该属性设置为了静态属性。

  • 类中使用DOM解析,去解析数据库配置文件connector.properties,操作时将该配置文件当成xml来解析…。

    DOM解析中通过getElementByTagName(“entry”),将配置文件中的所有<entry></entry>保存到了一个NodeList类型的属性nodelist中,可以理解为集合,只不过是属于org.w3c.dom第三方。

    接下来,就去遍历nodelist了,NodeList提供有大量操作类似xml格式数据的方法,在遍历过程中如果key为defaultName,则设置defaultName,否则则将其add进list中。

以上流程则是解析也是静态方法GetConfig()的逻辑。—(第一部分结束)