20160409 javaweb 数据库连接池

时间:2022-04-02 13:37:08

20160409 javaweb 数据库连接池

20160409 javaweb 数据库连接池

20160409 javaweb 数据库连接池

20160409 javaweb 数据库连接池

1.自己编写数据库连接池:

package com.dzq.pool;

import java.io.PrintWriter;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.SQLFeatureNotSupportedException;
import java.util.LinkedList;
import java.util.List;
import java.util.logging.Logger;

import javax.sql.DataSource;

public class MyPool implements DataSource {
    private static List<Connection> pool=new LinkedList<Connection>();
    
    static{
        try{
        Class.forName("com.mysql.jdbc.Driver");
        for(int i=0;i<5;i++){
            Connection conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/database01?Unicode=true&characterEncoding=utf-8","root","");
            pool.add(conn);
        }
        
        }catch(Exception e){
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }
    
    @Override
    public Connection getConnection() throws SQLException {
        if(pool.size()==0){
            for(int i=0;i<3;i++){
                Connection conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/database01?Unicode=true&characterEncoding=utf-8","root","");
                pool.add(conn);
            }
        }  
            
        final Connection conn=pool.remove(0);
            
            //利用动态代理改造close方法
    Connection  proxy= (Connection) Proxy.newProxyInstance(conn.getClass().getClassLoader(), new Class[]{Connection.class}, new InvocationHandler() {
                
                @Override
                public Object invoke(Object proxy, Method method, Object[] args)
                        throws Throwable {
                    if("close".equals(method.getName())){
                        //对于想改造的close方法,我们自己写
                        retConn(conn);
                        return null;
                    }else{
                        //对于不想改造的方法,用被代理者身上相同的方法
                        return method.invoke(conn, args);
                    }
                }
            });
            System.out.println("获取了一个连接,池里还剩"+pool.size()+"个连接");
            return proxy;
            
    }

    private void retConn(Connection conn){
        try {
            if(conn!=null&&conn.isClosed()){
                pool.add(conn);
                System.out.println("还回了一个连接池里还剩"+pool.size()+"个连接");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    
    @Override
    public Connection getConnection(String arg0, String arg1)
            throws SQLException {
        
        return null;
    }

    @Override
    public PrintWriter getLogWriter() throws SQLException {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public int getLoginTimeout() throws SQLException {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public Logger getParentLogger() throws SQLFeatureNotSupportedException {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void setLogWriter(PrintWriter arg0) throws SQLException {
        // TODO Auto-generated method stub

    }

    @Override
    public void setLoginTimeout(int arg0) throws SQLException {
        // TODO Auto-generated method stub

    }

    @Override
    public boolean isWrapperFor(Class<?> iface) throws SQLException {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public <T> T unwrap(Class<T> iface) throws SQLException {
        // TODO Auto-generated method stub
        return null;
    }

    
    
    

}

 

20160409 javaweb 数据库连接池

 

 

20160409 javaweb 数据库连接池

20160409 javaweb 数据库连接池

2.开源数据源:
1.DBCP:
方式1:
BasicDataSource source = new BasicDataSource();
source.setDriverClassName("com.mysql.jdbc.Driver");
source.setUrl("jdbc:mysql:///day11");
source.setUsername("root");
source.setPassword("root");

方式2:
Properties prop = new Properties();
prop.load(new FileReader("dbcp.properties"));
BasicDataSourceFactory factory = new BasicDataSourceFactory();
DataSource source = factory.createDataSource(prop);

配置文件中:
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql:///day11
username=root
password=root

#<!-- 初始化连接 -->
initialSize=10

#最大连接数量
maxActive=50

#<!-- 最大空闲连接 -->
maxIdle=20

#<!-- 最小空闲连接 -->
minIdle=5

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

代码如下:

package com.dzq.jdbc;

import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;

import javax.sql.DataSource;

import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.dbcp.BasicDataSourceFactory;

public class DBCPDemo {
    public static void main(String[] args) {
        
          Connection conn=null;
          PreparedStatement ps=null;
          ResultSet rs=null;
          try {
          Properties prop=new Properties();
        
          prop.load(new FileReader("dbcp.properties"));
          /*BasicDataSource source=new BasicDataSource();
          source.setDriverClassName("com.mysql.jdbc.Driver");
          source.setUrl("jdbc:mysql://localhost:3306/database01?Unicode=true&characterEncoding=utf-8");
          source.setUsername("root");
          source.setPassword("");*/
          BasicDataSourceFactory factory =new BasicDataSourceFactory();
          DataSource source=factory.createDataSource(prop);
        
            conn=source.getConnection();
            String sql="select * from account";
            ps=conn.prepareStatement(sql);
            rs=ps.executeQuery();
            while (rs.next()) {
                String name=rs.getString("name");
                System.out.println(name);
                
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            if(rs!=null){
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }finally{
                    rs=null;
                }
            }
            
            if(ps!=null){
                try {
                    ps.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }finally{
                    ps=null;
                }
            }
            
            if(conn!=null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }finally{
                    conn=null;
                }
            }
        }
      }
}

 2.c3p0

20160409 javaweb 数据库连接池

C3P0数据源:
方式1:
ComboPooledDataSource source = new ComboPooledDataSource();
source.setDriverClass("com.mysql.jdbc.Driver");
source.setJdbcUrl("jdbc:mysql:///day11");
source.setUser("root");
source.setPassword("root");

方式2:
ComboPooledDataSource source = new ComboPooledDataSource();
在类加载目录下名称为c3p0-config.xml的配置文件中配置:
<c3p0-config>
<default-config>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql:///day11</property>
<property name="user">root</property>
<property name="password">root</property>
</default-config>
</c3p0-config>

c3p0配置文件:

<?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/database01?Unicode=true&amp;characterEncoding=utf-8</property>
    <property name="user">root</property>
    <property name="password"></property>
  </default-config>
  
   <named-config name="aaa"> 
       <property name="driverClass">com.mysql.jdbc.Driver</property>
    <property name="jdbcUrl">jdbc:mysql://localhost:3306/database01?Unicode=true&amp;characterEncoding=utf-8</property>
    <property name="user">root</property>
    <property name="password"></property>
   </named-config>    
</c3p0-config>

 

 示例代码:

package com.dzq.jdbc;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

import com.mchange.v2.c3p0.ComboPooledDataSource;

public class C3P0Demo {
     public static void main(String[] args) {
            
          Connection conn=null;
          PreparedStatement ps=null;
          ResultSet rs=null;
          try {
              ComboPooledDataSource source=new ComboPooledDataSource();
        /* ComboPooledDataSource source=new ComboPooledDataSource();
         source.setDriverClass("com.mysql.jdbc.Driver");
         source.setJdbcUrl("jdbc:mysql://localhost:3306/database01?Unicode=true&characterEncoding=utf-8");
         source.setUser("root");
         source.setPassword("");*/
              
              
         
            conn=source.getConnection();
            String sql="select * from account";
            ps=conn.prepareStatement(sql);
            rs=ps.executeQuery();
            while (rs.next()) {
                String name=rs.getString("name");
                System.out.println(name);
                
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally{
            if(rs!=null){
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }finally{
                    rs=null;
                }
            }
            
            if(ps!=null){
                try {
                    ps.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }finally{
                    ps=null;
                }
            }
            
            if(conn!=null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }finally{
                    conn=null;
                }
            }
        }
      }
}

3.tomcat 数据源

20160409 javaweb 数据库连接池

tomcat内置的数据源(DBCP):
~1.如何为tomcat配置数据源
~tomcat/conf/context.xml文件中配置<Context>配置在这个位置的信息将会被所有的web应用所共享
~tomcat/conf/[engin]/[Host]/context.xml文件中可以配置<Context>标签,这里配置的信息将会被这台虚拟主机中的所有web应用所共享

~tomcat/conf/server.xml文件中的<Host>标签中配置<Context>标签,这是web应用的第一种配置方式,在这个标签中配置的信息将只对当前web应用起作用
~tomcat/conf/[engin]/[Host]/自己创建一个.xml文件,在这个文件中使用<Context>标签配置一个web应用,这是web应用第二种配置方式,在这个<Context>标签中配置的信息将只会对当前web应用起作用
~web应用还有第三种配置方式:将web应用直接放置到虚拟主机管理的目录.此时可以在web应用的META-INF文件夹下创建一个context.xml文件,在其中可以写<Context>标签进行配置,这种配置信息将只会对当前web应用起作用

<Resource name="mySource"
auth="Container"
type="javax.sql.DataSource"
username="root"
password="root"
driverClassName="com.mysql.jdbc.Driver"
url="jdbc:mysql:///day11"
maxActive="8"
maxIdle="4"/>

 

~2.如何在程序中获取这个数据源
想要访问jndi就必须在Servlet中才能执行下列代码:

Context initCtx = new InitialContext();
Context jndi = (Context) initCtx.lookup("java:comp/env");
DataSource source = jndi.lookUp("mySource");

 20160409 javaweb 数据库连接池

 配置文件context.xml

<?xml version="1.0" encoding="utf-8" ?>
<Context>
    <Resource name="mySource"
            auth="Container"
            type="javax.sql.DataSource"
            username="root"
            password=""
            driverClassName="com.mysql.jdbc.Driver"
            url="jdbc:mysql://localhost:3306/database01?Unicode=true&amp;characterEncoding=utf-8"
            maxActive="8"
            maxIdle="4"/>
</Context>

示例代码:

package com.dzq.init;

import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;


@WebServlet("/DataSourceInitServlet")
public class DataSourceInitServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;
       
   
    
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        
    }

    
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
    @Override
    public void init() throws ServletException {
        try{
            Context initCtx = new InitialContext();
            Context jndi = (Context) initCtx.lookup("java:comp/env");
            DataSource source = (DataSource) jndi.lookup("mySource");
            
            Connection conn = source.getConnection();
            PreparedStatement ps = conn.prepareStatement("select * from account");
            ResultSet rs = ps.executeQuery();
            while(rs.next()){
                String name = rs.getString("name");
                System.out.println(name);
            }
            rs.close();
            ps.close();
            conn.close();
            
        }catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }
}