连接池

作者: 达摩君 | 来源:发表于2017-11-14 18:30 被阅读23次

数据库连接池

1、连接池原理
连接池原理.png

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

2、编写标准的数据源

自定义数据库连接池要实现javax.sql.DataSource接口,一般都叫数据源。

public class MyDataSource implements DataSource {

    private static LinkedList<Connection> pool = (LinkedList<Connection>) Collections.synchronizedList(new LinkedList<Connection>());

    static {
        try {
            for (int i = 0; i < 10; i ++) {
                Connection conn = DBUtils.getConnection();
                pool.add(conn);
            }
        } catch (Exception e) {
            throw new ExceptionInInitializerError("初始化数据库连接失败,请检查配置文件是否正确");
        }

    }

    @Override
    public Connection getConnection() throws SQLException {
        Connection conn = null;
        if (pool.size() > 0) {
            conn = pool.removeFirst();
            MyConnection myConn = new MyConnection(conn,pool);
            return myConn;
        } else {
            throw new RuntimeException("服务器忙");
        }
    }

    @Override
    public Connection getConnection(String username, String password) throws SQLException {
        return null;
    }

    @Override
    public <T> T unwrap(Class<T> iface) throws SQLException {
        return null;
    }

    @Override
    public boolean isWrapperFor(Class<?> iface) throws SQLException {
        return false;
    }

    @Override
    public PrintWriter getLogWriter() throws SQLException {
        return null;
    }

    @Override
    public void setLogWriter(PrintWriter out) throws SQLException {

    }

    @Override
    public void setLoginTimeout(int seconds) throws SQLException {

    }

    @Override
    public int getLoginTimeout() throws SQLException {
        return 0;
    }

    @Override
    public Logger getParentLogger() throws SQLFeatureNotSupportedException {
        return null;
    }
}
3、编写数据源时遇到的问题和解决方法

装饰设计模式:使用频率很高
目的:改写已存在的类的某个方法或某些方法,装饰设计模式(包装模式)
口诀:
1、编写一个类,实现与被包装类相同的接口。(具备相同的行为)
2、定义一个被包装类类型的变量。
3、定义构造方法,把被包装类的对象注入,给被包装类变量赋值。
4、对于不需要改写的方法,调用原有的方法。
5、对于需要改写的方法,写自己的代码

public class MyConnection implements Connection {

    private Connection oldConnection;
    private LinkedList<Connection> pool;

    public MyConnection(Connection oldConnection, LinkedList<Connection> pool) {
        this.oldConnection = oldConnection;
        this.pool = pool;
    }

    @Override
    public void close() throws SQLException {
//重写关闭方法
        pool.addLast(oldConnection);
    }

    @Override
    public Statement createStatement() throws SQLException {
        return oldConnection.createStatement();
    }

    @Override
    public PreparedStatement prepareStatement(String sql) throws SQLException {
        return oldConnection.prepareStatement(sql);
    }

    @Override
    public CallableStatement prepareCall(String sql) throws SQLException {
        return oldConnection.prepareCall(sql);
    }
    ........
}
public class Test {
    public static void main(String[] args) {

        Connection conn = null;
        PreparedStatement ps = null;
        DataSource ds = new MyDataSource();

        try {
            conn = ds.getConnection();
            ps = conn.prepareStatement("sql");
            //.......
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

    }
}

默认适配器:装饰设计模式一个变体
1、编写一个类,实现与被包装类相同的接口。(具备相同的行为)
2、定义一个被包装类类型的变量。
3、定义构造方法,把被包装类的对象注入,给被包装类变量赋值。
4、对于不需要改写的方法,调用原有的方法。

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

DBCP

DBCP:Apache推出的Database Connection Pool
使用步骤:

  1. 添加jar包 commons-dbcp-1.4.jar commons-pool-1.5.6.jar
  2. 添加属性资源文件
  3. 编写数据源工具类
public class DBCPUtils {
    private static DataSource ds = null;

    static {
        Properties prop = new Properties();
        try {
            //根据DBCPUtiles的class,加载配置文件
            prop.load(DBCPUtils.class.getClassLoader().getResourceAsStream("dbcpconfig.properties"));
            ds = BasicDataSourceFactory.createDataSource(prop);//得到一个数据源
        } catch (Exception e) {
            throw new ExceptionInInitializerError("初始化错误,请检查配置文件");
        }
    }

    public static Connection getConnection() {
        try {
            return ds.getConnection();
        } catch (SQLException e) {
            throw new RuntimeException("服务器忙。。。");
        }
    }

    public void release(Connection conn, Statement stmt, ResultSet rs) {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            rs = null;
        }
        if (stmt != null) {
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            stmt = null;
        }
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            conn = null;
        }
    }
}
C3P0

使用步骤:
1、添加jar包
2、编写配置文件
c3p0-config.xml,放在classpath中,或classes目录中

<?xml version="1.0" encoding="utf-8" ?>

<c3p0-config>
    <default-config>
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql:///testdb</property>
        <property name="user">root</property>
        <property name="password">root</property>
        <property name="automaticTestTable">con_test</property>
        <property name="checkoutTimeout">30000</property>
        <property name="idleConnectionTestPeriod">30</property>
        <property name="initialPoolSize">10</property>
        <property name="maxIdleTime">30</property>
        <property name="maxPoolSize">100</property>
        <property name="minPoolSize">10</property>
        <property name="maxStatements">200</property>

        <user-overrides user="test-user">
            <property name="maxPoolSize">10</property>
            <property name="minPoolSize">1</property>
            <property name="maxStatements">0</property>
        </user-overrides>

    </default-config>

</c3p0-config>

3、编写工具类:

public class C3P0Util  {

    private static ComboPooledDataSource cpds = new ComboPooledDataSource();

    public static Connection getConnection() {
        try {
            return cpds.getConnection();
        } catch (SQLException e) {
            throw new RuntimeException("服务器错误");
        }
    }

    public void release(Connection conn, Statement stmt, ResultSet rs) {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            rs = null;
        }
        if (stmt != null) {
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            stmt = null;
        }
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            conn = null;
        }
    }

}

用JavaWeb服务器管理数据源:Tomcat

开发JavaWeb应用,必须使用一个JavaWeb服务器,JavaWeb服务器都内置数据源。
Tomcat:(DBCP)
数据源只需要配置服务器即可。
配置数据源的步骤:
1、拷贝数据库连接的jar到tomcatlib目录下
2、配置数据源XML文件

  • 如果把配置信息写在tomcat下的conf目录的context.xml中,那么所有应用都能使用此数据源。
  • 如果是在当前应用的META-INF中创建context.xml, 编写数据源,那么只有当前应用可以使用。
<Context>
    <Resource name="jdbc/TomcatDBCP" auth="Container" type="javax.sql.DataSource"
              maxTotal="100" maxIdle="30" maxWaitMillis="10000"
              username="root" password="root" driverClassName="com.mysql.jdbc.Driver"
              url="jdbc:mysql:///day13"/>
</Context>

3、使用连接池

<%
      Context initContext = new InitialContext();
//      Context envContext  = (Context)initContext.lookup("java:/comp/env");
      DataSource ds = (DataSource)initContext.lookup("java:/comp/env/jdbc/TomcatDBCP");
      Connection conn = ds.getConnection();
      out.print(conn);

    %>

JNDI:java nameing directory interface
JNDI容器就是一个Map

key(String) value(Object)
path+name 对象
path+"jdbc/day16" DataSource对象

相关文章

  • 撩课-JavaWeb之什么是连接池与连接池使用

    什么是连接池 没有连接池的情况 数据库连接池 池 连接池 作用 数据库连接池 示意图 连接池中的属性 连接池使用 ...

  • 代码分析

    interface 相关配置 默认子连接池 定义全局连接池 注册连接池 默认子连接池 连接

  • JDBC 进阶——连接池

    本文包括传统JDBC的缺点连接池原理自定义连接池开源数据库连接池DBCP连接池C3P0连接池Tomcat内置连接池...

  • SSM框架mybatis深入了解(二)

    一、mybatis中的连接池及事务控制 1.mybatis中的连接池使用及分析 1.1 连接池简介连接池是创建和...

  • JDBC进阶学习笔记

    JDBC进阶 JDBC连接池 1. 常见的JDBC连接池 c3p0 开源连接池 druid 阿里的开源数据库连接池...

  • Druid连接池

    第一章 连接池 一.1. 遇到的问题-引出连接池 | | 一.2. 连接池思想 | | 一.3. 连接池的概述 一...

  • JAEE学习笔记(19)事物与连接池

    目录 1.事务2.连接池 1.连接池概念 2.自定义连接池 3.开源连接池(c3p0) 复习: =========...

  • Redis连接池的使用

    1 . 安装 2 . 注册 redis 连接池 使用连接池

  • DBUtiles的使用

    自定义连接池: 学会用resourcebundle来加载properties文件 运用连接池的技术 连接池技术原理...

  • 连接池原理

    什么是连接池 上游对下游发起的请求,比如数据库连接池crud操作 为什么使用连接池? 如果不使用连接池,每次请求到...

网友评论

      本文标题:连接池

      本文链接:https://www.haomeiwen.com/subject/bacfvxtx.html