需要代码在java中创建连接池

moh*_*han 31 java connection connection-pooling

需要代码在java中创建连接池吗?我们如何确保连接池不返回已在使用的同一对象?如果客户端从连接池中取出连接后关闭连接会怎么样?

更新1:

我想用简单的Java术语创建它,并希望看到它在多线程环境中如何工作.我的意思是哪些方法将同步,哪些方法不同步.这门课还会成为公共课吗?如果是,则任何人都可以访问此类并重新初始化连接池?

更新2:

我有一些代码如下.但我不知道如何"关闭来自池的连接将其返回到池中,它不会在物理上关闭连接." 此外,我没有理解这一点"因为如果连接已从池中借用而尚未返回,则它不是"可用"且无法重新分配给池中的另一个客户端.

import java.util.*;
import java.sql.*;

class ConnectionPoolManager
{

 String databaseUrl = "jdbc:mysql://localhost:3306/myDatabase";
 String userName = "userName";
 String password = "userPass";

 Vector connectionPool = new Vector();

 public ConnectionPoolManager()
 {
  initialize();
 }

 public ConnectionPoolManager(
  //String databaseName,
  String databaseUrl,
  String userName,
  String password
  )
 {
  this.databaseUrl = databaseUrl;
  this.userName = userName;
  this.password = password;
  initialize();
 }

 private void initialize()
 {
  //Here we can initialize all the information that we need
  initializeConnectionPool();
 }

 private void initializeConnectionPool()
 {
  while(!checkIfConnectionPoolIsFull())
  {
   System.out.println("Connection Pool is NOT full. Proceeding with adding new connections");
   //Adding new connection instance until the pool is full
   connectionPool.addElement(createNewConnectionForPool());
  }
  System.out.println("Connection Pool is full.");
 }

 private synchronized boolean checkIfConnectionPoolIsFull()
 {
  final int MAX_POOL_SIZE = 5;

  //Check if the pool size
  if(connectionPool.size() < 5)
  {
   return false;
  }

  return true;
 }

 //Creating a connection
 private Connection createNewConnectionForPool()
 {
  Connection connection = null;

  try
  {
   Class.forName("com.mysql.jdbc.Driver");
   connection = DriverManager.getConnection(databaseUrl, userName, password);
   System.out.println("Connection: "+connection);
  }
  catch(SQLException sqle)
  {
   System.err.println("SQLException: "+sqle);
   return null;
  }
  catch(ClassNotFoundException cnfe)
  {
   System.err.println("ClassNotFoundException: "+cnfe);
   return null;
  }

  return connection;
 }

 public synchronized Connection getConnectionFromPool()
 {
  Connection connection = null;

  //Check if there is a connection available. There are times when all the connections in the pool may be used up
  if(connectionPool.size() > 0)
  {
   connection = (Connection) connectionPool.firstElement();
   connectionPool.removeElementAt(0);
  }
  //Giving away the connection from the connection pool
  return connection;
 }

 public synchronized void returnConnectionToPool(Connection connection)
 {
  //Adding the connection from the client back to the connection pool
  connectionPool.addElement(connection);
 }

 public static void main(String args[])
 {
  ConnectionPoolManager ConnectionPoolManager = new ConnectionPoolManager();
 }

}
Run Code Online (Sandbox Code Playgroud)

Pas*_*ent 46

需要代码在java中创建连接池吗?

不确定问题是什么,但不创建另一个连接池,使用现有的解决方案,如C3P0,Apache DBCP,ProxoolBoneCP(该领域的新玩家).我会用C3P0.

我们如何确保连接池不返回已在使用的同一对象?

因为如果从池中借用了连接但尚未返回,则它不在池中,也不能分配给池的另一个客户端(资源将从池中删除,直到它们被返回).

如果客户端从连接池中取出连接后关闭连接会怎么样?

客户端从池中获取的连接实际上不是java.sql.Connection,它是一个java.sql.Connection自定义某些方法行为的包装器(代理).该close()方法是其中之一,不会关闭Connection实例但会将其返回到池中.

  • "不会关闭Connection实例但会将其返回到池中" - 连接类如何知道池并且在调用close方法时能够将其自身返回给它? (3认同)
  • 请务必查看Hikari CP:https://github.com/brettwooldridge/HikariCP.从我所读到的,它似乎比列出的快得多. (3认同)
  • C3PO +1 ...我一直在使用它,效果非常好.它重量轻,非常容易使用. (2认同)

Rya*_*ins 14

不要自己写.有很多图书馆员会为你做这个开源且易于使用的图书馆员,并且会解决你自己想要做的所有问题.

这是一个使用Apache的Commons DBCP和Commons Pool的简单示例:

首先设置一个DataSource.

javax.sql.DataSource source = new org.apache.commons.dbcp.BasicDataSource();
source.setDriverClassName("com.mysql.jdbc.Driver");
source.setUsername("username");
source.setPassword("password");
source.setUrl("jdbc:mysql://localhost:3306/myDatabase");
Run Code Online (Sandbox Code Playgroud)

拥有DataSource后,可以轻松地从池中获取连接.

java.sql.Connection connection = source.getConnection();
Run Code Online (Sandbox Code Playgroud)

关闭连接会将它返回到池中.

connection.close();
Run Code Online (Sandbox Code Playgroud)

  • 但他不会通过尝试解决问题来学习. (3认同)
  • +1.但是,一个更正 - 方法`setDriverClassName()`和其他在`javax.sql.DataSource` [java 1.6]中不可用.类型应该是`BasicDataSource`.ie:`BasicDataSource source = new BasicDataSource();`有关详细信息,请访问:http://svn.apache.org/viewvc/commons/proper/dbcp/trunk/doc/BasicDataSourceExample.java?revision=1100136&view=markup (2认同)

Jag*_*esh 12

我希望这个源代码有助于 http://jagadeeshmanne.blogspot.in/2014/03/connection-pool-in-java-jdbc.html

Configuration.java

package com.jmanne.utils;

public class Configuration {

 public String DB_USER_NAME ;

 public String DB_PASSWORD ;

 public String DB_URL;

 public String DB_DRIVER;

 public Integer DB_MAX_CONNECTIONS;

 public Configuration(){
  init();
 }

 private static Configuration configuration = new Configuration();

 public static Configuration getInstance(){ 
  return configuration;
 }

 private void init(){
  DB_USER_NAME = "root"
  DB_PASSWORD = "root"
  DB_URL = "jdbc:mysql://localhost:3306/jmanne"
  DB_DRIVER = "com.mysql.jdbc.Driver"
  DB_MAX_CONNECTIONS = 5
 }     
}
Run Code Online (Sandbox Code Playgroud)

JdbcConnectionPool.java

package com.jmanne.db;

import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import com.jmanne.utils.Configuration;
import com.mysql.jdbc.Connection;

public class JdbcConnectionPool {

 List<connection> availableConnections = new ArrayList<connection>();

 public JdbcConnectionPool()
 {
  initializeConnectionPool();
 }

 private void initializeConnectionPool()
 {
  while(!checkIfConnectionPoolIsFull())
  {
   availableConnections.add(createNewConnectionForPool());
  }
 }

 private synchronized boolean checkIfConnectionPoolIsFull()
 {
  final int MAX_POOL_SIZE = Configuration.getInstance().DB_MAX_CONNECTIONS;

  if(availableConnections.size() < MAX_POOL_SIZE)
  {
   return false;
  }

  return true;
 }

 //Creating a connection
 private Connection createNewConnectionForPool()
 {
  Configuration config = Configuration.getInstance();
  try {
   Class.forName(config.DB_DRIVER);
   Connection connection = (Connection) DriverManager.getConnection(
     config.DB_URL, config.DB_USER_NAME, config.DB_PASSWORD);
   return connection;
  } catch (ClassNotFoundException e) {
   e.printStackTrace();
  } catch (SQLException e) {
   e.printStackTrace();
  }
  return null;

 }

 public synchronized Connection getConnectionFromPool()
 {
  Connection connection = null;
  if(availableConnections.size() > 0)
  {
   connection = (Connection) availableConnections.get(0);
   availableConnections.remove(0);
  }
  return connection;
 }

 public synchronized void returnConnectionToPool(Connection connection)
 {
  availableConnections.add(connection);
 }
}
Run Code Online (Sandbox Code Playgroud)

DataSource.java

package com.jmanne.db;

import java.sql.SQLException;

import com.mysql.jdbc.Connection;

public class DataSource {

 static JdbcConnectionPool pool = new JdbcConnectionPool();

 public static Connection getConnection() throws ClassNotFoundException, SQLException{
  Connection connection = pool.getConnectionFromPool();
  return connection;
 }

 public static void returnConnection(Connection connection) {
  pool.returnConnectionToPool(connection);
 }
}
Run Code Online (Sandbox Code Playgroud)

  • 抱歉耽搁了.db驱动程序意味着驱动程序类名 需要将该变量名称更改为driverClass.您可以在服务类中使用DataSource.getConnection().它将从池中返回连接对象 (2认同)

Pri*_*esh 6

只需使用信号量.理想情况下,您应该使用CP3ODBCP作为您的连接池.现在,您可以根据信号量限制连接.

每次你这样做Get,你获得并在每一个Release你从信号量释放它.更多信号量是线程安全的.


mha*_*ler 4

使用现有的之一,例如Apache DBCP

池返回的连接通常是“忽略”close()来自应用程序的调用的代理。当连接返回到池中时,它们可以被重用。如有必要,泳池还会自动关闭和重新开放。