Как установить пул соединений в JDBC?

Может ли кто-нибудь предоставить примеры или ссылки о том, как установить пул соединений JDBC?

Из поиска google я вижу много разных способов сделать это, и это довольно запутанно.

В конечном итоге мне нужен код, чтобы вернуть объект java.sql.Connection, но мне сложно начать работу. Любые предложения приветствуются.

Обновление: Не имеет ли javax.sql или java.sql объединение реализаций соединений? Почему бы не использовать их лучше?

Ответ 1

Если вам нужен автономный пул соединений, я предпочитаю C3P0 над DBCP (о чем я упомянул в предыдущем ответе ), у меня было слишком много проблем с DBCP при большой нагрузке. Использование C3P0 мертво просто. Из документа :

ComboPooledDataSource cpds = new ComboPooledDataSource();
cpds.setDriverClass( "org.postgresql.Driver" ); //loads the jdbc driver
cpds.setJdbcUrl( "jdbc:postgresql://localhost/testdb" );
cpds.setUser("swaldman");
cpds.setPassword("test-password");

// the settings below are optional -- c3p0 can work with defaults
cpds.setMinPoolSize(5);
cpds.setAcquireIncrement(5);
cpds.setMaxPoolSize(20);

// The DataSource cpds is now a fully configured and usable pooled DataSource 

Но если вы работаете на сервере приложений, я бы рекомендовал использовать встроенный пул соединений, который он предоставляет. В этом случае вам необходимо настроить его (см. Документацию на сервере приложений) и получить источник данных через JNDI:

DataSource ds = (DataSource) new InitialContext().lookup("jdbc/myDS");

Ответ 2

Обычно, если вам нужен пул соединений, вы пишете приложение, которое выполняется в некоторой управляемой среде, то есть вы работаете внутри сервера приложений. Если это так, убедитесь, что проверить, какие средства объединения пулов, которые сервер приложений предоставляет, перед тем, как попробовать какие-либо другие параметры.

Исключительное решение будет наилучшим образом интегрировано с остальными ресурсами серверов приложений. Если, однако, вы не работаете на сервере приложений, я бы рекомендовал Apache Commons DBCP Component. Он широко используется и обеспечивает всю базовую функциональность объединения, требуемую большинством приложений.

Ответ 3

Не изобретайте велосипед.

Попробуйте один из легко доступных сторонних компонентов:

  • Apache DBCP - Этот используется внутри Tomcat, и ваш действительно.
  • c3p0

Apache DBCP поставляется с другим примером того, как настроить объединение javax.sql.DataSource. Вот пример , который поможет вам начать работу.

Ответ 4

Я бы рекомендовал использовать библиотеку commons-dbcp. Есть многочисленные примеры, которые перечислены о том, как их использовать, вот ссылка на ход простой. Использование очень просто:

 BasicDataSource ds = new BasicDataSource();
 ds.setDriverClassName("oracle.jdbc.driver.OracleDriver")
 ds.setUsername("scott");
 ds.setPassword("tiger");
 ds.setUrl(connectURI);
 ...
 Connection conn = ds.getConnection();

Вам нужно только создать источник данных один раз, поэтому убедитесь, что вы прочитали документацию, если не знаете, как это сделать. Если вы не знаете, как правильно писать инструкции JDBC, чтобы не утечка ресурсов, вам также может понадобиться прочитать эту страницу Wikipedia.

Ответ 5

HikariCP

Это современный, быстрый, простой. Я использую его для каждого нового проекта. Я предпочитаю это много над C3P0, не знаю, что другие пулы слишком хорошо.

Ответ 6

На сервере приложений мы используем, где я работаю (Oracle Application Server 10g, как я помню), пул обрабатывается сервером приложений. Мы извлекаем javax.sql.DataSource с помощью поиска JNDI с javax.sql.InitialContext.

он сделал что-то вроде этого

try {     
   context = new InitialContext();
   jdbcURL = (DataSource) context.lookup("jdbc/CachedDS");
   System.out.println("Obtained Cached Data Source ");
}
catch(NamingException e)   
{  
    System.err.println("Error looking up Data Source from Factory: "+e.getMessage());
}

(Мы не пишем этот код, он скопировал из эту документацию.)

Ответ 7

Как утверждают другие, вы, вероятно, будете довольны Apache Dbcp или c3p0. Оба они популярны и работают нормально.

Относительно вашего сомнения

Не имеет ли javax.sql или java.sql объединенные реализации соединений? Зачем не было бы лучше использовать их?

Они не предоставляют реализаций, скорее интерфейсов и некоторых классов поддержки, но только для программистов, которые реализуют сторонние библиотеки (пулы или драйверы). Обычно вы даже не смотрите на это. Ваш код должен иметь дело с соединениями из вашего пула, так же как и "простые" соединения прозрачным способом.

Ответ 8

Vibur DBCP - это другая библиотека для этой цели. Несколько примеров, показывающих, как настроить его для использования с Hibernate, Spring + Hibernate или программно, можно найти на его веб-сайте: http://www.vibur.org/

Также см. отказ от здесь.

Ответ 9

бассейн

  • Механизм объединения - это способ создания Объектов заранее. Когда класс загружен.
  • Он улучшает приложение performance [путем повторного использования одного и того же объекта для выполнения любых действий над объектно-данными] и memory [выделения и де-распределения многих объекты создают значительные издержки управления памятью].
  • Очистка объекта не требуется, поскольку мы используем тот же объект, что уменьшает загрузку коллекции мусора.

"Объединение [ Object пул, String Постоянный пул, Thread Пул, пул соединений]

Строковый константный пул

  • Строковый литеральный пул поддерживает только одну копию каждого отдельного строкового значения. который должен быть неизменным.
  • Когда вызывается метод intern, он проверяет наличие объекта с тем же содержимым в пуле, используя метод equals. "Если String-copy доступен в пуле, то возвращает ссылку." В противном случае объект String добавляется в пул и возвращает ссылку.

Пример: String для проверки Уникального объекта из пула.

public class StringPoolTest {
    public static void main(String[] args) { // Integer.valueOf(), String.equals()
        String eol = System.getProperty("line.separator"); //java7 System.lineSeparator();

        String s1 = "Yash".intern();
        System.out.format("Val:%s Hash:%s SYS:%s "+eol, s1, s1.hashCode(), System.identityHashCode(s1));
        String s2 = "Yas"+"h".intern();
        System.out.format("Val:%s Hash:%s SYS:%s "+eol, s2, s2.hashCode(), System.identityHashCode(s2));
        String s3 = "Yas".intern()+"h".intern();
        System.out.format("Val:%s Hash:%s SYS:%s "+eol, s3, s3.hashCode(), System.identityHashCode(s3));
        String s4 = "Yas"+"h";
        System.out.format("Val:%s Hash:%s SYS:%s "+eol, s4, s4.hashCode(), System.identityHashCode(s4));
    }
}

Пул соединений с использованием Type-4 Драйвер с использованием сторонних библиотек [ DBCP2, c3p0, Tomcat JDBC]

Type 4 - The Thin driver converts JDBC calls directly into the vendor-specific database protocol Ex[Oracle - Thick, MySQL - Quora]. wiki

В механизме пула соединений, когда класс загружен, он получает объекты physical JDBC connection и предоставляет пользователю физический объект подключения. PoolableConnection - обертка вокруг фактического соединения.

  • getConnection() выберите одно из бесплатного завернутого соединения из соединения objectpool и вернет его.
  • close() вместо закрытия возвращает завернутое соединение обратно в пул.

Пример: использование пула соединений ~ DBCP2 с Java 7 <

<

public class ConnectionPool {
    static final BasicDataSource ds_dbcp2 = new BasicDataSource();
    static final ComboPooledDataSource ds_c3p0 = new ComboPooledDataSource();
    static final DataSource ds_JDBC = new DataSource();

    static Properties prop = new Properties();
    static {
        try {
            prop.load(ConnectionPool.class.getClassLoader().getResourceAsStream("connectionpool.properties"));

            ds_dbcp2.setDriverClassName( prop.getProperty("DriverClass") );
            ds_dbcp2.setUrl( prop.getProperty("URL") );
            ds_dbcp2.setUsername( prop.getProperty("UserName") );
            ds_dbcp2.setPassword( prop.getProperty("Password") );
            ds_dbcp2.setInitialSize( 5 );

            ds_c3p0.setDriverClass( prop.getProperty("DriverClass") );
            ds_c3p0.setJdbcUrl( prop.getProperty("URL") );
            ds_c3p0.setUser( prop.getProperty("UserName") );
            ds_c3p0.setPassword( prop.getProperty("Password") );
            ds_c3p0.setMinPoolSize(5);
            ds_c3p0.setAcquireIncrement(5);
            ds_c3p0.setMaxPoolSize(20);

            PoolProperties pool = new PoolProperties();
            pool.setUrl( prop.getProperty("URL") );
            pool.setDriverClassName( prop.getProperty("DriverClass") );
            pool.setUsername( prop.getProperty("UserName") );
            pool.setPassword( prop.getProperty("Password") );
            pool.setValidationQuery("SELECT 1");// SELECT 1(mysql) select 1 from dual(oracle)

            pool.setInitialSize(5);
            pool.setMaxActive(3);
            ds_JDBC.setPoolProperties( pool );
        } catch (IOException e) {   e.printStackTrace();
        } catch (PropertyVetoException e) { e.printStackTrace(); }
    }

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

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

    public static Connection getJDBCConnection() throws SQLException {
        return ds_JDBC.getConnection();
    }
}
public static boolean exists(String UserName, String Password ) throws SQLException {
    boolean exist = false;
    String SQL_EXIST = "SELECT * FROM users WHERE username=? AND password=?";
    try ( Connection connection = ConnectionPool.getDBCP2Connection();
          PreparedStatement pstmt = connection.prepareStatement(SQL_EXIST); ) {
        pstmt.setString(1, UserName );
        pstmt.setString(2, Password );

        try (ResultSet resultSet = pstmt.executeQuery()) {
            exist = resultSet.next(); // Note that you should not return a ResultSet here.
        }
    }
    System.out.println("User : "+exist);
    return exist;
}

jdbc:<DB>:<drivertype>:<HOST>:<TCP/IP PORT>:<dataBaseName> jdbc: oracle :thin:@localhost:1521:myDBName jdbc: mysql ://localhost:3306/myDBName

connectionpool.properties

URL         : jdbc:mysql://localhost:3306/myDBName
DriverClass : com.mysql.jdbc.Driver
UserName    : root
Password    :

Web Приложение: Чтобы избежать проблемы подключения, когда все соединение закрыто [MySQL "wait_timeout" по умолчанию 8 часов] для повторного открытия соединение с базовым БД.

Вы можете сделать это, чтобы протестировать каждое соединение, установив testOnBorrow = true и validationQuery = "SELECT 1" и donot использовать autoReconnect для сервера MySQL, поскольку он устарел. проблема

===== ===== context.xml ===== =====
<?xml version="1.0" encoding="UTF-8"?>
<!-- The contents of this file will be loaded for a web application -->
<Context>
    <Resource name="jdbc/MyAppDB" auth="Container" 
        factory="org.apache.tomcat.jdbc.pool.DataSourceFactory" 
        type="javax.sql.DataSource" 

        initialSize="5" minIdle="5" maxActive="15" maxIdle="10"

        testWhileIdle="true"
            timeBetweenEvictionRunsMillis="30000"

        testOnBorrow="true"
            validationQuery="SELECT 1"
            validationInterval="30000"


        driverClassName="com.mysql.jdbc.Driver" 
        url="jdbc:mysql://localhost:3306/myDBName" 
        username="yash" password="777"
    />
</Context>

===== ===== web.xml ===== =====
<resource-ref>
    <description>DB Connection</description>
    <res-ref-name>jdbc/MyAppDB</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
</resource-ref>
===== ===== DBOperations ===== =====
servlet «   init() {}
Normal call used by sevlet  « static {}

static DataSource ds;
static {
    try {
        Context ctx=new InitialContext();
        Context envContext = (Context)ctx.lookup("java:comp/env");
        ds  =   (DataSource) envContext.lookup("jdbc/MyAppDB");
    } catch (NamingException e) {   e.printStackTrace();    }
}

Смотрите также:

Ответ 10

Apache Commons имеет библиотеку для этой цели: DBCP. Если у вас нет странных требований к вашим пулам, я бы использовал библиотеку, поскольку она была сложной и более тонкой, чем вы могли бы надеяться.

Ответ 11

В конце 2017 года Proxool, BoneCP, C3P0, DBCP в настоящее время в основном не функционируют. HikariCP (созданный в 2012 году) кажется многообещающим, удаляет двери из всего остального, о чем я знаю. http://www.baeldung.com/hikaricp

Proxool имеет ряд проблем:
- При большой нагрузке может превышать максимальное количество соединений и не возвращаться ниже максимума
- Не удается вернуться к минимальным соединениям даже после истечения срока действия контактов.
- Может заблокировать весь пул (и все потоки сервера/клиента), если у него возникли проблемы с подключением к базе данных во время потока HouseKeeper (не использует .setQueryTimeout)
- поток HouseKeeper, имея блокировку пула соединений для своего процесса, запрашивает поток Prototyper для воссоздания соединений (sweep), что может привести к условию/блокировке гонки. В этом методе вызывается последний параметр, который всегда должен быть развернут: false во время цикла, только подметать: true под ним.
- HouseKeeper нуждается только в одном прообразе PrototypeController в конце и имеет больше [упомянутых выше]
- поток HouseKeeper проверяет проверку соединений до того, как видят, какие соединения могут быть истекли [некоторый риск тестирования истекшего соединения, которое может быть прервано/завершено с помощью других тайм-аутов в БД в брандмауэре и т.д.]
- Проект имеет незавершенный код (свойства, которые определены, но не действуют)
- Максимальный срок службы соединения по умолчанию, если он не определен, составляет 4 часа (чрезмерный)
- поток HouseKeeper работает каждые пять секунд за пул (чрезмерный)

Вы можете изменить код и внести эти улучшения. Но поскольку он был создан в 2003 году и обновлен в 2008 году, ему не хватало почти 10 лет усовершенствований Java, которые используют такие решения, как hikaricp.

Ответ 12

Вам следует использовать UCP. Универсальный пул соединений (UCP) - это пул соединений Java. Это богатый возможностями пул соединений и тесно интегрирован с базами данных Oracle Real Application Clusters (RAC), ADG, DG.

Подробнее об UCP см. на странице .

Ответ 13

MiniConnectionPoolManager - это реализация с одним ява файлом, если вы ищете встраиваемое решение и не слишком озабочены выступлениями (хотя я не проверял его в этом отношении).

Это многопрофильная EPL, LGPL и MPL.

В его документации также есть альтернативы, заслуживающие проверки (поверх DBCP и C3P0):