JavaWeb笔记之数据源连接池

数据库连接池

1、为什么要使用连接池?

数据源:数据的来源----mysql

连接池:连接管理复用机制

为什么合起来称呼,因为在我们当前机制下,就是通过连接池完成数据源的操作的

 

我们现在使用数据库,都是在需要使用的时候开始建立连接,等到我们使用完之后,就会把这连接close(回收释放断开销毁),等到我们又需要连接数据库时,就。。。。。。。。。。。。。

连接是给我们提供数据服务的,我们可以把它看成我们的10086移动客服业务,我们现在的做法,等同于-à有客户来咨询-à发现需要使用客服人员-à招聘培训上岗一个客户人员提供服务-à客户咨询完毕后,把这个培训人员close -à又有个客户来咨询.........

解决建立数据库连接耗费资源和时间很多的问题,提高性能。

2、打造自己的的数据源连接池

       1)编写自己的配置文件(mypoolconfig.properties)

         #连接设置

driverClassName=com.mysql.jdbc.Driver

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

username=root

password=123456

 

#<!--初始化连接 -->

initialSize=1

 

#最大连接数量

maxActive=5

 

#<!--最大空闲连接 -->

maxIdle=2

 

#<!--最小空闲连接 -->

minIdle=1

 

#<!--超时等待时间以毫秒为单位 6000毫秒/1000等于60 -->

maxWait=60000

       2)编写自己的配置文件加载类

public classPoolConfig {

    public static  String DRIVER_NAME = null;

    public static  String CONN_URL = null;

    public static  String ACCOUNT = null;

    public static  String PWD = null;

    public static  int INITIAL_SIZE = 1;

    public static  int MAXACTIVE = 1;

    public static  int MAXIDLE = 1;

    public static  int MINIDLE = 1;

 

    public static void loadConfig(Propertiesproperties){

       DRIVER_NAME=properties.getProperty("driverClassName");

       CONN_URL=properties.getProperty("url");

       ACCOUNT=properties.getProperty("username");

       PWD=properties.getProperty("password");

        INITIAL_SIZE=Integer.parseInt(properties.getProperty("initialSize"));

       MAXACTIVE=Integer.parseInt(properties.getProperty("maxActive"));

       MAXIDLE=Integer.parseInt(properties.getProperty("maxIdle"));

       MINIDLE=Integer.parseInt(properties.getProperty("minIdle"));

    }

}

 

       3)在写自己的连接池适配类,为了获取到我们需要的方法!

public abstract class PoolWrapper  implements DataSource{

    @Override

    publicConnection getConnection(String username, String password) throws SQLException{

        returnnull;

    }

    @Override

    public<T> T unwrap(Class<T> iface) throws SQLException {

        returnnull;

    }

    @Override

    public booleanisWrapperFor(Class<?> iface) throws SQLException {

        returnfalse;

    }

    @Override

    publicPrintWriter getLogWriter() throws SQLException {

        returnnull;

    }

    @Override

    public voidsetLogWriter(PrintWriter out) throws SQLException {

    }

    @Override

    public voidsetLoginTimeout(int seconds) throws SQLException {

    }

    @Override

    public intgetLoginTimeout() throws SQLException {

        return 0;

    }

    @Override

    public LoggergetParentLogger() throws SQLFeatureNotSupportedException {

        returnnull;

    }

}

4) 编写连接工具类(作用就是加载驱动,获取连接)

public class UtilConn {

   static {

       try {

           Class.forName(PoolConfig.DRIVER_NAME);

       } catch (ClassNotFoundException e) {

            throw new RuntimeException("驱动加载错误!");

       }

   }

   public static Connection openConnection() {

       Connection connection = null;

       try {

            connection =DriverManager.getConnection(PoolConfig.CONN_URL, PoolConfig.ACCOUNT,PoolConfig.PWD);

       } catch (SQLException e) {

            throw new RuntimeException("数据库连接错误!");

       }

       return connection;

   }

   public static void release(Connection connection , Statement statement,ResultSet resultSet){

       if (resultSet != null) {

            try {

                resultSet.close();

            } catch (SQLException e) {

                e.printStackTrace();

           }

 

       }

       if (statement != null) {

            try {

                statement.close();

            } catch (SQLException e) {

                e.printStackTrace();

            }

       }

       if (connection != null) {

            try {

                connection.close();

            } catch (SQLException e) {

                e.printStackTrace();

            }

       }

   }

   public static void release(Connection connection , Statement statement){

       release(connection,statement,null);

   }

   public static void release(Connection connection){

       release(connection,null,null);

   }

 

}

5) 最后编写自己的连接池,继承上面的连接池适配类(单例模式)

public class Pool extends PoolWrapper {

    private staticPool pool;

    //存放我们所有实例化出来的,没有在使用的Connection对象

    private staticLinkedList<Connection> connections = new LinkedList<>();

    //记录我们当前已经产生过多少个连接对象了,为什么不使用connections.size()?

    private staticint connTotalCount = 0;

    private Pool(){

    }

    //单例--连接池有一个就够了,提供多个连接对象

    public staticDataSource createDataSource(Properties properties) {

        if (pool ==null) {

            pool =new Pool();

           PoolConfig.loadConfig(properties);

            for(int i = 0; i < PoolConfig.INITIAL_SIZE; i++) {

                Connection connection =UtilConn.openConnection();

               connections.add(connection);

            }

           connTotalCount = PoolConfig.INITIAL_SIZE;

        }

        returnpool;

    }

    //提供连接

    @Override

    publicConnection getConnection() throws SQLException {

        //移除栈顶元素,返回值是我们刚刚移除出来的对象

        Connectionconnection = connections.pop();

        //如果获取一个连接之后,不满足最小空闲连接限制,则新增一个

        if(connections.size() < PoolConfig.MINIDLE) {

            //并且没有超出我们的连接总数上限

            if (connTotalCount< PoolConfig.MAXACTIVE) {

               connections.add(UtilConn.openConnection());

               connTotalCount++;

            }

 

        }

        if(connection == null) {

            thrownew RuntimeException("连接全忙,请稍后访问!!!");

        }

        returnconnection;

    }

    //回收连接

    public staticvoid recycleConnection(Connection connection) {

        if(connections.size() < PoolConfig.MAXIDLE) {

           connections.add(connection);

        } else {

           UtilConn.release(connection);

        }

    }

}

3、常用的数据源配置(日后都使用数据源,一定要配置一下)

3.1、DBCP

DBCP:Apache推出的Database Connection Pool

使用步骤:

> 添加jar包 commons-dbcp-1.4.jar commons-pool-1.5.6.jar

> 添加属性资源文件

> 编写数据源工具类

publicclass UtilDBCP {

    private static DataSource dataSource;

         //声明一个连接池

    static {

        Properties properties=new Properties();

        InputStream inputStream =UtilDBCP.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");

        try {

            properties.load(inputStream);

        } catch (IOException e) {

            e.printStackTrace();

        }

        try {

            dataSource =BasicDataSourceFactory.createDataSource(properties);

        } catch (Exception e) {

            e.printStackTrace();

        }

    }

         //打开一个连接

    public static Connection openConn(){

        try {

            return dataSource.getConnection();

        } catch (SQLException e) {

            e.printStackTrace();

        }

       throw new RuntimeException("无法获取连接!");

    }

    public static void release(Connectionconnection , Statement statement, ResultSet resultSet){

 

        if (resultSet != null) {

            try {

                resultSet.close();

            } catch (SQLException e) {

                e.printStackTrace();

            }

        }

        if (statement != null) {

            try {

                statement.close();

            } catch (SQLException e) {

                e.printStackTrace();

            }

        }

        if (connection != null) {

            try {

                connection.close();

            } catch (SQLException e) {

                e.printStackTrace();

            }

        }

    }

    public static void release(Connectionconnection , Statement statement){

        release(connection,statement,null);

    }

    public static void release(Connectionconnection){

       release(connection,null,null);

    }

 

}

3.2、C3P0

 使用步骤:

1、添加jar包

2、编写配置文件

c3p0-config.xml,放在classpath中,或classes目录中

<c3p0-config>

    <default-config>

        <propertyname="driverClass">com.mysql.jdbc.Driver</property>

        <propertyname="jdbcUrl">jdbc:mysql://localhost:3306/java1_9</property>

        <property name="user">root</property>

        <propertyname="password">123456</property>

        <propertyname="automaticTestTable">con_test</property>

        <propertyname="checkoutTimeout">30000</property>

        <propertyname="idleConnectionTestPeriod">30</property>

        <propertyname="initialPoolSize">10</property>

        <propertyname="maxIdleTime">30</property>

        <propertyname="maxPoolSize">100</property>

        <property name="minPoolSize">10</property>

        <propertyname="maxStatements">200</property>

        <user-overridesuser="test-user">

            <propertyname="maxPoolSize">10</property>

            <propertyname="minPoolSize">1</property>

            <property name="maxStatements">0</property>

        </user-overrides>

    </default-config> <!-- This app ismassive! -->

</c3p0-config>

3、编写工具类:(释放连接跟上面步骤一样)

publicclass UtilC3P0 {

    private static ComboPooledDataSourcecomboPooledDataSource;

    static {

        comboPooledDataSource=new ComboPooledDataSource();

    }

    public static Connection openConn(){

        try {

            returncomboPooledDataSource.getConnection();

        } catch (SQLException e) {

            e.printStackTrace();

        }

       throw new RuntimeException("无法获取连接!");

    }

4、用JavaWeb服务器管理数据源:Tomcat(已经测试会出错,没法查明原因)

开发JavaWeb应用,必须使用一个JavaWeb服务器,JavaWeb服务器都内置数据源。

Tomcat:(DBCP)

数据源只需要配置服务器即可。

 配置数据源的步骤:

1、拷贝数据库连接的jar到tomcatlib目录下

2、配置数据源XML文件

a)如果把配置信息写在tomcat下的conf目录的context.xml中,那么所有应用都能使用此数据源。

b)如果是在当前应用的META-INF中创建context.xml, 编写数据源,那么只有当前应用可以使用。

<Context>

<Resourcename="jdbc/test2" auth="Container"type="javax.sql.DataSource"

               maxActive="100"maxIdle="30" maxWait="10000"

               username="root"password="123456" driverClassName="com.mysql.jdbc.Driver"

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

</Context>

3、使用连接池

 

猜你喜欢

转载自blog.csdn.net/DaySurprise/article/details/78621209