数据库参数的可配置性
来源:互联网 发布:济南打车软件 编辑:程序博客网 时间:2024/06/06 02:53
数据库参数的可配置性(web.xml)
为了达到松耦合,数据库的连接参数具有可配置性是比较重要的,这样如果迁移到其他的数据库也比较方便,而且代码更易于维护,代码与数据库连接参数完全分离。
具体做法:
1. 将所有的数据库连接参数配置在web.xml文件中,当然也可以写在db.properties属性文件中,文件名db可以随便改。例如:
<!-- 数据库连接参数的可配置性 -->
<context-param>
<param-name>dburl</param-name>
<param-value>jdbc:mysql://localhost/tyy</param-value>
</context-param>
<context-param>
<param-name>username</param-name>
<param-value>root</param-value>
</context-param>
<context-param>
<param-name>password</param-name>
<param-value>passwd</param-value>
</context-param>
<context-param>
<param-name>driver</param-name>
<param-value>com.mysql.jdbc.Driver</param-value>
</context-param>
这样,就将所有的数据库连接参数配置到了web应用中,下面就看怎样读取这些配置信息,从而来连接数据库
2. 编写工具类Config.java 和 AppListener.java
Config.java 的代码如下:
package com.tyy.news.db;
import java.util.HashMap;
import java.util.Map;
public class Config {
private static Config instance;
private Map<String, String> map = new HashMap<String, String>();
// 通过一个Map来存储配置信息
static { //初始化Config,使用单例,保持其在应用期间只有一个实例,避免不必要的内存损耗
if (instance == null) {
instance = new Config();
}
}
private Config() {
}
public static Config getInstance() { //静态工厂方法获取Config实例
return instance;
}
/**
* 由于在容器初始化的时候map的值已经被初始化,且值在运行期间也不会改变,故不需要
* 考虑addKeyValue()和getValue()的同步性.
* @param key
* @param value
*/
public void addKeyValue(String key, String value) {
map.put(key, value);
}
public String getValue(String key) {
return map.get(key);
}
public Map<String, String> getMap() {
return map;
}
}
AppListener.java代码如下:该类必须实现javax.servlet.ServletContextListener接口
package com.tyy.news.db;
import java.util.Enumeration;
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class AppListener implements ServletContextListener {
public void contextDestroyed(ServletContextEvent event) {
System.out.println("============contextDestroyed()================");
}
/**
* 读取web.xml中的初始化信息,并将其放入Config对象中map里面,从而达到全局调用。
* 在容器初始化的时候,肯定会调用该方法,故在该方法中对这些数据进行初始化是比较合适的。
*/
public void contextInitialized(ServletContextEvent event) {
System.out.println("before contextInitialized");
ServletContext context = event.getServletContext();
Config config = Config.getInstance();
Enumeration<String> parameters = context.getInitParameterNames();
while(parameters.hasMoreElements()) {
String parameter = parameters.nextElement();
config.addKeyValue(parameter, context.getInitParameter(parameter));
}
System.out.println("map.size() = > " + config.getInstance().getMap().size());
System.out.println("after contextInitialized");
}
}
AppListener是一个过滤器,故需要在web.xml中进行注册
<listener>
<listener-class>com.tyy.news.db.AppListener</listener-class>
</listener>
AppListener主要是在容器启动的时候,自动读取web.xml中的配置信息,并以此来初始化Config对象的内部数据结构,也即一个Map。这样在整个应用期间,都可以通过此Map来获取信息。
3. 编写数据库连接类
public static Connection getConnection() {
// 不通过容器的话,Config.getInstance()所获得实例则是另外的实例,其中的Map数据结构为空,也即取不到任何有用的信息,全部都为空,这也是为什么无法脱离容器的原因。
String DBURL = Config.getInstance().getValue("dburl");
String USERNAME = Config.getInstance().getValue("username");
String PASSWORD = Config.getInstance().getValue("password");
String DRIVER = Config.getInstance().getValue("driver");
Connection conn = null;
try {
Class.forName(DRIVER);
conn = DriverManager.getConnection(DBURL, USERNAME, PASSWORD);
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
可以通过这种方式来获得数据库连接,但是此连接不可以脱离容器,也即如果通过下面这种方法进行测试的话,会返回错误的结果。
/**
* 此处测试不成功,说明不能够脱离容器进行测试。所有的连接参数都在容器初始化的时候从web.xml中
* 取出来,而单独运行的话,则无法获得这些连接参数,故会出现java.lang.NullPointException异常
* @param args
*/
public static void main(String[] args) {
System.out.println("conn => " + DBConnection.getConnection());
}
这样获得的数据库简介会不能够脱离容器的,因为一旦离开容器,所有的值都无法从数据库中获得。
接下来就可以利用数据库的连接来进行一系列的CRUD操作了。
使用web.xml文件来配置数据库连接参数的目的也达到了。
数据库参数的可配置性(dbinfo.properties)
1. 类似使用web.xml文件,只需要将其中的连接参数放入属性文件中即可,这次是放在了dbinfo.properties中,当然可以改名
dbinfo.properties文件内容如下:我使用的是Access数据库,通过配置数据源来实现的
dburl = jdbc:odbc:newspublish
driver = sun.jdbc.odbc.JdbcOdbcDriver
接下来编写AppListener文件,该文件用来读取配置信息,当然相对于之前的读取方式会有所不同,但原理还是一致的。该类必须实现javax.servlet.ServletContextListener接口
内容如下:
package com.tyy.news.db;
import java.util.Enumeration;
import java.util.ResourceBundle;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
public class AppListener implements ServletContextListener {
public void contextDestroyed(ServletContextEvent event) {
System.out.println("============contextDestroyed()================");
}
/**
* 读取dbinfo.properties中的初始化信息,并将其放入Config对象中map里面,从而达到全局调用。
* 在容器初始化的时候,肯定会调用该方法,故在该方法中对这些数据进行初始化是比较合适的。
*/
public void contextInitialized(ServletContextEvent event) {
Config config = Config.getInstance();
ResourceBundle rb = ResourceBundle.getBundle("dbinfo");
Enumeration<String> parameters= rb.getKeys();
while(parameters.hasMoreElements()) {
String parameter = parameters.nextElement();
config.addKeyValue(parameter, rb.getString(parameter));
}
}
}
java.util.ResourceBundle是用来读取属性文件的,相信用过国际化的人都知道该类。
其中包含了一系列读取国际化资源文件的方法,此处并没有使用这些,只是简单的使用了其查找属性文件并读取之的功能。
Config类并没有任何的改变。
接下来就是在数据库连接类中来建立数据库连接了。方法也和之前的相似。
public static Connection getConnection() {
String DBDRIVER = Config.getInstance().getValue("driver");
String DBURL = Config.getInstance().getValue("dburl");
Connection conn = null;
try {
Class.forName(DBDRIVER);
conn = DriverManager.getConnection(DBURL);
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
这样,就获得了数据库连接。通过属性文件来加载数据库配置信息也完成了。
当然获得数据库配置参数的方式还有很多种,很多种框架(如Hibernate)都提供了非常优秀的解决方法,但目的都是达到分离的作用。
此种方法也可以用在类似的实现的配置与代码分离的功能。
- 数据库参数的可配置性
- zebra_dialog简介可配置的全部参数
- 查询jvm可配置的参数
- grails 中实现数据库的可配置
- oracle配置可查询的数据库
- 18.1.1 SHTTPD启动参数可动态配置的需求
- 实现一个可配置的java web 参数验证器
- spring中的web.xml可配置的参数
- cmake配置c++可调用的文件路径参数
- 获得Z-WAVE产品的完整可配置参数列表
- 工厂模式:dsn参数值配置为mysql时,可连接mysql数据库【练习】
- 一个自动回调+可动态配置php参数+可暂停/继续的框架
- grails 中实现数据库的可配置(二)
- MySQL数据库参数配置
- mysql 数据库参数配置
- 数据库的备份与还原+INI文件数据库参数配置
- 论Oracle数据库的可移植性
- 数据库 - 并发调度的可串行性
- Apache和Subversion集成安装与配置
- VB做IE插件1 BHO
- buildbot的master.cfg 文件分析
- JAVA技术交流(学习群):51194570;JAVA技术交流(应用群):51194804
- 几个免费的文献数据库密码
- 数据库参数的可配置性
- 多个config文件导致的编译错误
- WebService 在传回 ArrayList 时说: XML 文档时出错
- 一个基于命令行的“距离变换”的实现
- 我失恋了
- 网上很多Rose2003的破解方式都无效,下面是几经尝试发现的方法。
- Linux下JNI参数中文字符串的处理
- 想考MCSE CCNA的朋友进来拿一份。。。
- Matlab的函数及指令一览表