数据库连接池

Posted loveer

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据库连接池相关的知识,希望对你有一定的参考价值。

JDBC方式操作数据库

java应用程序访问数据库的过程:

   ①装载数据库驱动程序;

   ②通过jdbc建立数据库连接;

   ③访问数据库,执行sql语句;

   ④断开数据库连接。


缺点:
    每一次web请求都要建立一次数据库连接。建立连接是一个费时的活动,而且系统还要分配内存资源。

    不能控制被创建的连接对象数,系统资源会被毫无顾及的分配出去,如连接过多,也可能导致内存泄漏,服务器崩溃。


JDBC最常用的资源有三类:
    Connection: 数据库连接。
    Statement: 会话声明。
    ResultSet: 结果集游标。

JDBC示例

public class BigData {

    String url="jdbc:mysql://localhost:3306/littledonkey";
    String username = "";
    String password = "";
    String driverclassname = "com.mysql.jdbc.Driver";

    public void store(){

        Connection connection=null;
        PreparedStatement pre=null;
        try {
            /**
             * 连接sql
             */
            Class.forName(driverclassname);
            connection = DriverManager.getConnection(url,username,password);

            String sql = "insert into music values(?,?)";

            /**
             * 获取properedstatement对象
             */
            pre = connection.prepareStatement(sql);
            pre.setString(1,"童话镇.mp3");

            /**
             * 将MP3转换成字节数组,然后转换成blob
             */
            byte[] bytes = IOUtils.toByteArray(new FileInputStream("D:陈一发儿-童话镇.mp3"));
            Blob serialBlob = new SerialBlob(bytes);
            pre.setBlob(2,serialBlob);

            /**
             * 发送sql语句
             */
            pre.executeUpdate();
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if(resultSet != null)  resultSet.close();
            if(pre != null)  pre.close();
        }
    }


    public void gain() throws SQLException {

        Connection connection=null;
        PreparedStatement pre=null;
        ResultSet resultSet=null;

        try {
            Class.forName(driverclassname);
            connection = DriverManager.getConnection(url,username,password);

            String sql = "select * from music";
            pre = connection.prepareStatement(sql);
            resultSet = pre.executeQuery();

            while(resultSet.next()){
                Blob data = resultSet.getBlob("data");
                InputStream in = data.getBinaryStream();
                String name =resultSet.getString("music_name");
                OutputStream out = new FileOutputStream(name);
                IOUtils.copy(in,out);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }finally {
            if(resultSet != null)  resultSet.close();
            if(pre != null)  pre.close();
            if(connection != null) connection.close();
        }
    }
}

数据库连接池

预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需从“缓冲池”中取出一个,使用完毕之后再放回去。

连接池示例

public class DruidUtils {
    //定义成员变量 DataSource
    private static DataSource ds;

    //初始化载入配置文件
    static{
        Properties pro = new Properties();
        InputStream rs = DruidUtils.class.getClassLoader().getResourceAsStream("druid.properties");
        try {
            pro.load(rs);
            ds = DruidDataSourceFactory.createDataSource(pro);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static Connection getConnection() throws SQLException {
        return ds.getConnection();
    }

    public static DataSource getDataSource(){
        return ds;
    }

    public static void close(Statement sta,Connection con){
        if(sta!=null) {
            try {
                sta.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(con!=null) {
            try {
                /**
                 * 数据库缓冲池使用代理模式重写了Connection
                 *      用close方法,并不是真正关闭了数据库,
                 *      而是将该connection返回到数据库缓冲池。
                 *      如果不close,尽管过段时间会自动返回数据库缓冲池,
                 *      但在大量数据操作时,仍然可能引起缓冲池中没有可用连接,从而创建新连接,使速度变慢
                 */
                con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    public static void close(ResultSet re,Statement sta,Connection con){
        if(re!=null) {
            try {
                re.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        close(sta,con);
    }
}

以上是关于数据库连接池的主要内容,如果未能解决你的问题,请参考以下文章

newCacheThreadPool()newFixedThreadPool()newScheduledThreadPool()newSingleThreadExecutor()自定义线程池(代码片段

连接池报错 Proxool Provider unable to load JAXP configurator file: proxool.xml

MySQL与Redis数据库连接池介绍(图示+源码+代码演示)

稳定性 耗时 监控原因分析-- dubbo rpc 框架 的线程池,io 连接模型. 客户端,服务端

基于UniDac的数据库连接池

数据库连接池的Java连接池