当前位置: 澳门新濠3559 > 编程 > 正文

没有达到最大连接数,它允许应用程序重复使用

时间:2019-10-07 13:15来源:编程
一.自定义连接池 完成思路 1.点名早先化连接数目,程序运维时就推行创立2.钦赐最地拉那接数3.点名当前使用的连接数(无法超过最菲尼克斯接数) 一 连接池概念 数据库连接池担任分

一.自定义连接池

完成思路

1.点名早先化连接数目,程序运维时就推行创立2.钦赐最地拉那接数3.点名当前使用的连接数(无法超过最菲尼克斯接数)

一 连接池概念
数据库连接池担任分配、管理和刑释数据库连接,它同意应用程序重复使用叁个存世的数据库连接,实际不是再重新创立二个;释放空闲时间超越最大空闲时间的数据库连接来防止因为从没自由数据库连接而孳生的数据库连接遗漏。那项本领能一览无余增进对数据库操作的品质。
二 思路

连接池引进

  • 思维:程序中三番五次如哪个地点理?(MySQL的连日最多也就几百个, web项目标并发数非常大的时候就远远不足用, 数据库的属性就非常不够强大了-- 所以使用Oracle数据库)
    1. 总是财富宝贵;必要对连日处理
    2. 三番五次:操作数据库,创设连接; 操作停止, 关闭连接
  • 剖析 : 涉及频仍的一连的开辟、关闭,影响程序的运转作用
  • 连日来管理 : 预先成立一组连接,不经常每便抽取三个; 用完后, 放回;

思考:
前后相继中三回九转怎么样保管?

代码达成:

1.连连池类2.钦命全局参数:伊始化数目,最罗安达接数,当前一而再,连接池会集3.构造函数:循环成立八个再而三4.写三个创办连接的措施5.到手连接判定:--池中有三番五次,直接拿--池中没有连接,推断是或不是达到做第Billy斯接数;达到,抛出非常;未有抵达最浦那接数,制造新的连天6.放出连接连接放回集和中

  • 点名起始化连接数目程序运行时就奉行创立
  • 点名最菲尼克斯接数目
  • 点名当前接纳连接数目

学习连接池:

  • 上学习成绩杰出异的连接池组件: DBCP, C3P0
  • 自定义叁个连连池 :

    • 程序完成思路:

      1. 点名“初阶化连接数目” 【3】
        (App运转时候,就实施成立!)
      2. 点名“最亚松森接数” 【6】
      3. 内定“当前应用连接个数” 【无法抢先最辛辛那提接数】
    • 代码完毕:

      1. MyPool.java 连接池类,
      2. 点名全局参数: 伊始化数目、最辛辛那提接数、当前连连、 连接池集结
      3. 构造函数:循环创造3个连续
      4. 写三个创设连接的主意
      5. 得到连接
      • 看清: 池中有连接, 直接拿
      • 池中尚无连接,
      • 推断,是或不是到达最奥斯汀接数; 达到,抛出相当;未有高达最菲尼克斯接数,制造新的延续
      1. 放出连接 : 连接放回群集中(..)
package anderson.my_pool;
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.util.LinkedList;
/**
 * 自定义连接池, 管理连接
 * 代码实现:
    1.  MyPool.java  连接池类,   
    2.  指定全局参数:  初始化数目、最大连接数、当前连接、   连接池集合
    3.  构造函数:循环创建3个连接
    4.  写一个创建连接的方法
    5.  获取连接
    ------>  判断: 池中有连接, 直接拿
     ------>                池中没有连接,
    ------>                 判断,是否达到最大连接数; 达到,抛出异常;没有达到最大连接数,
            创建新的连接
    6. 释放连接
     ------->  连接放回集合中(..)
 *
 */
public class MyPool {
    private int init_count = 3;     // 初始化连接数目
    private int max_count = 6;      // 最大连接数
    private int current_count = 0;  // 记录当前使用连接数
    // 连接池 (存放所有的初始化连接)
    private LinkedList<Connection> pool = new LinkedList<Connection>();
    //1.  构造函数中,初始化连接放入连接池
    public MyPool() {
        // 初始化连接
        for (int i=0; i<init_count; i  ){
            // 记录当前连接数目
            current_count  ;
            // 创建原始的连接对象
            Connection con = createConnection();
            // 把连接加入连接池
            pool.addLast(con);
        }
    }
    //2. 创建一个新的连接的方法
    private Connection createConnection(){
        try {
            Class.forName("com.mysql.jdbc.Driver");
            // 原始的目标对象
            final Connection con = DriverManager.getConnection("jdbc:mysql:///jdbc_demo", "root", "root");
            /**********对con对象代理**************/      
            // 对con创建其代理对象
            Connection proxy = (Connection) Proxy.newProxyInstance(
                    con.getClass().getClassLoader(),    // 类加载器
                    //con.getClass().getInterfaces(),   // 当目标对象是一个具体的类的时候 
                    new Class[]{Connection.class},      // 目标对象实现的接口
                    new InvocationHandler() {           // 当调用con对象方法的时候, 自动触发事务处理器
                        @Override
                        public Object invoke(Object proxy, Method method, Object[] args)
                                throws Throwable {
                            // 方法返回值
                            Object result = null;
                            // 当前执行的方法的方法名
                            String methodName = method.getName();                           
                            // 判断当执行了close方法的时候,把连接放入连接池
                            if ("close".equals(methodName)) {
                                System.out.println("begin:当前执行close方法开始!");
                                // 连接放入连接池 (判断..)
                                pool.addLast(con);
                                System.out.println("end: 当前连接已经放入连接池了!");
                            } else {
                                // 调用目标对象方法
                                result = method.invoke(con, args);
                            }
                            return result;
                        }
                    }
            );
            return proxy;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    //3. 获取连接
    public Connection getConnection(){  
        // 3.1 判断连接池中是否有连接, 如果有连接,就直接从连接池取出
        if (pool.size() > 0){
            return pool.removeFirst();
        }
        // 3.2 连接池中没有连接: 判断,如果没有达到最大连接数,创建;
        if (current_count < max_count) {
            // 记录当前使用的连接数
            current_count  ;
            // 创建连接
            return createConnection();
        }
        // 3.3 如果当前已经达到最大连接数,抛出异常
        throw new RuntimeException("当前连接已经达到最大连接数目 !");
    }
    //4. 释放连接
    public void realeaseConnection(Connection con) {
        // 4.1 判断: 池的数目如果小于初始化连接,就放入池中
        if (pool.size() < init_count){
            pool.addLast(con);
        } else {
            try {
                // 4.2 关闭 
                current_count--;
                con.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
    }
    public static void main(String[] args) throws SQLException {
        MyPool pool = new MyPool();
        System.out.println("当前连接: "   pool.current_count);  // 3    
        // 使用连接
        pool.getConnection();
        pool.getConnection();
        Connection con4 = pool.getConnection();
        Connection con3 = pool.getConnection();
        Connection con2 = pool.getConnection();
        Connection con1 = pool.getConnection();
        // 释放连接, 连接放回连接池
//      pool.realeaseConnection(con1);
        /*
         * 希望:当关闭连接的时候,要把连接放入连接池!【当调用Connection接口的close方法时候,希望触发pool.addLast(con);操作】
         *                                                                          把连接放入连接池
         * 解决1:实现Connection接口,重写close方法
         * 解决2:动态代理
         */
        con1.close();

        // 再获取
        pool.getConnection();
        System.out.println("连接池:"   pool.pool.size());      // 0
        System.out.println("当前连接: "   pool.current_count);  // 3
    }
}

1.老是财富宝贵:须要对连年管理
2.连接:
a) 操作数据库,创造连接
b) 操作结束,关闭

自定义连接池

1.创办连接池中3个Connection连接2.最辛辛那提接数6个

public class MyConnectionPool { private int init_count = 3;//初始化链接数目 private int max_count = 6;//最大连接数 private int current_count = 0;//记录当前使用的连接数 //连接池:存放所有的初始化连接 private LinkedList<Connection> pool = new LinkedList<Connection>(); //1.构造函数,初始化连接放入连接池 public MyConnectionPool() { for (int i = 0; i < init_count; i  ) { current_count  ;//记录当前连接数 //把连接加到连接池 pool.addLast(creatConnection; } } //2.创建一个新的连接方法 private Connection creatConnection() { try { Class.forName("com.mysql.jdbc.Driver"); String url="jdbc:mysql://localhost:3306/car";//2.指定连接数据库的地址名称 String user="root"; String passWord = "root";//指定用户名和密码 return DriverManager.getConnection(url,user,passWord);//3获取数据库连接 } catch (Exception e) { e.printStackTrace(); } return null; } //3.获取连接 public Connection getConnection() { //池中有连接,直接拿 if (pool.size { return pool.removeFirst();//将第一个list集合删除并返回 } //池中没有连接,判断是否达到做大连接数;没有达到最大连接数,创建新的连接 if (current_count < max_count) { //记录当前使用的连接数 current_count  ; //创建连接 return creatConnection(); } //达到最大连接数,抛出异常; throw new RuntimeException("当前已经达到最大连接数"); } //4.释放连接 public void realeaseConnection(Connection conn){ //判断:连接池中数目如果小于初始化连接,就放入池中 if(pool.size()<init_count){ pool.addLast; }else{ try { //关闭连接 current_count--; conn.close(); } catch (SQLException e) { e.printStackTrace(); } } }}
  • ###### 测试
 //测试连接 public static void main(String[] args){ MyConnectionPool pool = new MyConnectionPool(); System.out.println("连接池:" pool.current_count); Connection conn1 = pool.getConnection(); pool.getConnection(); pool.getConnection(); pool.getConnection(); pool.getConnection(); pool.getConnection(); pool.realeaseConnection; pool.getConnection(); System.out.println("当前连接池中:" pool.pool.size; System.out.println("当前连接:" pool.current_count); }

图片 1

三 落成进度

连接池代理

  • 代理 : 倘使对某些接口中的有些钦命的点子的机能拓宽扩展,而不想完结接口里拥有办法,能够应用(动态)代理方式! 使用动态代理,能够监测接口中方法的实施!
  • Java中代理格局:静态/动态/Cglib代理(spring)
  • 怎么对Connection对象,生成叁个代理对象:
// Proxy 类
 static Object newProxyInstance(
    ClassLoader loader,    // 当前使用的类加载器
    Class<?>[] interfaces,   // 目标对象(Connection)实现的接口类型
    InvocationHandler h   // 事件处理器:当执行上面接口中的方法的时候,就会自动触发事件处理器代码,把当前执行的方法(method)作为参数传入
)  
// 对con创建其代理对象
  Connection proxy = (Connection) Proxy.newProxyInstance(
  con.getClass().getClassLoader(),    // 类加载器
  //con.getClass().getInterfaces(),   // 当目标对象是一个具体的类的时候调用该方法 
  new Class[]{Connection.class},      // 目标对象是一个接口的时候调用该方法
  new InvocationHandler() {    // 当调用con对象方法的时候, 自动触发事务处理器
      @Override
      public Object invoke(Object proxy, Method method, Object[] args)
                                throws Throwable {
            // 方法返回值
            Object result = null;
            // 当前执行的方法的方法名
            String methodName = method.getName();
            // 判断当执行了close方法的时候,把连接放入连接池
            if ("close".equals(methodName)) {
                  System.out.println("begin:当前执行close方法开始!");
                  // 连接放入连接池 (判断..)
                  pool.addLast(con);
                  System.out.println("end: 当前连接已经放入连接池了!");
           } else {
                  // 调用目标对象方法
                  result = method.invoke(con, args);
            }
            return result;
        }
    }
  );
  return proxy;
  • 代理的下结论:使用代理, 能够在不兑现接口的动静, 对接口的艺术开展扩大, 增多额外的客商须要的事体逻辑(掌握会用)

分析:
设计每每的连接的开荒关闭,影响程序的运维作用。

小说文集:JavaEE--学习笔记

  • 钦定全局变量:开端化数目,最明斯克接数,当前连接数,连接池集合
  • 构造函数:循环创制 “伊始化数目” 连接
  • 数据库连接格局
  • 赢得连接
    • 池中有连日,直接拿
    • 池中尚无连接,决断是不是达到规定的规范做罗安达接数;到达,抛出特别;没有直达最厦门接数,创制新的接连
  • 获释和三番五次(连接放回集合中)
    四 代码

开源的连接池技能

  • 概述 : Sun约定:若是是连接池技艺, 供给实现二个接口 javax.sql.DataSource;
  • 连接池 : DBCP, C3P0
  • DBCP连接池:
    • DBCP 是 Apache 软件基金组织下的开源连接池完结,使用DBCP数据源,应用程序应在系统中加进如下两个jar 文件:
      1. Commons-dbcp.jar :连接池的贯彻
      2. Commons-pool.jar :连接池完结的正视库
    • 汤姆cat 的连接池就是利用该连接池来达成的。该数据库连接池既可以够与应用服务器整合应用,也可由应用程序独立行使
    • 核心类:BasicDataSource
    • 动用步骤 :
      1. 引入jar文件
      2. commons-dbcp-1.4.jar
      3. commons-pool-1.5.6.jar
package anderson.my_dbcp;
import java.io.InputStream;
import java.sql.Connection;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.dbcp.BasicDataSourceFactory;
import org.junit.Test;
public class App_DBCP {
    // 1. 硬编码方式实现连接池
    @Test
    public void testDbcp() throws Exception {
        // DBCP连接池核心类
        BasicDataSource dataSouce = new BasicDataSource();
        // 连接池参数配置:初始化连接数、最大连接数 / 连接字符串、驱动、用户、密码
        dataSouce.setUrl("jdbc:mysql:///jdbc_demo");            //数据库连接字符串
        dataSouce.setDriverClassName("com.mysql.jdbc.Driver");  //数据库驱动
        dataSouce.setUsername("root");                          //数据库连接用户
        dataSouce.setPassword("root");                          //数据库连接密码
        dataSouce.setInitialSize(3);  // 初始化连接
        dataSouce.setMaxActive(6);    // 最大连接
        dataSouce.setMaxIdle(3000);   // 最大空闲时间
        // 获取连接
        Connection con = dataSouce.getConnection();
        con.prepareStatement("delete from admin where id=3").executeUpdate();
        // 关闭
        con.close();
    }
    @Test
    // 2. 【推荐】配置方式实现连接池  ,  便于维护
    public void testProp() throws Exception {
        // 加载prop配置文件
        Properties prop = new Properties();
        // 获取文件流
        InputStream inStream = App_DBCP.class.getResourceAsStream("db.properties");

/** --- db.properties ---
  * url=jdbc:mysql:///jdbc_demo
  * driverClassName=com.mysql.jdbc.Driver
  * username=root
  * password=root
  * initialSize=3
  * maxActive=6
  * maxIdle=3000
  */
        // 加载属性配置文件
        prop.load(inStream);
        // 根据prop配置,直接创建数据源对象
        DataSource dataSouce = BasicDataSourceFactory.createDataSource(prop);

        // 获取连接
        Connection con = dataSouce.getConnection();
        con.prepareStatement("delete from admin where id=4").executeUpdate();
        // 关闭
        con.close();
    }
}  
  • C3P0连接池
    • C3P0连接池:最常用的连接池本领!Spring框架,私下认可帮衬C3P0连接池本领!
    • C3P0连接池,核心类:CombopooledDataSource ds;
    • 使用:
      1. 下载,引入jar文件: c3p0-0.9.1.2.jar
      2. 采取连接池,创设连接
      3. 硬编码格局
      4. 铺排格局(xml)
package anderson.my_c3p0;

import java.sql.Connection;
import java.sql.PreparedStatement;

import org.junit.Test;

import com.mchange.v2.c3p0.ComboPooledDataSource;

public class App {

    @Test
    //1. 硬编码方式,使用C3P0连接池管理连接
    public void testCode() throws Exception {
        // 创建连接池核心工具类
        ComboPooledDataSource dataSource = new ComboPooledDataSource();
        // 设置连接参数:url、驱动、用户密码、初始连接数、最大连接数
        dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/jdbc_demo");
        dataSource.setDriverClass("com.mysql.jdbc.Driver");
        dataSource.setUser("root");
        dataSource.setPassword("root");
        dataSource.setInitialPoolSize(3);
        dataSource.setMaxPoolSize(6);
        dataSource.setMaxIdleTime(1000);

        // ---> 从连接池对象中,获取连接对象
        Connection con = dataSource.getConnection();
        // 执行更新
        con.prepareStatement("delete from admin where id=7").executeUpdate();
        // 关闭
        con.close();
    }

    @Test
    //2. XML配置方式,使用C3P0连接池管理连接
    public void testXML() throws Exception {
        // 创建c3p0连接池核心工具类
        // 自动加载src下c3p0的配置文件【c3p0-config.xml】
        ComboPooledDataSource dataSource = new ComboPooledDataSource();// 使用默认的配置
        PreparedStatement pstmt = null;

        // 获取连接
        Connection con = dataSource.getConnection();
        for (int i=1; i<11;i  ){
            String sql = "insert into employee(empName,dept_id) values(?,?)";
            // 执行更新
            pstmt = con.prepareStatement(sql);
            pstmt.setString(1, "Rose"   i);
            pstmt.setInt(2, 1);
            pstmt.executeUpdate();
        }
        pstmt.close();
        // 关闭
        con.close();
    }
}

顾客每一次央求都必要向数据库获得链接,而数据库成立连接常常供给消耗相对十分大的能源,创立时间也较长。借使网站一天10万访问量,数据库服务器就供给创立10万次接二连三,相当的大的浪费数据库的财富,并且极易导致数据库服务器内部存款和储蓄器溢出、拓机。

分页技巧

  • 分页本事:JSP页面,用来呈现数据! 假诺数量有一千条,分页突显,每页呈现10条,共100页; 好处: 利于页面布局,且展现的频率高!

  • 分页关键点:

    1. 分页SQL语句:
    • SELECT * FROM User LIMIT 0, 10; 第二个参数: 查询初步行; 第三个参数: 重回多少行
    • SELECT * FROM User LIMIT 10;
    1. 后台管理: dao/service/servlet/JSP

连日管理:
先行成立一组连接,有一点点饿时候每趟抽取贰个;用完后,放回。

package utils;

import java.sql.Connection;
import java.sql.DriverManager;
import java.util.LinkedList;

/**
 * Created by pc on 2017/9/10.
 */
public class MyConnectionPool {
     int init_count = 3; //初始化链接数目
     int max_count = 10;  //最大链接数
     int current_count = 0;  //记录当前使用的链接数
    //连接池:存放所有的初始化链接
    public LinkedList<Connection> pool = new LinkedList<Connection>();
    //1.构造函数,初始化连接放入连接池
   public MyConnectionPool(){
        for (int i = 0;i < init_count;i  ){
            current_count  ;//记录当前连接数
            //把链接加到连接池
            pool.addLast(creatConnection());
}
    }
    //2.创建一个新的链接方法
    public Connection creatConnection(){
        try{
            Class.forName("com.mysql.jdbc.Driver");//加载驱动
            String url = "jdbc:mysql://localhost:3306/test";//加载数据库链接
            String user = "root";//配置用户名
            String password = "root";//配置密码
            return DriverManager.getConnection(url,user,password);//获取链接
        }catch (Exception e){
            throw new RuntimeException(e);
        }
    }
    //3.获取链接
    public Connection getConnection(){
        //池中有链接直接拿
        if (pool.size() > 0){
            return  pool.removeFirst();//将第一个list集合删除并返回
        }
        //池中没有链接,判断是否达到最大连接数;如果没有,创建新的链接
        if (current_count < max_count){
            //记录当前使用的连接数
            current_count  ;
            //创建链接
            return  creatConnection();
        }
        //达到最大链接,抛出异常
        throw new  RuntimeException("当前已经达到最大连接数");
    }
    //4.释放链接
    public void realeaseConnection(Connection conn){
        //判断:连接池中数目如果小于初始化连接,就放入池中
        if (pool.size() < init_count){
            pool.addLast(conn);
        }else {
            try {
                //关闭连接
                    current_count--;
                    conn.close();
            }catch (Exception e){
                throw new RuntimeException(e);
            }
        }
    }
}

学习连接池:
1)自定义叁个连接池
2)学习能够的连接池组件
a) DBCP
b)C3P0

图片 2

程序完结思路:

结果展现

1)制订“初阶化连接数目”(APP运转的时候,就实行创造)
2)钦定“最罗安达接数”
3)制订“当前应用连接个数”(无法越过最加纳Ake拉接数)

图片 3

图片.png

参考:http://www.javaweb1024.com/java/JavaWebzhongji/2015/06/01/736.html

数据库连接是一种重大的点滴的高昂的能源,这点在多顾客的网页应用程序中体现的越来越卓绝。对数据库连接的治本能显然影响到一切应用程序的伸缩性和健壮性,影响到程序的品质指标。数据库连接池负担分配,管理和自由数据库连接,它同意应用程序重复使用一个共处的数据库连接,实际不是重复建立一个。

代码完结:
1)MyPool.java 连接池类
2)钦赐全局参数:初阶haunted数目,最阿比让接数,当前连日
3)构造函数:循环成立多个接二连三
4)写二个创办连接的措施
5)获取连接
--->推断:池中有连日,直接拿
---> 池中从不连接,
---> 判别,是不是达到规定的标准最罗安达接数;到达,抛出极其;未有高达最达累斯萨Lamb接数,新的总是
6)释放连接

自定义连接池

2.开源的连接池

概述:
Sun公司预约,即便是连接池技能,供给贯彻三个接口!Javax.sql.DataSource;
(DBCP和C3P0都要促成丰富接口)

1)DBCP连接池

连接池也叫DataSource。
连接池的效果与利益:管理总是。

DBCP是Apache软件基金组织下的开源连接池完成,使用DBCP数据源,应用程序应该在系统中加进如下多个jar包:

  • Commons-dbcp.jar: 连接池的实现
  • Commons-pool.jar: 连接池完结的注重库
    汤姆cat的连接池正式使用该连接池来兑现的。该数据库连接池不只能够与应用服务器整合利用,也可由应用程序独立使用。

核心类:BasicDataSource

图片 4

图片.png

编辑:编程 本文来源:没有达到最大连接数,它允许应用程序重复使用

关键词: 澳门新濠3559