- 使用传统的数据库连接方式,有以下缺点
所以我们使用连接池来优化数据库连接,其原理如下。每次的连接不是直接和数据库进行交互,而是从连接池里面拿,这样减少了和数据库交互的次数,提高了效率
现在很多WEB服务器(Weblogic, WebSphere, Tomcat)都提供了DataSoruce的实现,即连接池的实现。通常我们把DataSource的实现,按其英文含义称之为数据源,数据源中都包含了数据库连接池的实现
- DBCP 是 Apache 软件基金组织下的开源连接池实现,使用DBCP数据源,应用程序应在系统中增加如下两个 jar 文件:
Commons-dbcp.jar:连接池的实现
Commons-pool.jar:连接池实现的依赖库
Tomcat 的连接池正是采用该连接池来实现的。该数据库连接池既可以与应用服务器整合使用,也可由应用程序独立使用 - 第一种连接方式:;使用连接池和属性配置文件来连接数据库。这里属性配置文件里面写数据库连接的URL,账号,密码等,然后通过反射机制加载到类中,从而连接数据库
- 创建一个类,类里面实现数据库的连接与断开
package com.z.JdbcUtils;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSourceFactory;
public class Jdbc {
private static DataSource ds;
static{
try {
Properties pro=new Properties();//加载属性配置文件
InputStream in=Jdbc.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");//读文件
pro.load(in);//加载,发生关系
//创建一个基本的数据源工厂
BasicDataSourceFactory bdsf=new BasicDataSourceFactory();
ds=bdsf.createDataSource(pro);
} catch (Exception e) {
throw new ExceptionInInitializerError(e);
}
}
public static Connection getConnection() throws SQLException{
return ds.getConnection();
}
//从数据库连接池里面获取链接
public static void main(String[] args) throws SQLException {
System.out.println(getConnection());
}
//关闭数据库,此时这的关闭不是真正的关闭链接,而是归还到池中
public static void close(ResultSet rs,Statement st,Connection con){
try {
if(rs!=null) rs.close();
} catch (SQLException e) {
throw new RuntimeException();
}finally{
try {
if(st!=null) st.close();
} catch (SQLException e) {
throw new RuntimeException();
}finally{
try {
if(con!=null) con.close();
} catch (SQLException e) {
throw new RuntimeException();
}
}
}
}
}
- 创建属性配置文件,配置路径,密码,账号,连接池最小连接数,最大连接数等
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test
password=
username=root
initialSize=10
maxActive=50
maxIdle=20
minIdle=5
maxWait=60000
- 运行如果报的错误是java.lang.NoClassDefFoundError: org/apache/commons/pool/impl/GenericObjectPool
在网上查找错误的原因,说是缺少了一个commons-pool.jar文件
在myeclipse的安装目录下搜索,得到这个文件.放进lib文件夹.
数据库连接需要一个Jar包,连接池DBCP需要两个Jar包,都需要放在项目的webroot下的lib包底下。
- 第二种连接方式:通过Tomcat访问页面时,从连接池里面获得连接。
- 先把上一种方法中提出的那三个Jar包放到Tomcat下的lib目录下。
D:\Tomcat6.0\lib
在D:\Tomcat6.0\conf下的server.xml中配置
<Context path="/toncatdbcp">
<Resource name="jdbc/datasource"
auth="Container"
username="root"
password=""
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/test"
maxActive="8"
maxIdle="4" />
</Context>
写Jdbc
package com.z.dbcp;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
public class Jdbc {
private static DataSource ds;
static{
try {
//创建一个大容器
Context initCtx = new InitialContext();
//创建一个子容器
Context envCtx = (Context) initCtx.lookup("java:comp/env");
//获取链接池资源,就是连接池对象
ds=(DataSource) envCtx.lookup("jdbc/datasource");
} catch (NamingException e) {
throw new ExceptionInInitializerError(e);
}
}
public static Connection getConnection() throws SQLException{
return ds.getConnection();
}
//从数据库连接池里面获取链接
public static void main(String[] args) throws SQLException {
System.out.println(getConnection());
}
//关闭数据库,此时这的关闭不是真正的关闭链接,而是归还到池中
public static void close(ResultSet rs,Statement st,Connection con){
try {
if(rs!=null) rs.close();
} catch (SQLException e) {
throw new RuntimeException();
}finally{
try {
if(st!=null) st.close();
} catch (SQLException e) {
throw new RuntimeException();
}finally{
try {
if(con!=null) con.close();
} catch (SQLException e) {
throw new RuntimeException();
}
}
}
}
}
- x写servlet测试
package com.z.servlet;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.SQLException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.z.dbcp.Jdbc;
public class JdbcServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}
@Override
protected void service(HttpServletRequest resquest, HttpServletResponse response)
throws ServletException, IOException {
try {
Connection con=Jdbc.getConnection();
System.out.println(con);
} catch (SQLException e) {
e.printStackTrace();
}
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
}
}
这种方式没次都需要重启服务器,而且server.xml里面的项目名是写死的,每次都需要改,所以特别不方便,不推荐使用。
- 第三种方式:
1,还是把那三个Jar包放到Tomcat的lib下面,供所有项目访问,不过也可以放到自己的项目lib下面,这样的话只有你自己才能用。
2,在webroot下的MEAT-INF下创建context.xml文件,在里面配置数据库连接
<Context>
<Resource name="jdbc/datasource"
auth="Container"
type="javax.sql.DataSource"
username="root"
password=""
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql://localhost:3306/test"
maxActive="8"
maxIdle="4"/>
</Context>
3,做jdbc
package com.z.dbcp;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
public class Jdbc {
private static DataSource ds;
static{
try {
//创建一个大容器
Context initCtx = new InitialContext();
//创建一个子容器
Context envCtx = (Context) initCtx.lookup("java:comp/env");
//获取链接池资源,就是连接池对象
ds=(DataSource) envCtx.lookup("jdbc/datasource");
} catch (NamingException e) {
throw new ExceptionInInitializerError(e);
}
}
public static Connection getConnection() throws SQLException{
return ds.getConnection();
}
//从数据库连接池里面获取链接
public static void main(String[] args) throws SQLException {
System.out.println(getConnection());
}
//关闭数据库,此时这的关闭不是真正的关闭链接,而是归还到池中
public static void close(ResultSet rs,Statement st,Connection con){
try {
if(rs!=null) rs.close();
} catch (SQLException e) {
throw new RuntimeException();
}finally{
try {
if(st!=null) st.close();
} catch (SQLException e) {
throw new RuntimeException();
}finally{
try {
if(con!=null) con.close();
} catch (SQLException e) {
throw new RuntimeException();
}
}
}
}
}
4,测试同上面的测试方法。
使用这种方法有个好处就是不用重启服务器,而且也可以在context.xml里面写入oracle的数据库连接,想要连接的时候直接在下图红色位置吧oracle的连接名字写进去,或者想要用哪个类的时候,直接在这个文件里面拿,也是非常的方便
上面三种方式还用到了JNDI技术
JNDI(Java Naming and Directory Interface),Java命名和目录接口,它对应于Java SE中的javax.naming包,
这套API的主要作用在于:它可以把Java对象放在一个容器中(JNDI容器),并为容器中的java对象取一个名称,以后程序想获得Java对象,只需通过名称检索即可。
其核心API为Context,它代表JNDI容器,其lookup方法为检索容器中对应名称的对象。JNDI的出现,让程序员和数据库的耦合降低!