「MySQL」自定义数据库连接池和开源数据库连接池的使用

Mysql-数据库优化-连接参数 这个参数是管理连接池数量的,和线程池的思想一样,spring.datasource.druid.min-idle这个相当于核心线程数,无论怎样连接池始终保持这么多的连接数量。数据库连接池化的思想也就是提前将连接创建好并保存用的时候直接拿来用,同时要进行管理,也就有了上面这些相关的参数,如果不适用池化的思想,数据库会有一个最大的连接数,如果超过这个最大连接数,数据库直接无法处客户端的查询请求。可以看到一旦达到最大连接数就会报错,异常比例是相当高的,但是使用连接池就不会有这种大量报错的现象。 阅读详情

数据库连接池的概念

  • 数据库连接背景数据库连接是一种关键的、有限的、昂贵的资源,这一点在多用户的网页应用程序中体现得尤为突出。对数据库连接的管理能显著影响到整个应用程序的伸缩性和健壮性,影响到程序的性能指标。数据库连接池正是针对这个问题提出来的。
  • 数据库连接池数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个。这项技术能明显提高对数据库操作的性能。
  • 数据库连接池的原理没有使用数据库连接池:一个访问创建一个连接,使用完关闭连接。而频繁的创建和关闭连接非常耗时

  • 使用数据库连接池之后:提前准备一些数据库连接,使用时从池中取出,用完归还连接池

自定义连接池

初探连接池

自定义JDBC工具类

配置文件 config.properties

driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql://主机名:3306/数据库名
username=用户名
password=密码

JDBCUtils工具类

public class JDBCUtils {
    private JDBCUtils() {}  //构造函数私有化

    private static String driverClass;
    private static String url;
    private static String username;
    private static String password;
    private static Connection con;

    static {
        try {
            InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("config.properties");
            Properties properties = new Properties();
            properties.load(is);
            driverClass = properties.getProperty("driverClass");
            url = properties.getProperty("url");
            username = properties.getProperty("username");
            password = properties.getProperty("password");
            Class.forName(driverClass);

        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    public static Connection getConnection() {  //获取连接对象
        try {
            con = DriverManager.getConnection(url, username, password);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return con;
    }
    //关闭连接(有查询结果集)
    public static void close(Connection con, Statement stat, ResultSet res) {
        if (con != null) {
            try {
                con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (stat != null) {
            try {
                stat.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (res != null) {
            try {
                res.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    //关闭连接(无查询结果集)
    public static void close(Connection con, Statement stat) {
        close(con, stat, null);
    }
}

实现连接池类

定义一个连接池类并实现 java.sql.DataSource 接口。

Connection getConnection();  //获取数据库连接对象
public class MyDataSource implements DataSource{
    //定义集合容器,用于保存多个数据库连接对象
    //使用Collections 工具类实现集合的线程同步
    private static List<Connection> pool = Collections.synchronizedList(new ArrayList<Connection>());

    //静态代码块,生成10个数据库连接保存到集合中
    static {
        for (int i = 0; i < 10; i++) {
            Connection con = JDBCUtils.getConnection();
            pool.add(con);
        }
    }

    //返回连接池的大小
    public int getSize() {
        return pool.size();
    }

    //从池中返回一个数据库连接
    @Override
    public Connection getConnection() {
        if(pool.size() > 0) {
            //从池中获取数据库连接
            return pool.remove(0);
        }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;
    }
}

自定义连接池的测试

public class MyDataSourceTest {
    public static void main(String[] args) throws SQLException {
        MyDataSource dataSource = new MyDataSource();
        System.out.println("使用前连接池数量:" + dataSource.getSize());

        Connection con = dataSource.getConnection();

        String sql = "select * from emp";

        PreparedStatement pst = con.prepareStatement(sql);

        ResultSet res = pst.executeQuery();
        while (res.next()) {
            String ename = res.getString("ename");
            String job = res.getString("job");
            String hiredate = res.getString("hiredate");
            System.out.println("ename:" + ename + "\t job:" + job + "\t hiredate:" + hiredate);
        }

        res.close();
        pst.close();
        con.close();
        System.out.println("使用后连接池数量:" + dataSource.getSize());
    }
}

输出:

使用前连接池数量:10
ename:SMITH	 job:CLERK	 hiredate:1980-12-17
ename:ALLEN	 job:SALESMAN	 hiredate:1981-02-20
ename:WARD	 job:SALESMAN	 hiredate:1981-02-22
ename:JONES	 job:MANAGER	 hiredate:1981-04-02
ename:MARTIN	 job:SALESMAN	 hiredate:1981-09-28
ename:BLAKE	 job:MANAGER	 hiredate:1981-05-01
ename:CLARK	 job:MANAGER	 hiredate:1981-06-09
ename:SCOTT	 job:ANALYST	 hiredate:1987-04-19
ename:KING	 job:PRESIDENT	 hiredate:1981-11-17
ename:TURNER	 job:SALESMAN	 hiredate:1981-09-08
ename:ADAMS	 job:CLERK	 hiredate:1987-05-23
ename:JAMES	 job:CLERK	 hiredate:1981-12-03
ename:FORD	 job:ANALYST	 hiredate:1981-12-03
ename:MILLER	 job:CLERK	 hiredate:1982-01-23
使用后连接池数量:9

问题:虽然我们自定义了数据库连接池,但是连接关闭以后并没有归还给数据库连接池,还需要改进 归还连接 的问题

继承方式改进连接池

System.out.println(JDBCUtils.getConnection());
//com.mysql.jdbc.JDBC4Connection@470e2030

通过输出 Connection 的地址发现 Connection 类的实现类是 JDBC4Connection ,是否能够通过编写一个类继承 JDBC4Connection ,然后重写 close() 方法,在关闭连接的同时归还连接?

/*
      自定义Connection类
   */
  public class MyConnection1 extends JDBC4Connection {
      //声明连接对象和连接池集合对象
      private Connection con;
      private List<Connection> pool;
  
      //通过构造方法给成员变量赋值
      public MyConnection1(String hostToConnectTo, int portToConnectTo, Properties info, String databaseToConnectTo, String url,Connection con,List<Connection> pool) throws SQLException {
          super(hostToConnectTo, portToConnectTo, info, databaseToConnectTo, url);
          this.con = con;
          this.pool = pool;
      }
  
      //重写close()方法,将连接归还给池中
      @Override
      public void close() throws SQLException {
          pool.add(con);
      }
  }

但是这种方式行不通,通过查看JDBC工具类获取连接的方法我们发现:我们虽然自定义了一个子类,完成了归还连接的操作。但是 DriverManager 获取的还是 JDBC4Connection 这个对象,并不是我们的子类对象。而我们又不能整体去修改驱动包中类的功能!

//将之前的连接对象换成自定义的子类对象
  private static MyConnection1 con;
  
  public static Connection getConnection() {
      try {
          //等效于:MyConnection1 con = new JDBC4Connection();  子类引用指向父类对象,语法错误!
          con = DriverManager.getConnection(url,username,password);
      } catch (SQLException e) {
          e.printStackTrace();
      }
  
      return con;
  }

装饰设计模式改进连接池

自定义Connection类。通过装饰设计模式,实现和mysql驱动包中的Connection实现类相同的功能!

实现步骤:

  • 定义一个类,实现Connection接口
  • 定义Connection连接对象和连接池容器对象的变量
  • 提供有参构造方法,接收连接对象和连接池对象,对变量赋值
  • 在close()方法中,完成连接的归还
  • 剩余方法,只需要调用mysql驱动包的连接对象完成即可
public class MyConnection2 implements Connection {
  
      //2.定义Connection连接对象和连接池容器对象的变量
      private Connection con;
      private List<Connection> pool;
  
      //3.提供有参构造方法,接收连接对象和连接池对象,对变量赋值
      public MyConnection2(Connection con,List<Connection> pool) {
          this.con = con;
          this.pool = pool;
      }
  
      //4.在close()方法中,完成连接的归还
      @Override
      public void close() throws SQLException {
          pool.add(con);
      }
  
  
      @Override
      public Statement createStatement() throws SQLException {
          return con.createStatement();
      }
  
      @Override
      public PreparedStatement prepareStatement(String sql) throws SQLException {
          return con.prepareStatement(sql);
      }
  
      @Override
      public CallableStatement prepareCall(String sql) throws SQLException {
          return con.prepareCall(sql);
      }
  
      @Override
      public String nativeSQL(String sql) throws SQLException {
          return con.nativeSQL(sql);
      }
  
      @Override
      public void setAutoCommit(boolean autoCommit) throws SQLException {
          con.setAutoCommit(autoCommit);
      }
  
      @Override
      public boolean getAutoCommit() throws SQLException {
          return con.getAutoCommit();
      }
  
      @Override
      public void commit() throws SQLException {
          con.commit();
      }
  
      @Override
      public void rollback() throws SQLException {
          con.rollback();
      }
  
      @Override
      public boolean isClosed() throws SQLException {
          return con.isClosed();
      }
  
      @Override
      public DatabaseMetaData getMetaData() throws SQLException {
          return con.getMetaData();
      }
  
      @Override
      public void setReadOnly(boolean readOnly) throws SQLException {
          con.setReadOnly(readOnly);
      }
  
      @Override
      public boolean isReadOnly() throws SQLException {
          return con.isReadOnly();
      }
  
      @Override
      public void setCatalog(String catalog) throws SQLException {
          con.setCatalog(catalog);
      }
  
      @Override
      public String getCatalog() throws SQLException {
          return con.getCatalog();
      }
  
      @Override
      public void setTransactionIsolation(int level) throws SQLException {
          con.setTransactionIsolation(level);
      }
  
      @Override
      public int getTransactionIsolation() throws SQLException {
          return con.getTransactionIsolation();
      }
  
      @Override
      public SQLWarning getWarnings() throws SQLException {
          return con.getWarnings();
      }
  
      @Override
      public void clearWarnings() throws SQLException {
          con.clearWarnings();
      }
  
      @Override
      public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
          return con.createStatement(resultSetType,resultSetConcurrency);
      }
  
      @Override
      public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
          return con.prepareStatement(sql,resultSetType,resultSetConcurrency);
      }
  
      @Override
      public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
          return con.prepareCall(sql,resultSetType,resultSetConcurrency);
      }
  
      @Override
      public Map<String, Class<?>> getTypeMap() throws SQLException {
          return con.getTypeMap();
      }
  
      @Override
      public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
          con.setTypeMap(map);
      }
  
      @Override
      public void setHoldability(int holdability) throws SQLException {
          con.setHoldability(holdability);
      }
  
      @Override
      public int getHoldability() throws SQLException {
          return con.getHoldability();
      }
  
      @Override
      public Savepoint setSavepoint() throws SQLException {
          return con.setSavepoint();
      }
  
      @Override
      public Savepoint setSavepoint(String name) throws SQLException {
          return con.setSavepoint(name);
      }
  
      @Override
      public void rollback(Savepoint savepoint) throws SQLException {
          con.rollback(savepoint);
      }
  
      @Override
      public void releaseSavepoint(Savepoint savepoint) throws SQLException {
          con.releaseSavepoint(savepoint);
      }
  
      @Override
      public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
          return con.createStatement(resultSetType,resultSetConcurrency,resultSetHoldability);
      }
  
      @Override
      public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
          return con.prepareStatement(sql,resultSetType,resultSetConcurrency,resultSetHoldability);
      }
  
      @Override
      public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
          return con.prepareCall(sql,resultSetType,resultSetConcurrency,resultSetHoldability);
      }
  
      @Override
      public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
          return con.prepareStatement(sql,autoGeneratedKeys);
      }
  
      @Override
      public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
          return con.prepareStatement(sql,columnIndexes);
      }
  
      @Override
      public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
          return con.prepareStatement(sql,columnNames);
      }
  
      @Override
      public Clob createClob() throws SQLException {
          return con.createClob();
      }
  
      @Override
      public Blob createBlob() throws SQLException {
          return con.createBlob();
      }
  
      @Override
      public NClob createNClob() throws SQLException {
          return con.createNClob();
      }
  
      @Override
      public SQLXML createSQLXML() throws SQLException {
          return con.createSQLXML();
      }
  
      @Override
      public boolean isValid(int timeout) throws SQLException {
          return con.isValid(timeout);
      }
  
      @Override
      public void setClientInfo(String name, String value) throws SQLClientInfoException {
          con.setClientInfo(name,value);
      }
  
      @Override
      public void setClientInfo(Properties properties) throws SQLClientInfoException {
          con.setClientInfo(properties);
      }
  
      @Override
      public String getClientInfo(String name) throws SQLException {
          return con.getClientInfo(name);
      }
  
      @Override
      public Properties getClientInfo() throws SQLException {
          return con.getClientInfo();
      }
  
      @Override
      public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
          return con.createArrayOf(typeName,elements);
      }
  
      @Override
      public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
          return con.createStruct(typeName,attributes);
      }
  
      @Override
      public void setSchema(String schema) throws SQLException {
          con.setSchema(schema);
      }
  
      @Override
      public String getSchema() throws SQLException {
          return con.getSchema();
      }
  
      @Override
      public void abort(Executor executor) throws SQLException {
          con.abort(executor);
      }
  
      @Override
      public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {
          con.setNetworkTimeout(executor,milliseconds);
      }
  
      @Override
      public int getNetworkTimeout() throws SQLException {
          return con.getNetworkTimeout();
      }
  
      @Override
      public <T> T unwrap(Class<T> iface) throws SQLException {
          return con.unwrap(iface);
      }
  
      @Override
      public boolean isWrapperFor(Class<?> iface) throws SQLException {
          return con.isWrapperFor(iface);
      }
  }

自定义连接池类

public class MyDataSource implements DataSource{
      //定义集合容器,用于保存多个数据库连接对象
      private static List<Connection> pool = Collections.synchronizedList(new ArrayList<Connection>());
  
      //静态代码块,生成10个数据库连接保存到集合中
      static {
          for (int i = 0; i < 10; i++) {
              Connection con = JDBCUtils.getConnection();
              pool.add(con);
          }
      }
  
      //返回连接池的大小
      public int getSize() {
          return pool.size();
      }
  
      //从池中返回一个数据库连接
      @Override
      public Connection getConnection() {
          if(pool.size() > 0) {
              //从池中获取数据库连接
              Connection con = pool.remove(0);
              //通过自定义连接对象进行包装
              MyConnection2 mycon = new MyConnection2(con,pool);
              //返回包装后的连接对象
              return mycon;
          }else {
              throw new RuntimeException("连接数量已用尽");
          }
      }
  }

缺点: Connection 接口中要实现的方法太多了,代码繁杂

适配器设计模式改进连接池

提供一个适配器类,实现 Connection 接口,将所有功能进行实现(除了 close()方法),作为中间类。自定义连接类只需要继承这个适配器类,重写需要改进的 close() 方法即可!

适配器类不需要实现 close() 方法,所以定义为抽象类

public abstract class MyAdapter implements Connection {
  
      // 定义数据库连接对象的变量
      private Connection con;
  
      // 通过构造方法赋值
      public MyAdapter(Connection con) {
          this.con = con;
      }
  
      // 所有的方法,均调用mysql的连接对象实现
      @Override
      public Statement createStatement() throws SQLException {
          return con.createStatement();
      }
  
      @Override
      public PreparedStatement prepareStatement(String sql) throws SQLException {
          return con.prepareStatement(sql);
      }
  
      @Override
      public CallableStatement prepareCall(String sql) throws SQLException {
          return con.prepareCall(sql);
      }
  
      @Override
      public String nativeSQL(String sql) throws SQLException {
          return con.nativeSQL(sql);
      }
  
      @Override
      public void setAutoCommit(boolean autoCommit) throws SQLException {
          con.setAutoCommit(autoCommit);
      }
  
      @Override
      public boolean getAutoCommit() throws SQLException {
          return con.getAutoCommit();
      }
  
      @Override
      public void commit() throws SQLException {
          con.commit();
      }
  
      @Override
      public void rollback() throws SQLException {
          con.rollback();
      }
  
      @Override
      public boolean isClosed() throws SQLException {
          return con.isClosed();
      }
  
      @Override
      public DatabaseMetaData getMetaData() throws SQLException {
          return con.getMetaData();
      }
  
      @Override
      public void setReadOnly(boolean readOnly) throws SQLException {
          con.setReadOnly(readOnly);
      }
  
      @Override
      public boolean isReadOnly() throws SQLException {
          return con.isReadOnly();
      }
  
      @Override
      public void setCatalog(String catalog) throws SQLException {
          con.setCatalog(catalog);
      }
  
      @Override
      public String getCatalog() throws SQLException {
          return con.getCatalog();
      }
  
      @Override
      public void setTransactionIsolation(int level) throws SQLException {
          con.setTransactionIsolation(level);
      }
  
      @Override
      public int getTransactionIsolation() throws SQLException {
          return con.getTransactionIsolation();
      }
  
      @Override
      public SQLWarning getWarnings() throws SQLException {
          return con.getWarnings();
      }
  
      @Override
      public void clearWarnings() throws SQLException {
          con.clearWarnings();
      }
  
      @Override
      public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
          return con.createStatement(resultSetType,resultSetConcurrency);
      }
  
      @Override
      public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
          return con.prepareStatement(sql,resultSetType,resultSetConcurrency);
      }
  
      @Override
      public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
          return con.prepareCall(sql,resultSetType,resultSetConcurrency);
      }
  
      @Override
      public Map<String, Class<?>> getTypeMap() throws SQLException {
          return con.getTypeMap();
      }
  
      @Override
      public void setTypeMap(Map<String, Class<?>> map) throws SQLException {
          con.setTypeMap(map);
      }
  
      @Override
      public void setHoldability(int holdability) throws SQLException {
          con.setHoldability(holdability);
      }
  
      @Override
      public int getHoldability() throws SQLException {
          return con.getHoldability();
      }
  
      @Override
      public Savepoint setSavepoint() throws SQLException {
          return con.setSavepoint();
      }
  
      @Override
      public Savepoint setSavepoint(String name) throws SQLException {
          return con.setSavepoint(name);
      }
  
      @Override
      public void rollback(Savepoint savepoint) throws SQLException {
          con.rollback(savepoint);
      }
  
      @Override
      public void releaseSavepoint(Savepoint savepoint) throws SQLException {
          con.releaseSavepoint(savepoint);
      }
  
      @Override
      public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
          return con.createStatement(resultSetType,resultSetConcurrency,resultSetHoldability);
      }
  
      @Override
      public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
          return con.prepareStatement(sql,resultSetType,resultSetConcurrency,resultSetHoldability);
      }
  
      @Override
      public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
          return con.prepareCall(sql,resultSetType,resultSetConcurrency,resultSetHoldability);
      }
  
      @Override
      public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
          return con.prepareStatement(sql,autoGeneratedKeys);
      }
  
      @Override
      public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
          return con.prepareStatement(sql,columnIndexes);
      }
  
      @Override
      public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
          return con.prepareStatement(sql,columnNames);
      }
  
      @Override
      public Clob createClob() throws SQLException {
          return con.createClob();
      }
  
      @Override
      public Blob createBlob() throws SQLException {
          return con.createBlob();
      }
  
      @Override
      public NClob createNClob() throws SQLException {
          return con.createNClob();
      }
  
      @Override
      public SQLXML createSQLXML() throws SQLException {
          return con.createSQLXML();
      }
  
      @Override
      public boolean isValid(int timeout) throws SQLException {
          return con.isValid(timeout);
      }
  
      @Override
      public void setClientInfo(String name, String value) throws SQLClientInfoException {
          con.setClientInfo(name,value);
      }
  
      @Override
      public void setClientInfo(Properties properties) throws SQLClientInfoException {
          con.setClientInfo(properties);
      }
  
      @Override
      public String getClientInfo(String name) throws SQLException {
          return con.getClientInfo(name);
      }
  
      @Override
      public Properties getClientInfo() throws SQLException {
          return con.getClientInfo();
      }
  
      @Override
      public Array createArrayOf(String typeName, Object[] elements) throws SQLException {
          return con.createArrayOf(typeName,elements);
      }
  
      @Override
      public Struct createStruct(String typeName, Object[] attributes) throws SQLException {
          return con.createStruct(typeName,attributes);
      }
  
      @Override
      public void setSchema(String schema) throws SQLException {
          con.setSchema(schema);
      }
  
      @Override
      public String getSchema() throws SQLException {
          return con.getSchema();
      }
  
      @Override
      public void abort(Executor executor) throws SQLException {
          con.abort(executor);
      }
  
      @Override
      public void setNetworkTimeout(Executor executor, int milliseconds) throws SQLException {
          con.setNetworkTimeout(executor,milliseconds);
      }
  
      @Override
      public int getNetworkTimeout() throws SQLException {
          return con.getNetworkTimeout();
      }
  
      @Override
      public <T> T unwrap(Class<T> iface) throws SQLException {
          return con.unwrap(iface);
      }
  
      @Override
      public boolean isWrapperFor(Class<?> iface) throws SQLException {
          return con.isWrapperFor(iface);
      }
  }

自定义连接类

通过适配器设计模式。完成close()方法的重写

  • 定义一个类,继承适配器父类
  • 定义 Connection 连接对象和连接池容器对象的变量
  • 提供有参构造方法,接收连接对象和连接池对象,对变量赋值
  • 在 close() 方法中,完成连接的归还
public class MyConnection3 extends MyAdapter {
      //2.定义Connection连接对象和连接池容器对象的变量
      private Connection con;
      private List<Connection> pool;
  
      //3.提供有参构造方法,接收连接对象和连接池对象,对变量赋值
      public MyConnection3(Connection con,List<Connection> pool) {
          super(con);    // 将接收的数据库连接对象给适配器父类传递
          this.con = con;
          this.pool = pool;
      }
  
      //4.在close()方法中,完成连接的归还
      @Override
      public void close() throws SQLException {
          pool.add(con);
      }
  }

自定义连接池类

public class MyDataSource implements DataSource{
      //定义集合容器,用于保存多个数据库连接对象
      private static List<Connection> pool = Collections.synchronizedList(new ArrayList<Connection>());
  
      //静态代码块,生成10个数据库连接保存到集合中
      static {
          for (int i = 0; i < 10; i++) {
              Connection con = JDBCUtils.getConnection();
              pool.add(con);
          }
      }
  
      //返回连接池的大小
      public int getSize() {
          return pool.size();
      }
  
      //从池中返回一个数据库连接
      @Override
      public Connection getConnection() {
          if(pool.size() > 0) {
              //从池中获取数据库连接
              Connection con = pool.remove(0);
  
              //通过自定义连接对象进行包装
              MyConnection3 mycon = new MyConnection3(con,pool);
  
              //返回包装后的连接对象
              return mycon;
          }else {
              throw new RuntimeException("连接数量已用尽");
          }
      }
  }

缺点:自定义连接类中的方法已经很简洁了。剩余所有的方法已经抽取到了适配器类中。但是适配器这个类还是我们自己编写的,也比较麻烦!所以可以使用动态代理的方式来改进。

动态代理

public class MyDataSource implements DataSource{
      //定义集合容器,用于保存多个数据库连接对象
      private static List<Connection> pool = Collections.synchronizedList(new ArrayList<Connection>());
  
      //静态代码块,生成10个数据库连接保存到集合中
      static {
          for (int i = 0; i < 10; i++) {
              Connection con = JDBCUtils.getConnection();
              pool.add(con);
          }
      }
  
      //返回连接池的大小
      public int getSize() {
          return pool.size();
      }
  
      //动态代理方式
      @Override
      public Connection getConnection() {
          if(pool.size() > 0) {
              //从池中获取数据库连接
              Connection con = pool.remove(0);
  
              Connection proxyCon = (Connection)Proxy.newProxyInstance(con.getClass().getClassLoader(), new Class[]{Connection.class}, new InvocationHandler() {
                  /*
                      执行Connection实现类所有方法都会经过invoke
                      如果是close方法,则将连接还回池中
                      如果不是,直接执行实现类的原有方法
                   */
                  @Override
                  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                      if(method.getName().equals("close")) {
                          pool.add(con);
                          return null;
                      }else {
                          return method.invoke(con,args);
                      }
                  }
              });
  
              return proxyCon;
          }else {
              throw new RuntimeException("连接数量已用尽");
          }
      }
  
  
      //从池中返回一个数据库连接
      /*@Override
      public Connection getConnection() {
          if(pool.size() > 0) {
              //从池中获取数据库连接
              Connection con = pool.remove(0);
  
              //通过自定义连接对象进行包装
              //MyConnection2 mycon = new MyConnection2(con,pool);
              MyConnection3 mycon = new MyConnection3(con,pool);
  
              //返回包装后的连接对象
              return mycon;
          }else {
              throw new RuntimeException("连接数量已用尽");
          }
      }*/
  }

开源连接池的使用

C3P0连接池

  • 导入jar包
  • 导入配置文件到src目录下
  • 创建c3p0连接池对象
  • 获取数据库连接进行使用

配置文件 c3p0-config.xml 注意该配置文件的名字是固定的不要改,否则无法识别

  • initialPoolSize :初始化连接数量
  • maxPoolSize :最大连接数量,当连接数量超过初始化连接数量时,会在连接池内继续创建连接,直到达到数据库连接池所能容纳的最大连接数量
  • checkoutTimeout :超过时间。如果使用的连接数量超过最大连接数量,编译器会在 checkoutTimeout 时间以后报错并终止程序。
<c3p0-config>
  <!-- 使用默认的配置读取连接池对象 -->
  <default-config>
  	<!--  连接参数 -->
    <property name="driverClass">com.mysql.jdbc.Driver</property>
    <property name="jdbcUrl">jdbc:mysql://主机名:3306/数据库名</property>
    <property name="user">用户名</property>
    <property name="password">密码</property>
    
    <!-- 连接池参数 -->
    <!-- 初始化连接数量 -->
    <property name="initialPoolSize">5</property>
    <!--  最大连接数量  -->
    <property name="maxPoolSize">10</property>
    <!--  超时时间  -->
    <property name="checkoutTimeout">3000</property>
  </default-config>


  <!--  创建数据库连接池时指定名称-->
  <named-config name="otherc3p0"> 
    <!--  连接参数 -->
    <property name="driverClass">com.mysql.jdbc.Driver</property>
    <property name="jdbcUrl">jdbc:mysql://主机名:3306/数据库名</property>
    <property name="user">用户名</property>
    <property name="password">密码</property>
    
    <!-- 连接池参数 -->
    <property name="initialPoolSize">5</property>
    <property name="maxPoolSize">8</property>
    <property name="checkoutTimeout">1000</property>
  </named-config>
</c3p0-config>

C3P0数据库连接池的使用

public static void main(String[] args) throws SQLException {
        //创建c3p0连接池对象
        DataSource dataSource = new ComboPooledDataSource();
        //获取数据库连接进行使用
        Connection con = dataSource.getConnection();
        String s = "select *from emp";
        PreparedStatement pst = con.prepareStatement(s);
        ResultSet rs = pst.executeQuery();
        while (rs.next()) {
            String ename = rs.getString("ename");
            String job = rs.getString("job");
            String hiredate = rs.getString("hiredate");
            System.out.println("ename:" + ename + " job:" + job + " hiredate:" + hiredate);
        }
        rs.close();
        pst.close();
        con.close(); // 将连接对象归还池中
    }

Druid连接池

  • 导入jar包
  • 编写配置文件,放在src目录下
  • 通过Properties集合加载配置文件
  • 通过Druid连接池工厂类获取数据库连接池对象
  • 获取数据库连接,进行使用

配置文件 druid.properties

driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://主机名:3306/数据库名
username:用户名
password:密码
# 初始连接数量
initialSize=5
# 最大连接数量
maxActive=10
# 最长等待时间
maxWait=3000

Druid数据库的使用

public static void main(String[] args) throws Exception {
        //通过Properties集合加载配置文件
        InputStream is = demo01.class.getClassLoader().getResourceAsStream("druid.properties");
        Properties prop = new Properties();
        prop.load(is);
        //通过Druid连接池工厂类获取数据库连接池对象
        DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
        //获取数据库连接,进行使用
        Connection con = dataSource.getConnection();
        PreparedStatement pst = con.prepareStatement("select *from emp");
        ResultSet rs = pst.executeQuery();
        while (rs.next()) {
            String ename = rs.getString("ename");
            String job = rs.getString("job");
            String hiredate = rs.getString("hiredate");
            System.out.println("ename:" + ename + " job:" + job + " hiredate:" + hiredate);
        }
        rs.close();
        pst.close();
        con.close();
    }

抽取工具类

/*
      数据库连接池工具类
   */
  public class DataSourceUtils {
      //1.私有构造方法
      private DataSourceUtils(){}
  
      //2.定义DataSource数据源变量
      private static DataSource dataSource;
  
      //3.提供静态代码块,完成配置文件的加载和获取连接池对象
      static {
          try{
              //加载配置文件
              InputStream is = DruidDemo1.class.getClassLoader().getResourceAsStream("druid.properties");
              Properties prop = new Properties();
              prop.load(is);
  
              //获取数据库连接池对象
              dataSource = DruidDataSourceFactory.createDataSource(prop);
  
          } catch(Exception e) {
              e.printStackTrace();
          }
      }
  
      //4.提供获取数据库连接的方法
      public static Connection getConnection() {
          Connection con = null;
          try {
              con = dataSource.getConnection();
          } catch (SQLException e) {
              e.printStackTrace();
          }
          return con;
      }
  
      //5.提供获取数据库连接池的方法
      public static DataSource getDataSource() {
          return dataSource;
      }
  
      //6.提供释放资源的方法
      public static void close(Connection con, Statement stat, ResultSet rs) {
          if(con != null) {
              try {
                  con.close();
              } catch (SQLException e) {
                  e.printStackTrace();
              }
          }
  
          if(stat != null) {
              try {
                  stat.close();
              } catch (SQLException e) {
                  e.printStackTrace();
              }
          }
  
          if(rs != null) {
              try {
                  rs.close();
              } catch (SQLException e) {
                  e.printStackTrace();
              }
          }
      }
  
      public static void close(Connection con, Statement stat) {
          close(con,stat,null);
      }
  
  }

工具类的使用

public static void main(String[] args) throws SQLException {
        //利用工具类获取DataSoure
        DataSource dataSource = DataSourceUtils.getDataSource();
        //获取连接,并使用
        Connection con = dataSource.getConnection();
        String s = "select *from emp";
        PreparedStatement pst = con.prepareStatement(s);
        ResultSet rs = pst.executeQuery();
        while (rs.next()) {
            String ename = rs.getString("ename");
            String job = rs.getString("job");
            String hiredate = rs.getString("hiredate");
            System.out.println("ename:" + ename + " job:" + job + " hiredate:" + hiredate);
        }
        DataSourceUtils.close(con, pst, rs);
    }
MySQL数据库连接池 第一节:数据库连接池 1.为什么使用数据库连接池 回顾:jdbc步骤: 1.加载驱动 2.创建连接 3.sql预编译 (Statement/PreparedStatement ?) 4.执行sql(DQL:executeQuery(), DML:executeUpdate()) 5.关闭连接 在之前,我们每一次操作数据库,都需要走创建连接,并且用过就关闭。考虑一波并发。假如现在同时有10000个 人访问数据库。mysql扛不住,内存扛不住。 如何解决?使用数据库连接池 问题: 1.假如现在有10000人同时 阅读详情

相关推荐

JDBC: C3P0数据库连接池连接MySQL数据库

JDBC: C3P0数据库连接池连接MySQL数据库 数据库连接池介绍 数据库连接池负责分配、管理和释放数据库连接,它相当于一个容器(集合),存放数据库连接。当系统初始化好后,容器被创建,容器中会申请一些连接对象,当用户来访问数据库时,从容器中获取连接对象,用户访问完之后,会将连接对象归还给容器。它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;释放空闲时间超过最大空闲时间的数...

CharmJay的博客 2319

MYSQL数据库连接池及常见参数调优

(1)查询缓存(query_cache_size):MySQL 可以将查询的结果缓存起来,下次相同的查询就可以直接从缓存中获取,一般设置为物理内存的 10%。(1)缓冲池大小(innodb_buffer_pool_size):InnoDB 存储引擎缓存的数据和索引的大小,一般设置为物理内存的 60%-80%。(4)查询缓存大小(query_cache_size):MySQL 可以将查询的结果缓存起来,下次相同的查询就可以直接从缓存中获取。(2)错误日志(log_error):记录数据库错误日志。

lonely_baby的博客 1万+

​​​​​​​​​​​​​​Spring Boot数据库连接池

在MySQL数据库中,一个连接的最大存活时间通常是由wait_timeout参数来控制的。这个参数定义了非交互式连接可以保持空闲的最长时间,超过这个时间后,连接将被自动关闭。你可以通过修改MySQL的配置文件(通常是my.cnf或my.ini),在[mysqld]部分设置wait_timeout的值来更改最大连接存活时间。另外,还有一个interactive_timeout参数,它定义了交互式连接(如通过MySQL客户端进行的连接)可以保持空闲的最长时间。的意思是光,“光”的意思是“…

qq_48501521的博客 1409

JDBC-05-笔记

数据库连接池 1. 数据库连接池的概念 2. 自定义连接池 3. 自定义连接池测试 4. 归还连接 继承(无法解决) 装饰设计模式 适配器设计模式 动态代理 5. 开源连接池的使用

qq_24410589的博客 346

MySQL 连接池的配置和使用

通过对这些配置项的合理设置,可以根据应用程序的需求和数据库服务器的配置来优化连接池的性能和可伸缩性。在实际应用中,根据具体情况进行调整,并进行性能测试和监控,以确保连接池的有效运行。连接池是在数据库应用程序中常见的一个重要组件,它可以管理和维护与数据库的连接,提高应用程序的性能和可伸缩性。在本文中,我们将详细介绍如何配置和使用MySQL连接池。连接池的配置通常涉及以下几个方面:连接池大小、最大空闲时间、连接超时、验证查询和连接属性。下面我们将逐一介绍这些配置项,并提供相应的示例代码。如有疑问,请随时提问。

DfsnVue的博客 769

MySQL连接池数量的合理配置

这样可以提高应用程序的性能和可伸缩性,同时减少数据库连接的创建和销毁开销。连接池是一种管理数据库连接的技术,它可以提高数据库应用程序的性能和可伸缩性。应用程序类型:不同类型的应用程序对数据库连接的需求是不同的。因此,连接池的大小应该根据应用程序的需求来配置。这样可以减少数据库连接的创建和销毁开销,提高应用程序的响应速度和性能。如果并发访问量很高,那么连接池的大小应该设置得足够大,以便同时处理更多的连接请求。如果数据库服务器的硬件资源有限,那么连接池的大小应该适当调整,以避免资源瓶颈。

MbfrDeveloper的博客 597

剖析 MySQL 数据库连接池(C++版)

上次给大家介绍了线程池的实现,这次来介绍下 Linux 下数据库连接池的实现,以大家最为熟悉的MySQL为例,因为连接池总体实现还是较为复杂的,本次以一个开源框架的数据库连接池部分为例进行讲解。首先,服务器与数据库的交互是请求响应模式,通常所使用的是TCP 长连接,而 TCP 连接需要三次握手和四次挥手,并且每次连接都需要验证账号密码等,所以连接资源属于耗时资源,可以用连接池来复用连接。

新人博主,多多关照 2215

第1部分 基础算法(提高篇)--第2章 二分与三分1439:【SCOI2010】传送带

1439:【SCOI2010】传送带 时间限制: 2000 ms 内存限制: 65536 KB 提交数: 372 通过数: 212 【题目描述】 在一个2维平面上有两条传送带,每一条传送带可以看成是一条线段。两条传送带分别为线段AB和线段CD。lxhgww在AB上的移动速度为P,在CD上的移动速度为Q,在平面上的移动速度R。现在lxhgww想从A点走到D点,他想知道最少需要走多长时间。 【输入】 输入数据第一行是4个整数,表示A和B的坐标,分别为Ax,Ay,Bx,By 第二行是4个整

zqhf123的博客 839

【MySQL】自定义数据库连接池和开源数据库连接池的使用

数据库连接池的概念 数据库连接背景 数据库连接是一种关键的、有限的、昂贵的资源,这一点在多用户的网页应用程序中体现得尤为突出。对数据库连接的管理能显著影响到整个应用程序的伸缩性和健壮性,影响到程序的性能指标。数据库连接池正是针对这个问题提出来的。 数据库连接池 数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个。这项技术能明显...

罗翔 167

RADIOML 2018.01A数据集在自动调制识别中的实战应用指南

本文提供了RADIOML 2018.01A数据集在自动调制识别(AMR)任务中的完整实战指南。内容涵盖从数据集介绍、数据获取与解包、高效预处理流程,到构建PyTorch数据管道、模型设计(如1D CNN、ResNet)以及训练调参策略。重点阐述了如何利用该数据集训练鲁棒的AI模型,以应对复杂信道环境和低信噪比挑战,并给出了详细的性能评估方法。

plant的博客 174

BCM-BCP-DRP-运维管理之故障管理——故障的分类与处理流程

ITSM Business Continuity Manage(BCM) BusinessContinuityPlan(BCP) 偏业务 DisasterRecoveryPlan(DRP) 偏IT 天塌了,考虑在天塌了的状态下做什么,怎么开展业务就是BCP; 天塌了,考虑怎么把天撑回去,就是DRP。 DRP+BCP+供应链管理+危机管理等就是BCM (业务连续性管...

mmgithub123的博客 2725

MySQL——开源数据库连接池DBCP和C3P0的使用

数据库——数据库连接池 数据库连接是一种关键的、有限的、昂贵的资源 对数据库连接的管理能显著影响到整个应用程序(特别是多用户的网页应用程序)的伸缩性和健壮性,影响到程序的性能指标。 数据库连接—>执行完毕—>释放 这个过程很浪费系统资源 因此需要数据库连接池负责分配、管理和释放数据库连接(数据库连接池的功能) 编写连接池只用实现一个接口 DateSource 影响数据库连接池的因素: 最小连接数: 是连接池一直保持的数据库连接,所以如果应用程序对数据库连接的使用量不大,将会有大量的数据库

万里顾一程的博客 675

基于LLaMA-action模型的文档摘要任务微调

文档摘要是指从长文档中提取关键信息,生成简短而准确的总结。抽取式摘要:从原文中直接抽取关键句子或短语组成摘要。生成式摘要:通过生成新的句子来表达原文的核心内容。混合式摘要:结合抽取式和生成式方法,既保留原文的关键句子,又生成新的内容。新闻网站:自动生成新闻摘要,帮助用户快速了解新闻要点。社交媒体:为用户提供新闻摘要,便于分享和传播。学术搜索引擎:为用户提供学术文献的摘要,帮助用户快速筛选相关文献。学术写作辅助:帮助研究人员快速生成文献综述部分。企业内部文档管理:自动生成文档摘要,便于员工快速了解文档内容。

加入“Super Entity”,与全能开发团队共探AI智能体与数字人项目,开启前沿技术之旅。 1432

使用 数据库连接池技术 直接连接 MySQL数据库

JDBC的学习,可以参考博主之前的博客: 使用JDBC连接MySQL数据库 JDBC实现表数据:增、删、改、查 目录 1、JDBC数据库连接池的必要性 2、数据库连接池技术 3、常见的开源数据库连接池 4、Druid(德鲁伊)数据库连接池下载 5、Druid(德鲁伊)连接MySQL数据库 1、JDBC数据库连接池的必要性 普通的JDBC数据库连接使用 DriverManager 来获取,每次向数据库建立连接的时候都要将 Connection 加载到内存中,再验证用户名和密...

行行失故路 1039

Android Framework AMS面试题及参考答案

比如,应用 B 的 Activity 如果是 “singleTask” 启动模式,AMS 会查找应用 B 是否有包含该 Activity 的任务栈,若有则将这个任务栈切换到前台,并且清除该 Activity 之上的其他 Activity,实现流畅的跨应用跳转体验。如果一个 Activity 的启动依赖于另一个 Activity 的结果,AMS 会暂停当前 Activity 的部分生命周期操作,等待依赖的 Activity 完成相关操作后,再继续当前 Activity 的生命周期进程。

大模型大数据攻城狮的专栏 1863

NX二次开发 计算多个体的最小包围盒

多个体的最小包围盒

weixin_72680115的博客 430

推荐一款高效稳定的Django数据库连接池管理库:django-db-connection-pool

推荐一款高效稳定的Django数据库连接池管理库:django-db-connection-pool django-db-connection-poolDatabase connection pool component library for Django项目地址:https://gitcode.com/gh_mirrors/dj/django-db-connection-pool 在开发复杂...

gitblog_00058的博客 1208

【DeepSeek R1构建本地RAG知识库】数据结构化清洗-知识图谱制作、使用、dify集成

本文探讨了在构建本地RAG(Retrieval-Augmented Generation)系统时,如何通过引入知识图谱来增强系统的知识理解能力。传统的向量数据库和嵌入模型虽然能处理语义匹配,但无法有效捕捉知识间的关联性。知识图谱通过“实体-关系-属性”的结构化表示,能够更好地支持推理、推荐和多跳问答等高级功能。文章详细介绍了知识图谱的基本概念、制作思路,以及如何使用Neo4j图数据库进行知识图谱的构建和查询。通过实例展示了从PDF文件解析到知识图谱入库的全过程,强调了知识图谱在提升RAG系统性能中的重要作用

少说,多做 568

c mysql 开源连接池_开源数据库连接池的使用

上篇博客刚刚说完如何去自定义一个数据库连接池,当然,这个自定义的数据库连接池是十分简易的,凭借自己的能力也无法写出优秀的连接池。但是,不用担心,我们可以使用开源的数据库连接池,开源的优势体现于此。在Java中有三种开源数据库连接池提供了数据源的独立实现:DBCP 数据库连接池C3P0 数据库连接池Apache Tomcat内置的连接池(apache dbcp)1、DBCP数据库连接池DBCP是Ap...

weixin_33694136的博客 283

一张图读懂 SAP S/4HANA Cloud 与 SAP BTP 的扩展版图

本文解析了SAP S/4HANA Cloud的扩展技术谱系,提出扩展应分为on-stack(系统内)和side-by-side(并行)两种路径,并沿着低代码到专业代码的能力梯度进行分层。on-stack扩展包括面向业务人员的Key User Extensibility和面向开发者的Developer Extensibility,强调贴近核心业务对象;side-by-side扩展则依托SAP BTP平台,提供SAP Build低代码工具、CAP开发框架和ABAP云环境三种方案,支持解耦创新。文章通过五个真实案

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 255

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

自定义数据库连接池

一、基本步骤 1.创建集合存储即将要创建的数据库连接池       数据库连接需要经常增删,而链表的增删速度比较快,在这里我们使用LinkedList 2.创建配置文件存储即将用到的数据库驱动地址,数据库地址,用户名和密码       配置文件我们采用config.properties 3.为提高速度在静态代码块中创建多个数据库连接并将该链接存储到集合中   

cs.Ing 2077

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

mysql连接池使用场景_数据库连接池的理解和使用

一、什么是数据库连接池?官方:数据库连接池(Connection pooling)是程序启动时建立足够的数据库连接,并将这些连接组成一个连接池,由程序动态地对池中的连接进行申请,使用,释放。个人理解:创建数据库连接是一个很耗时的操作,也容易对数据库造成安全隐患。所以,在程序初始化的时候,集中创建多个数据库连接,并把他们集中管理,供程序使用,可以保证较快的数据库读写速度,还更加安全可靠。简而言之,数...

weixin_34637857的博客 963

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

上一篇: 淘宝直播全屏页重排算法实践
下一篇: 记一次十亿级时延敏感集群+索引引起的业务抖动及快速恢复方法
JavaMonsterr
博客等级 码龄4年 211粉丝 481原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值