数据库连接池

来源:互联网 发布:卸载软件残留 编辑:程序博客网 时间:2024/04/28 19:54

自己编写数据库连接池

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

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

    Connection getConnection()

    ConnectiongetConnection(String username, String password)

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

          2实现getConnection方法,让getConnection方法每次调用时,从LinkedList中取一个Connection返回给用户。

          3当用户使用完Connection,调用Connection.close()方法时,Collection对象应保证将自己返回到LinkedList中,而不要把conn还给数据库。

例:public class JdbcPool implements DataSource {private static LinkedList<Connection> list = new LinkedList<Connection>();private static Properties config = new Properties();static{try {config.load(JdbcUtils_DBCP.class.getClassLoader().getResourceAsStream("db.properties"));Class.forName(config.getProperty("driver"));for(int i=0;i<10;i++){Connection conn = DriverManager.getConnection(config.getProperty("url"),config.getProperty("username"), config.getProperty("password"));list.add(conn);}} catch (Exception e) {throw new ExceptionInInitializerError(e);}}

    在实际开发,发现对象的方法满足不了开发需求时,有三种方式对其进行增强

    1、写一个connecton子类,覆盖close方法,增强close方法(要导入原有信息,相当于重写conection      对象,几乎不可能)

    2、用包装设计模式(可行,但是要覆盖的方法太多)

        步骤:1.定义一个类,实现与被增强相同的接口

              2.在类中定义一个变量,记住被增强对象

              3.定义一个构造函数,接收被增强对象

              4.覆盖想增强的方法

              5.对于不想增强的方法,直接调用目标对象(被增强对象)的方法

    3、用动态代理(aop面向切面编程)

public Connection getConnection() throws SQLException {if(list.size()<=0){throw new RuntimeException("数据库忙,请稍会再来!!");}//取出连接不要调用get方法,要用remove方法,取出并删除池中连接Connection conn = list.removeFirst();//定义一个自己的连接,然后返回。主要原因为了用户调用close方法的时候不把连接还给数据库,要还给连接池。MyConnection my = new MyConnection(conn); return my;    }//定义一个类,实现与被增强相同的接口class MyConnection implements Connection{//在类中定义一个变量,记住被增强对象private Connection conn;//定义一个构造函数,接收被增强对象public MyConnection(Connection conn){this.conn = conn;}//覆盖想增强的方法,将连接加入集合中。public void close(){list.add(this.conn);}//对于不想增强的方法,直接调用目标对象(被增强对象)的方法public void clearWarnings() throws SQLException {this.conn.clearWarnings();}public void commit() throws SQLException {this.conn.commit();}public Statement createStatement() throws SQLException {return this.conn.createStatement();}..............很多需要覆盖的方法}}

开源数据库连接池

         现在很多WEB服务器(Weblogic, WebSphere, Tomcat)都提供了DataSoruce的实现,即连接池的实现。通        常我们把DataSource的实现,按其英文含义称之为数据源,数据源中都包含了数据库连接池的实现。          也有一些开源组织提供了数据源的独立实现:有DBCP 数据库连接池和C3P0 数据库连接池。实际应用 时不需要编写连接数据库代码,直接从数据源获得数据库的连接。程序员编程时也应尽量使用这些数     据源的实现,以提升程序的数据库访问性能。

DBCP数据源

         DBCP 是 Apache 软件基金组织下的开源连接池实现,使用DBCP数据源,应用程序应在系统中增加两     个 jar 文件:Commons-dbcp.jar(连接池的实现)与Commons-pool.jar(连接池实现的依赖库)Tomcat   的连接池正是采用该连接池来实现的。该数据库连接池既可以与应用服务器整合使用,也可由应用程     序独立使用。

例:public class JdbcUtils {private static DataSource ds = null;static{try{//用到类装载器读取DBCP的配置文件InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");//用之前除了要导入两个jar包,还有将dbcpconfig.properties考到类目录下,配置文件内部有连接信息Properties prop = new Properties();prop.load(in);//实力化BasicDataSourceFactory工厂,并调用createDataSource方法将配置文件传入后获得连接池BasicDataSourceFactory factory = new BasicDataSourceFactory();ds = factory.createDataSource(prop);}catch (Exception e) {throw new ExceptionInInitializerError(e);}}//编写一个方法用于获取连接池中的连接public static Connection getConnection() throws SQLException{//内部返回的也不是真正的Connection,原因也是close方法重写,为了将连接直接返回连接池return ds.getConnection();}}

C3P0 数据源

         使用C3P0数据源,应用程序应在系统中导入c3p0-0.9.2-pre1.jar、mchange-commons-0.2.jar、 c3p0-oracle-thin-extras-0.9.2-pre1.jar(数据库为oracle才导入)文件

例:public class JdbcUtils_C3P0 {private static ComboPooledDataSource ds = null;static{try{//实例化连接池,可以传入参数作为配置,如果不传入就用缺省的配置ds = new ComboPooledDataSource();//配置C3P0的配置要在c3p0-config.xml文件中配置,文件名不能变。将配置文件放到类目录    下(src)}catch (Exception e) {throw new ExceptionInInitializerError(e);}}public static Connection getConnection() throws SQLException{return ds.getConnection();}}

配置文件<?xml version="1.0" encoding="UTF-8"?><c3p0-config><default-config><property name="driverClass">com.mysql.jdbc.Driver</property>驱动名称<property name="jdbcUrl">jdbc:mysql://localhost:3306/day16</property>URL<property name="user">root</property>用户名<property name="password">root</property>密码<property name="maxIdleTime">30</property>最大空闲时间<property name="initialPoolSize">10</property>池初始化大小<property name="minPoolSize">5</property>最小的池的数量<property name="maxPoolSize">20</property>最大的池的数量</default-config><named-config name="flx">名称为实力化池要传入的参数<property name="driverClass">com.mysql.jdbc.Driver</property><property name="jdbcUrl">jdbc:mysql://localhost:3306/day16</property><property name="user">root</property><property name="password">root</property><property name="acquireIncrement">5</property><property name="initialPoolSize">10</property><property name="minPoolSize">5</property><property name="maxPoolSize">20</property></named-config></c3p0-config>

配置Tomcat数据源

         在C:\apache-tomcat-6.0.36\conf\Catalina\localhost文件夹中新建context.xml文件配置,也可在META-INF     文件夹中新建context.xml文件配置。

<Context>

     <Resourcename="jdbc/EmployeeDB"名称

           auth="Container"容器创建

           type="javax.sql.DataSource"类型

           username="root"用户名

           password="root"密码

           driverClassName="com.mysql.jdbc.Driver"驱动

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

           initialSize="10"初始化池个数

           maxActive="30"最大可以池

           maxIdle="4"/>最大空闲连接数

</Context>

                            注:如果要操作mysql,必须将mysql的驱动导入,否则会出现找不到类异常

public class JdbcUtils_Tomcat {private static DataSource ds;static {try {//初始化JNDIContext initCtx = new InitialContext();//找到JNDI容器Context envCtx = (Context) initCtx.lookup("java:comp/env");//找到数据源ds = (DataSource) envCtx.lookup("jdbc/EmployeeDB");} catch (Exception e) {throw new RuntimeException(e);}}public static Connection getConnection() throws SQLException{return ds.getConnection();}}