为什么使用数据源
主要是方便管理
1 你肯定要链接数据库
2 那么你肯定要用户名和密码
3 正式的数据库和应用服务器应该是单独的人员管理,而不是开发人员
4 密码会定期修改
5 如果链接数据库是各自书写代码和配置,则运行环境的密码修改将会是一个噩梦,一不小心就忘记一个
6 所以,大家全部到一个数据源那里获取连接。管理员只需要修改数据源的配置,而无需修改应用的配置
7 如果数据库的地址变更,则同样不会影响到应用,也只是修改数据源
8 开发人员无需知道正式数据库的密码
-----------------------------------------------------
在配置项中,我们使用数据源来表示对应的数据库连接。使用数据源有两个好处:对开发人员屏蔽数据库细节,只要通过JNDI取得数据源就可以了,无需关心数据库连接是如何建立的;数据源通常都提供了数据库连接池的功能。
数据库连接是一种关键的有限的昂贵的资源,而且数据库连接的建立和关闭也是很耗费系统资源的。在传统的两层C/S架构中,一个客户端对应一个数据库连接,在用户活动期间就独占此连接;而在分布式系统中,数据库连接的建立与关闭是异常频繁的,因此数据库连接的对系统的性能影响更是明显。对数据库连接的管理能显著影响到整个应用程序的伸缩性和健壮性,影响到程序的性能指标。数据库连接池正是针对这个问题提出来的。
数据库连接池在初始化时将创建一定数量的数据库连接放到连接池中,这些数据库连接的数量是由最小数据库连接数来设定的。数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而再不是重新建立一个;释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏。无论这些数据库连接是否被使用,连接池都将一直保证至少拥有这么多的连接数量。连接池的最大数据库连接数量限定了这个连接池能占有的最大连接数,当应用程序向连接池请求的连接数超过最大连接数量时,这些请求将被加入到等待队列中。
JDBC3.0规范中规定了如下的接口和类来实现数据库连接池:
javax.sql.ConnectionEvent:连接事件
javax.sql.ConnectionPoolDataSource:连接池数据源
javax.sql.PooledConnection:被池化的连接
javax.sql.ConnectionEventListener:连接事件监听接口
上边这些接口和类是对数据库连接池内部实现的规定,对于使用者来说是透明的。数据库连接池的使用者一般只和DataSource接口直接打交道,通过这个接口获得数据库连接,其主要方法为:
Connection getConnection():得到一个数据库连接
Connection getConnection(String userName,String password):得到一个数据库连接
java.io.PrintWriter getLogWriter():获得Log Writer的对象
void setLogWriter(java.io.PrintWriter out):设置Log Writer
void setLoginTimeout(int seconds):设置数据源尝试连接数据库的最大时间
int getLoginTimeout():获得数据源尝试连接数据库的最大时间
开源社区中有很多数据库连接池的实现,比如PoolMan等,使用这些数据库连接池包可以保证跨应用服务器的移植。不过在本案例系统中,我们使用应用服务器的数据源功能提供的数据库连接池。数据源在不同的服务器中有不同的配置方式,下面介绍Tomcat中数据源的配置。
打开%TOMCAT_HOME%\conf\server.xml,在</Context>和</host>前添加如下配置文件项:
<Context docBase="CowNewPIS" path="/CowNewPIS" reloadable="true">
<Resource type="javax.sql.DataSource"
auth="Container" name="jdbc/PISMSSQL_Dev" />
<ResourceParams name="jdbc/PISMSSQL_Dev">
<parameter>
<name>maxWait</name>
<value>5000</value>
</parameter>
<parameter>
<name>maxActive</name>
<value>4</value>
</parameter>
<parameter>
<name>password</name>
<value></value>
</parameter>
<parameter>
<name>url</name>
<value>
jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=PISDev1106
</value>
</parameter>
<parameter>
<name>driverClassName</name>
<value>
com.microsoft.jdbc.sqlserver.SQLServerDriver
</value>
</parameter>
<parameter>
<name>maxIdle</name>
<value>2</value>
</parameter>
<parameter>
<name>username</name>
<value>sa</value>
</parameter>
</ResourceParams>
</Context>
在配置的时候,要指定数据库的JDBC驱动、数据库连接URL等。数据源配置完毕,重启服务器。编写一个测试客户端:
Context ctx=null;
Connection conn=null;
try
{
ctx=new InitialContext();
DataSource ds=(DataSource)ctx.lookup("java:comp/env/jdbc/PISMSSQL_Dev");
conn=ds.getConnection();
}
finally
{
if(conn!=null)
conn.close();
if(ctx!=null)
ctx.close();
}
Tomcat启动的时候会将Server.xml中的数据源配置绑定到JNDI中,我们可以在应用服务器启动的时候用代码来代替Tomcat完成绑定:
BasicDataSource bdds = new BasicDataSource();
//设置数据库驱动
bdds.setDriverClassName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
//设置JDBC的URL
bdds.setUrl("jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=PISDev1106");
bdds.setUsername("sa");
//设置连接池初始大小
bdds.setInitialSize(2);
//JNDI配置
Map env = new Hashtable();
env.put("java.naming.factory.initial",
"org.apache.naming.java.javaURLContextFactory");
InitialContext ctx=new InitialContext(env);
//数据源绑定到JNDI
ctx.bind("jdbc/PISMSSQL_Dev",bdds);
这样我们可以把数据源的配置文件移到ServerConfig.xml中,增加类似如下的配置:
<DataSources>
<DataSource
name=”jdbc/PISMSSQL_Dev” driverClassName=”com.microsoft.jdbc.sqlserver.SQLServerDriver”
url=”jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=PISDev1106”
userName=”sa”
>
</DataSource>
</DataSources>
在应用服务器启动的时候,到ServerConfig.xml中读取数据源配置完成绑定。这种方式一是减少了实施人员配置文件的工作量,服务端的任何配置都可以在这个配置文件中完成;二是使得系统在不同服务器之间移植变得更加容易。