mysql数据库连接池原理_数据库连接池实现原理

数据库连接池实现原理

实现原理是用动态代理技术

编写连接池需实现java.sql.DataSource接口,

DataSource接口中定义了两个重载的getConnection方法:

Connection getConnection()

Connection getConnection(String username, String password)

public class JdbcPool implements DataSource {

private static String driver;

private static String url;

private static String username;

private static String password;

static{

try {

Properties prop = new Properties();

InputStream in = JdbcUtil.class.getClassLoader().getResourceAsStream("db.properties");

prop.load(in);

driver = prop.getProperty("driver");

url = prop.getProperty("url");

username = prop.getProperty("username");

password = prop.getProperty("password");

Class.forName(driver);

} catch (Exception e) {

throw new ExceptionInInitializerError(e);

}

}

private static LinkedList pool = new LinkedList();

private static int poolsize = 10;

//问题:每次newJdbcPoll都会建立10个链接,可使用单态设计模式解决此类问题

public JdbcPool(){

for(int i=0;i

try {

Connection conn = DriverManager.getConnection(url,username,password);

pool.add(conn);

System.out.println(conn + "被加到池里面了!!!");

} catch (SQLException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

/*

* 这里使用动态代理技术返回一个假的Connection,当dao调用假connection的任何方法时,该方法体内会调用InvocationHandler.invoke方法

* 在invoke方法体内,发现dao调用的是close方法,则把链接还到池里,否则,调用真connection的对应方法。

* (non-Javadoc)

* @see javax.sql.DataSource#getConnection()

*/

public Connection getConnection() throws SQLException { //spring aop

if(pool.size()>0){

final Connection conn = pool.removeFirst();

System.out.println(conn + "从池里面取出去了!!!");

return (Connection) Proxy.newProxyInstance(JdbcPool.class.getClassLoader(),conn.getClass().getInterfaces(), new InvocationHandler(){

//proxy为代理对象 method为要调用的方法 args为方法的参数

public Object invoke(Object proxy, Method method, Object[] args)

throws Throwable {

if(method.getName().equals("close")){

pool.addFirst(conn);

System.out.println(conn + "被还到池里面了!!");

return null;

}else{

return method.invoke(conn, args);

}

}

});

}

throw new RuntimeException("对不起,池里没有资源了!!!");

}

public Connection getConnection(String arg0, String arg1)

throws SQLException {

// TODO Auto-generated method stub

return null;

}

public PrintWriter getLogWriter() throws SQLException {

// TODO Auto-generated method stub

return null;

}

public int getLoginTimeout() throws SQLException {

// TODO Auto-generated method stub

return 0;

}

public void setLogWriter(PrintWriter arg0) throws SQLException {

// TODO Auto-generated method stub

}

public void setLoginTimeout(int arg0) throws SQLException {

// TODO Auto-generated method stub

}

//public Jdbcpool

}

一般实现第一个就可了,数据库的信息都 是通过配置文件来实现的,

通过加载配置文件就可以,取得与数据库的连接

实现DataSource接口,并实现连接池功能的步骤:

1.在DataSource构造函数中批量创建与数据库的连接,并把创建的连接加入LinkedList对象中

因为LinkedList 是用链表实现的,对于增删实现起来比较容易

因为每从池中取出一个连接,都要将这个对象从池不删除,当返回时就要添加回去

2.实现getConnection方法,让getConnection方法每次调用时,

从LinkedList中取一个Connection返回给用户(即要从池中删除一个对象)

3.当用户使用完Connection,调用Connection.close()方法时,

Collection对象应保证将自己返回到LinkedList中

(用户一般都会调用Connection的close方法来关闭连接,从而不能将这个连接返回给池,

所以这里采用了动态代理技术:赤获取用户关闭连接的操作,当获取到时而不是将其给关闭,

而是将这个连接(对象)添加到池中)

注:

** 这里使用动态代理技术返回一个假的Connection,

当dao调用假connection的任何方法时,该方法体内会调用InvocationHandler.invoke方法

** 在invoke方法体内,发现dao调用的是close方法,则把链接还到池里,

否则,调用真connection的对应方法。

开源的数据库连接池(数据源)

都提供DataSoruce的实现,即连接池的实现

DBCP 数据库连接池     C3P0 数据库连接池

DBCP 是 Apache 软件基金组织下的开源连接池实现,使用DBCP数据源

Commons-dbcp.jar:连接池的实现

Commons-pool.jar:连接池实现的依赖库

它用到了一个配置文件dbcpconfig.properties(放在类路径下)

用BaseDataSourceFactory 对象 装载这个配置文件

private static DataSource dataSource;

static {

try {

InputStream in = JdbcUtil.class.getClassLoader()

.getResourceAsStream("dbcpconfig.properties");

Properties prop = new Properties();

prop.load(in);

BasicDataSourceFactory factory = new BasicDataSourceFactory();

dataSource = factory.createDataSource(prop);

} catch (Exception e) {

throw new ExceptionInInitializerError(e);

}

}

public static Connection getConnection() throws SQLException {

return dataSource.getConnection();

}

在Tomcat 下实现数据库连接池

1.要在META-INF目录下建一个context.xml文件

type="javax.sql.DataSource" username="root" password="root"

driverClassName="com.mysql.jdbc.Driver"

url="jdbc:mysql://localhost:3306/jdbc"

maxActive="8" maxIdle="4"/>

(这是将数据库连接对象绑定到一个名字中去,要用到时就通过这个名字来找这个对象)JNDI

2.还要将数据库驱动的JAR复制到Tomcat的LIB目录下,因为Tomcat起动时就会去初始化连接池

所以就会去找相应的JAR文件,其实这个配置是可以配在Tomcat conf目录下server.xml文件中的

, 为了不改变它原来的配置,所以配置有那也是一样有效的

3.取得连接,通过命名空间

Context initCtx = new InitialContext();

Context envCtx = (Context) initCtx.lookup("java:comp/env");

dataSource = (DataSource)envCtx.lookup("jdbc/dataSource");

分享到:

18e900b8666ce6f233d25ec02f95ee59.png

72dd548719f0ace4d5f9bca64e1d7715.png

2010-09-21 23:11

浏览 6516

评论

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值