public class DBManager { private Connection con = null;
private DataSource ds = null;
private static DBManager instance = null; private DBManager() {
try {
Context context = new InitialContext();
ds = (DataSource) context.lookup("java:comp/env/ams");
} catch (NamingException e) {
System.err.println("???????命名空间异常");
e.printStackTrace();
}
} public static DBManager getInstance() {
if (instance == null)
instance = new DBManager();
return instance;
} public Connection getConnection() throws SQLException { try {
con = ds.getConnection();
con.setAutoCommit(false);
} catch (SQLException e) {
con.rollback();
System.out.println("can't get connection!");
throw e;
}
return con;
} public void close(PreparedStatement ps, ResultSet rs) {
if (con != null) {
try {
con.close();
ps.close();
rs.close();
} catch (SQLException e) {
} finally {
ps = null;
rs = null;
con = null;
}
}
} public void close(Statement st, ResultSet rs) {
if (con != null) {
try {
con.close();
st.close();
rs.close();
} catch (SQLException e) {
} finally {
st = null;
rs = null;
con = null;
}
}
} public void close(PreparedStatement ps) {
if (con != null) {
try {
con.close();
ps.close();
} catch (SQLException e) {
} finally {
ps = null;
con = null;
}
}
}
}这个数据库连接池能够连接成功,只是似乎同时只能连接两个客户端,不知道该怎么修改啊!似乎是单例出错了....有标准的通用类给我一个也行啊,谢谢了!
private static DBManager instance = null;
public synchronized static DBManager getInstance() {
if (instance == null)
instance = new DBManager();
return instance;
}
}
方法加同步,影响性能。
方法不加同步这么写
private static DBManager instance =new DBManager();
public synchronized static DBManager getInstance() {
return instance;
}
if (instance == null)
synchronized if(instance == null) {
instance = new DBManager();
return instance;
}
}
} 这样写可以吧
if (instance == null)
synchronized(this) {
if(instance == null) {
instance = new DBManager();
return instance;
}
}
}
}
这样哈
/*
* ConnectionPool.java
*
* Created on 2007年10月27日, 下午1:18
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/package connPool;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Vector;
import java.util.Enumeration;
import java.util.Iterator;/**
*
* @author jim
*/
public class ConnectionPool {
private volatile static ConnectionPool connPool;
private String jdbcDriver="com.mysql.jdbc.Driver"; //数据库驱动
private String dbUrl="jdbc:mysql://127.0.0.1:3306/chtx"; //数据库url
private String dbUser="chtx"; //数据库用户
private String dbPwd="chtx"; //数据库密码
private String testTable="test"; //要测试的数据库表
private int initConnectionSize=10; //连接池初始大小
private int incConnectionSize=5; //一次自增连接池大小
private int maxConnectionSize=50; //最大连接池大小
private Vector connections=null; //存放数据库连接对象
/**
* 构造函数<br>
* 按默认的参数创建连接池
*/
private ConnectionPool()
{
}
/**
* 构造函数
*
* @param jdbcDriver String 数据库驱动
* @param dbUrl String 数据库url
* @param dbUser String 数据库用户
* @param dbPwd String 数据库密码
*/
private ConnectionPool(String jdbcDriver,String dbUrl,String dbUser,String dbPwd)
{
this.jdbcDriver=jdbcDriver;
this.dbUrl=dbUrl;
this.dbUser=dbUser;
this.dbPwd=dbPwd;
try {
createPool();
} catch (Exception ex) {
ex.printStackTrace();
}
}
/**
* 生成唯一实例
*/
public static ConnectionPool getInstance()
{
if(connPool == null)
{
synchronized (ConnectionPool.class)
{
if(connPool == null)
{
connPool=new ConnectionPool();
}
}
try {
connPool.createPool();
} catch (Exception ex) {
ex.printStackTrace();
}
}
return connPool;
}
/**
* 设置测试数据表
*
* @param testTable String 要测试的数据表
*/
public void setTestTable(String testTable)
{
this.testTable=testTable;
}
/**
* 返回测试数据表
*
* @return testTable String 测试数据表
*/
public String getTestTable()
{
return this.testTable;
}
/**
* 设置连接池初始大小
*
* @param initConnectionSize int 初始大小
*/
public void setInitConnectionSize(int initConnectionSize)
{
this.incConnectionSize=initConnectionSize;
}
/**
* 返回初始连接池大小
*
* @return 返回int类型
*/
public int getInitConnectionSize()
{
return this.initConnectionSize;
}
/**
* 设置连接池一次性自增数大小
*
* @param incConnectionSize int 自增数
*/
public void setIncConnectionSize(int incConnectionSize)
{
this.incConnectionSize=incConnectionSize;
}
/**
* 返回连接池一次性自增数大小
*
* @return 返回int类型
*/
public int getIncConnectionSize()
{
return this.incConnectionSize;
}
/**
* 设置最大连接池大小
*
* @param maxConnectionSize int 最大连接池大小
*/
public void setMaxConnectionSize(int maxConnectionSize)
{
this.maxConnectionSize=maxConnectionSize;
}
/**
* 返回最大连接池大小
*
* @return 返回int类型
*/
public int getMaxConnectionSize()
{
return this.maxConnectionSize;
}
/**
* 关闭数据库连接对象
*
* @param conn Connection 数据库连接对象
*/
public void closeConnection(Connection conn)
{
try {
conn.close();
System.out.println("The connection is close ...");
} catch (SQLException ex) {
System.out.println("Close failure of the database connection object ...");
conn=null;
ex.printStackTrace();
}
}
/**
* 测试连接池中的连接对象是否可用
* false不可用销毁该连接,true可用
*
* @param conn Connection 数据库连接对象
* @return boolean
*/
public boolean testConnection(Connection conn)
{
try {
//是否有测试表,提供测试
if(testTable.equals(""))
{
conn.setAutoCommit(true);
}
else
{
Statement stmt=conn.createStatement();
stmt.execute("select count(*) from " + testTable);
}
} catch (SQLException ex) {
closeConnection(conn);
System.out.println("The database connection object can't be used, in the close ...");
ex.printStackTrace();
return false;
}
return true;
}
/**
* 获取空闲的数据库连接对象
*
* @return Connection
*/
public Connection getConnection()
throws SQLException
{
//还没创建连接池
if(connections==null)
return null;
Connection conn=getFreeConnection();
//拿不到数据库连接对象就一直试
while(conn==null)
{
wait(250);
conn=getFreeConnection();
}
return conn;
}
/**
* 让程序停止 ? 毫秒
*
* @param ms int 毫秒
*/
private void wait(int ms)
{
try {
Thread.sleep(ms);
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
我自己写的数据库连接池,
/**
* 获取可用连接,如果没有可用连接,则创建一定量(incConnection)的连接数,
* 如果在没有获取到可用连接,则直接返回null
*
* @return Connection
*/
private Connection getFreeConnection()
throws SQLException
{
Connection conn=findFreeConnection();
if(conn==null)
{
createConnections(this.incConnectionSize);
conn=findFreeConnection();
//如果还是没办法获取空闲连接数,则返回null
if(conn==null)
return null;
}
return conn;
}
/**
* 查找空闲的数据库连接对象
*
* @return Connection
*/
private Connection findFreeConnection()
{
Connection conn=null;
PooledConnection pConn=null;
Enumeration enumeration=connections.elements();
while(enumeration.hasMoreElements())
{
pConn=(PooledConnection)enumeration.nextElement();
//如果不繁忙则获取连接对象
if(!pConn.isBusy())
{
conn=pConn.getConnection();
if(!testConnection(conn))
{
try {
conn=createNewConnection();
} catch (SQLException ex) {
System.out.println("Create the database connection object failed:"+ex.getMessage());
ex.printStackTrace();
return null;
}
pConn.setConnection(conn);
}
pConn.setBusy(true);
break;
}
}
return conn;
}
/**
* 回收connection对象
*/
public void returnConnection(Connection conn)
{
if(connections==null)
{
System.out.println("The database connection pool wasn't created ...");
return ;
}
Enumeration enumeration=connections.elements();
PooledConnection pConn=null;
while(enumeration.hasMoreElements())
{
pConn=(PooledConnection)enumeration.nextElement();
if(pConn.getConnection()==conn)
{
pConn.setBusy(false);
break;
}
}
}
/**
* 刷新连接池
*/
public synchronized void refreshPool()
throws SQLException
{
if(connections==null)
{
System.out.println("The database connection pool wasn't created ...");
return ;
}
PooledConnection pConn=null;
Enumeration enumeration=connections.elements();
while(enumeration.hasMoreElements())
{
pConn=(PooledConnection)enumeration.nextElement();
if(pConn.isBusy())
{
wait(5000);
}
closeConnection(pConn.getConnection());
pConn.setConnection(createNewConnection());
pConn.setBusy(false);
}
}
/**
* 关闭连接池
*/
public synchronized void closePool()
{
if(connections==null)
{
System.out.println("The database connection pool wasn't created ...");
return ;
}
PooledConnection pConn=null;
Iterator it=connections.iterator();
int i=1;
while(it.hasNext())
{
pConn=(PooledConnection)(it.next());
if(pConn.isBusy())
{
wait(5000);
}
closeConnection(pConn.getConnection());
}
connections.clear();
connections=null;
}
/**
* 创建数据库连接池
*/
public synchronized void createPool()
throws Exception
{
//防止多次创建
if(connections!=null)
return ;
//实例化驱动
Driver driver=(Driver)(Class.forName(jdbcDriver).newInstance());
DriverManager.registerDriver(driver);
//创建Connection对象容器
connections=new Vector();
//初始化连接池
createConnections(this.initConnectionSize);
System.out.println("Create the database connection pool with success ...");
}
/**
* 创建指定数目的Connection对象
*
* @param count int 要创建Connection对象的个数
*/
private void createConnections(int count)
throws SQLException
{
for(int i=0;i<count;i++)
{
if(maxConnectionSize>0 && connections.size()>=maxConnectionSize)
{
System.out.println("The database connection has attained the maximum connection, can't be created ...");
break;
}
try
{
connections.addElement(new PooledConnection(createNewConnection()));
} catch (SQLException ex) {
System.out.println("Create the database connection object failed ....");
System.out.println(ex.getMessage());
throw new SQLException();
}
System.out.println("Create the database connection object with success ...");
}
}
/**
* 创建一个新的Connection
* @return 返回一个新的Connection对象
*/
private Connection createNewConnection()
throws SQLException
{
Connection conn=DriverManager.getConnection(dbUrl,dbUser,dbPwd);
//如果是第一次创建
if(connections.size()==0)
{
DatabaseMetaData metaData=conn.getMetaData();
int maxConnections=metaData.getMaxConnections();
//如果数据库连接池数超出数据库的连接数,则设置数据库的连接数
if(maxConnectionSize> maxConnections)
{
maxConnectionSize=maxConnections;
}
}
return conn;
}
/* --------------------|inner class PooledConnection|-------------------- */
/**
* 创建connection对象,并且可查询connection状态
*/
class PooledConnection
{
private boolean busy=false;
private Connection conn=null;
private int count=0;
/**
* 构造函数
*
* @param conn Connection connection对象
*/
public PooledConnection(Connection conn)
{
this.conn=conn;
}//`
/**
* 设置connection对象
*
* @param conn Connection connection对象
*/
public void setConnection(Connection conn)
{
this.conn=conn;
}
/**
* 返回connection对象
*
* @return 返回connection对象
*/
public Connection getConnection()
{
return this.conn;
}
/**
* 设置数据库状态
*
* @param busy boolean false空闲,true繁忙
*/
public void setBusy(boolean busy)
{
this.busy=busy;
if(this.busy)
{
count++;
}else
{
if(count == 1000)
{
try {
if(conn != null)
{
conn.close();
conn = null;
conn = createNewConnection();
count = 0;
System.out.println("conn auto close");
}
} catch (SQLException ex) {
Log.exception(log, ex, Level.WARNING);
}
}
}
}
/**
* 返回数据库状态
*
* @return false空闲,true繁忙
*/
public boolean isBusy()
{
return this.busy;
}
}//class~
/* --------------------|inner class PooledConnection|-------------------- */
}//class~
package com.east.db;import javax.sql.DataSource;
import javax.naming.InitialContext;
import javax.naming.Context;
import java.sql.*;
public class DBTools {
public static Connection getCon(){
Connection con = null;
try{
Context ctx = new InitialContext();
DataSource ds = (DataSource)ctx.lookup("java:comp/env/jdbc/ds");
if (ds != null){
con = ds.getConnection();
}
}
catch(Exception se){
se.printStackTrace();
}finally{
return con;
}
}
}
----web.xml--------------------------------------------
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <resource-ref>
<description>sqlserverDB connection</description>
<res-ref-name>jdbc/ds</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
</web-app>
---tomcat servlet.xml-------------------------------- <!--
<Valve className="org.apache.catalina.valves.FastCommonAccessLogValve"
directory="logs" prefix="localhost_access_log." suffix=".txt"
pattern="common" resolveHosts="false"/>
-->
<Context path="/Pool" docBase="Pool" debug="1" reloadable="true">
<Resource name="jdbc/ds" auth="Container" type="javax.sql.DataSource"
driverClassName="com.microsoft.jdbc.sqlserver.SQLServerDriver"
url="jdbc:microsoft:sqlserver://localhost:1433;databasename=pubs"
username="sa" password=""
maxWait="5000" maxActive="4"
maxIdle="4"/>
</Context> </Host> </Engine> </Service></Server>