数据库连接池的基本思想就是为数据库连接建立一个“缓冲池”。预先在缓冲池中放入一定数量的连接(预加载),当需要建立数据库连接时,只需从“缓冲池”中取出一个,使用完毕之后再放回去。
我们可以通过设定连接池最大连接数来防止系统无尽的与数据库连接。更为重要的是我们可以通过连接池的管理机制监视数据库的连接的数量﹑使用情况,为系统开发﹑测试及性能调整提供依据。
数据库连接有很多中方式,JDBC数据库的连接方式,前边我们已经介绍过了,而开发中我们经常使用的是DataBaseConnectionPool(数据库连接池,DBCP)。数据库连接池到底是什么?它比jdbc数据库连接有什么优势呢?它又怎么使用呢?
一,先看一下JDBC连接,每次用户访问数据库时,需要JDBC为我们创建数据库连接,我们使用,然后关闭。而当我们加断点测试,可以发现这个过程中创建数据库连接这个过程是比较费时间的,而不是我们在数据库中操作数据费时间。所以JDBC这种方式的效率大大折扣。而且如果过多的人同时并发来访问数据库,连接数量创建过多,会导致性能降低,更严重可能会导致数据库崩溃。而,数据库连接池就是来解决这两种问题的。
二,数据库连接池是什么?
顾名思义就是盛放多个数据库连接的一个池子!当我们访问数据库时我们直接从这个池子中拿连接对象即可,省去了初始化创建的过程,大大提高了效率。而且这个池子可以控制数据库连接的数量,我们里边可以至少放上几个,不够用了再进行创建,最多能够创建几个等等来控制连接的数量。它就是这么一个技术。准确一点说,连接池是一种缓存技术(cache),因为这个池子是在缓存中存放的。
三,连接池的优势呢?
其实就是解决了JDBC的劣势。提前准备好连接对象,提高了访问效率,控制连接数量,防止同时过多用户访问导致性能大大降低,数据库崩溃。
四,DBCP怎么使用?
编写数据库连接池是比较麻烦的,而且编写出来的效果如何另说。所以一般我们都使用现成的。各种服务器都为我们提供了,这里先看一下Tomcat服务器的数据库连接池如何使用。
1,在tomcat的catalina_home/webapps/webapp/meta-inf/目录下新建context.xml文件,来编写DBCP,这是针对此应用程序的(当然也可以之间在tomcat的catalina_home/conf/context.xml中编写,这个这个是针对这个tomcat服务器的),编写内容如下:
#数据库驱动
driverClassName=com.mysql.jdbc.Driver
#数据库连接地址
url=jdbc:mysql://localhost/test
#用户名
username=root
#密码
password=123456
#连接池的最大数据库连接数。设为0表示无限制
maxActive=30
#最大空闲数,数据库连接的最大空闲时间。超过空闲时间,数据库连
#接将被标记为不可用,然后被释放。设为0表示无限制
maxIdle=10
#最大建立连接等待时间。如果超过此时间将接到异常。设为-1表示无限制
maxWait=1000
#超过removeAbandonedTimeout时间后,是否进行没用连接(废弃)的回收(默认为false,调整为true)
removeAbandoned=true
#超过时间限制,回收没有用(废弃)的连接(默认为 300秒)
removeAbandonedTimeout=180
大家可以通过名字看出,这都是在设置dbcp的各个属性,例如,最大连接数,最小连接数,最长等待时间等等,设置好以后我们就可以使用了。
那么怎么使用呢?这里就涉及到了JNDI,JNDI是J2EE13个规范之一,也是非常重要的。这里我来先简单介绍一下JNDI:
由于只是简单了解,要想了解更多关于JNDI的资料,请查看:JNDI是什么 JNDI简介 tomcat配置JNDI
//获取JNDI的上下文对象Context
Context context = new InitialContext();
//根据名称和资源的绑定来获取数据源连接池,其中java:/com/env是tomcat实现JNDI的路径,后边是我们连接池名字
DataSource ds = (DataSource)context.lookup("java:/comp/env/jdbc/ljh");
//get,获取一种的一个连接,当然下边的close就是返回一个连接给连接池,这里的连接池都对Connection中的方法进行重写,例如close,是返回给连接池,而不是关闭数据库连接。
conn = ds.getConnection();
这样我们就可以使用连接对象了。
综上为连接池DBCP和JNDI的联合使用访问数据库。在实际开发中我们经常使用C3P0连接池,因为它开源的,而且和各种框架一起使用非常方便,效率也更高。不过原理跟上边的差不多,都是依赖JDBC规范和JNDI规范,来实现的,这里看一些它的资料吧! C3P0英文文档 C3p0百科
综上为数据库连接,顺便简单总结了一下JNDI。数据库连接在每个系统中都会使用,虽然可能就需要我们配置一次,编写一次,但是是非常重要的,因为数据的安全是非常重要的哈。所以还是需要我们好好掌握的。
-------------------------------------------------------------------------------------------------------------------------------------------------------
然后在tomcat目录/conf/server.xml文件里相应的
JNDI是J2EE中一个很重要的标准,通常我们是在EJB编程中用到,
Tomcat4.0中提供了在JSP和Servelt中直接使用JNDI的方法,下面谈一下在Tomcat4.0中配置和使用JNDI的方法
(以通过JNDI连接数据库为例)
假设使用的数据库是mysql,实验例子在TOMCAT_HOME/webapps/DBTest目录中
A.将mysql的JDBC连接库mm.mysql-2.0.9-bin.jar放入TOMCAT_HOME/common/lib中
B.配置TOMCAT_HOME/conf/serer.xml文件在
需要注意的是JNDI NAME要在前面加上"java:comp/env/"
package com.bluedot.jclg.util;
import java.sql.Connection;
import java.sql.SQLException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
public class DBUtil {
public static Connection getConnection(){
Connection conn=null;
try {
//初始化容器
Context ctx=new InitialContext();
//通过容器来查找容器中的数据源,注意,必须按照制定的目录java:comp/env,最后一个zyy随便写
DataSource ds=(DataSource)ctx.lookup("java:comp/env/sunvsjay");
//从数据源中获取一个空闲的连接
conn=ds.getConnection();
} catch (NamingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return conn;
}
}
http://www.javaweb1024.com/java/JavaWebzhongji/2015/06/01/736.html
借鉴,http://blog.csdn.net/cyxlzzs/article/details/7352837
JDBC编程步骤:
----java与Oracle数据的连接(lomboz_eclipse环境下)
1.在Oracle数据库安装文件夹中找到jdbc文件夹→lib文件夹→classesl2.jar
2.lomboz_eclipse中导入此Jar包
导入方法:
建立一个项目,在项目名称上右键鼠标选择Build Path→Add External Archives→
选择classesl2.jar进行导入
3.新建一程序编写与Oracle连接的代码
步骤如下:
1.实例话驱动类
class.forName("Oracle.jdbc.driver.OracleDriver");
2.建立到数据库的连接
Connection conn = DriverManager.getConnection("jdbc:oracle:thin:
@192.168.8.1:1521:yuewei","scott","tiger");
3.将数据发送到数据库中
Statement stm = conn.CreatStatement();
4.执行语句(select语句)
ResultSet rs = stm.executeQuery(select * from dept);
5.显示语句
rs.getString("deptno");
import java.sql.*;
public class TestJDBC {
public static void main(String[] args) {
ResultSet rs = null;
Statement stmt = null;
Connection conn = null;
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
//new oracle.jdbc.driver.OracleDriver();
conn = DriverManager.getConnection("jdbc:oracle:thin:@192.168.0.1:1521:yuewei", "scott", "tiger");
stmt = conn.createStatement();
rs = stmt.executeQuery("select * from dept");
while(rs.next()) {
System.out.println(rs.getString("deptno"));
//System.out.println(rs.getInt("deptno"));
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if(rs != null) {
rs.close();
rs = null;
}
if(stmt != null) {
stmt.close();
stmt = null;
}
if(conn != null) {
conn.close();
conn = null;
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
元素名 |
属性 |
解释 |
server |
port |
指定一个端口,这个端口负责监听关闭tomcat 的请求 |
shutdown |
指定向端口发送的命令字符串 |
|
service |
name |
指定service 的名字 |
Connector ( 表示客户端和service之间的连接) |
port |
指定服务器端要创建的端口号,并在这个端口监听来自客户端的请求 |
minProcessors |
服务器启动时创建的处理请求的线程数 |
|
maxProcessors |
最大可以创建的处理请求的线程数 |
|
enableLookups |
如果为true ,则可以通过调用request.getRemoteHost() 进行DNS 查询来得到远程客户端的实际主机名,若为false 则不进行DNS 查询,而是返回其ip 地址 |
|
redirectPort |
指定服务器正在处理http 请求时收到了一个SSL 传输请求后重定向的端口号 |
|
acceptCount |
指定当所有可以使用的处理请求的线程数都被使用时,可以放到处理队列中的请求数,超过这个数的请求将不予处理 |
|
connectionTimeout |
指定超时的时间数( 以毫秒为单位) |
|
Engine ( 表示指定service 中的请求处理机,接收和处理来自Connector的请求) |
defaultHost |
指定缺省的处理请求的主机名,它至少与其中的一个host 元素的name 属性值是一样的 |
Context ( 表示一个web 应用程序,通常为WAR 文件,关于WAR 的具体信息见servlet 规范) |
docBase |
应用程序的路径或者是WAR 文件存放的路径 |
path |
表示此web 应用程序的url 的前缀,这样请求的url为http://localhost:8080/path/ **** |
|
reloadable |
这个属性非常重要,如果为true ,则tomcat 会自动检测应用程序的/WEB-INF/lib 和/WEB-INF/classes 目录的变化,自动装载新的应用程序,我们可以在不重起tomcat 的情况下改变应用程序 |
|
host ( 表示一个虚拟主机 ) |
name |
指定主机名 |
appBase |
应用程序基本目录,即存放应用程序的目录 |
|
unpackWARs |
如果为true ,则tomcat 会自动将WAR 文件解压,否则不解压,直接从WAR 文件中运行应用程序 |
|
Logger ( 表示日志,调试和错误信息) |
className |
指定logger 使用的类名,此类必须实现org.apache.catalina.Logger 接口 |
prefix |
指定log 文件的前缀 |
|
suffix |
指定log 文件的后缀 |
|
timestamp |
如果为true ,则log 文件名中要加入时间,如下例:localhost_log.2001-10-04.txt |
|
Realm ( 表示存放用户名,密码及role 的数据库) |
className |
指定Realm 使用的类名,此类必须实现org.apache.catalina.Realm 接口 |
Valve ( 功能与Logger 差不多,其prefix 和suffix 属性解释和Logger 中的一样) |
className |
指定Valve 使用的类名,如用org.apache.catalina.valves.AccessLogValve 类可以记录应用程序的访问信息 |
directory |
指定log 文件存放的位置 |
|
pattern |
有两个值,common 方式记录远程主机名或ip 地址,用户名,日期,第一行请求的字符串,HTTP 响应代码,发送的字节数。combined 方式比common 方式记录的值更多 |
2. Tomcat处理一个HTTP请求的过程
假设来自客户的请求为: http://localhost:8080/wsota/wsota_index.jsp
1) 请求被发送到本机端口8080,被在那里侦听的Coyote HTTP/1.1 Connector获得
2) Connector把该请求交给它所在的Service的Engine来处理,并等待来自Engine的回应
3) Engine获得请求localhost/wsota/wsota_index.jsp,匹配它所拥有的所有虚拟主机Host
4) Engine匹配到名为localhost的Host(即使匹配不到也把请求交给该Host处理,因为该Host被定义为该Engine的默认主机)
5) localhost Host获得请求/wsota/wsota_index.jsp,匹配它所拥有的所有Context
6) Host匹配到路径为/wsota的Context(如果匹配不到就把该请求交给路径名为""的Context去处理)
7) path="/wsota"的Context获得请求/wsota_index.jsp,在它的mapping table中寻找对应的servlet
8) Context匹配到URL PATTERN为*.jsp的servlet,对应于JspServlet类
9) 构造HttpServletRequest对象和HttpServletResponse对象,作为参数调用JspServlet的doGet或doPost方法
10)Context把执行完了之后的HttpServletResponse对象返回给Host
11)Host把HttpServletResponse对象返回给Engine
12)Engine把HttpServletResponse对象返回给Connector
13)Connector把HttpServletResponse对象返回给客户browser
Tomcat下部署多个项目
在service标签下面写一个service标签。复制上面service,再修改里面的端口号为8081。
-------------------------------------------------------------------------------------------------------------------------
同一服务器部署多个tomcat时,存在端口号冲突的问题,所以需要修改tomcat配置文件server.xml,以tomcat7为例。
其中8080为HTTP端口,8443为HTTPS端口
8005为远程停服务端口
8009为AJP端口,APACHE能过AJP协议访问TOMCAT的8009端口。
2.远程停服务端口,默认8005,如下改为8006
3.AJP端口,默认8009,如下改,8010