предисловие
Сегодня поговорим о технологии пула соединений с базой данных. На самом деле этот термин звучит немного выше, но на самом деле он не очень сложен.Я считаю, что после моего объяснения и фактического написания кода я смогу глубже понять эту технологию. Без лишних слов, давайте начнем объяснять.
Обзор технологии объединения соединений с базой данных
Так называемая технология пула соединений с базой данных используется для выделения, управления и освобождения соединений с базой данных. Вы можете спросить, кажется, я могу реализовать эти функции непосредственно с помощью JDBC. Что ж, вы правы, JDBC действительно может, но вы помните, когда мы используем технологию JDBC, каждый раз, когда мы ее используем, будет ли соединение закрываться; придется снова открывать соединение с базой данных? На самом деле, ресурсы ссылок на базу данных очень ценны, и мы не можем увидеть их в небольших проектах.В проектах с высокой степенью параллелизма вы обнаружите, что такое частое открытие и закрытие ссылок на базу данных является своего рода разрушением сервера, очень сильно влияет эффективность. Итак, как же это делает пул соединений с базой данных? Идея реализации такова: каждый раз, когда есть доступ, пул соединений с базой данных будет выделять соединение с базой данных для пользователя, а когда у пользователя заканчиваются соединения, пул соединений будет перерабатывать соединение и возвращать его в соединение. набор. Принцип такой, давайте посмотрим на эту картинку, чтобы углубить впечатление
Так что вам все еще может быть не ясно, и пул соединений с базой данных имеет более сложные вещи, которые нужно учитывать, чем выше, но не бойтесь, я помогу вам понять реальный код. Примечание. Следующий код предназначен для самостоятельной реализации простого пула соединений с базой данных с упором на понимание принципа пула соединений с базой данных.Самостоятельно реализовать пул соединений с базой данных
Примечание: следующий код я объясняю блоками, вы вставляете их один за другим, и они обязательно будут работать в итоге, для удобства я приведу полный код реализации после доклада.
- Определите количество начальных подключений, максимальное количество подключений и количество подключенных в данный момент подключений В начале, когда запускается пул соединений с базой данных, для достижения вышеуказанных требований мы должны сначала дать несколько завершенных соединений, чтобы пользователи могли получить их непосредственно при доступе; кроме того, по истечении определенного периода времени. количество пользователей доступа превышает количество подключений в пуле подключений, который я определил, необходимо создать дополнительное подключение для использования пользователем; конечно, это вновь созданное подключение не должно быть неограниченным, иначе оно все равно повлияет на эффективность.Поэтому, нам также необходимо определить максимальное количество подключений.
private final int init_count = 3; //初始化链接数目
private final int max_count = 6; //最大连接数
private int current_count = 0; //到当前连接数
- Итак, где мы должны разместить вновь созданный пул соединений для использования пользователями? Обязательно нужно создать набор подключения, что удобнее. Что касается того, зачем использовать такую коллекцию, как LinkedList, я расскажу об этом позже.
private LinkedList<Connection> pool = new LinkedList<Connection>();
- Как я только что сказал, мы должны сначала инициализировать соединение для использования пользователем, а затем нам нужно создать определенное количество ссылок при запуске пула соединений. После анализа выясняется, что лучше всего инициализировать ссылку в конструкторе, и, наконец, поместить ссылку в коллекцию ссылок.
//构造函数,初始化链接放入连接池
public MyPool() {
for (int i=0;i<init_count;i++){
//记录当前连接数
current_count++;
//createConnection是自定义的创建链接函数.
Connection connection = createConnection();
pool.addLast(connection);
}
}
- Создайте новое подключение, об этом и говорить нечего, ведь нужные вам ссылки идут отсюда.
public Connection createConnection() {
Class.forName("com.mysql.jdbc.Driver");
Connection connection =DriverManager.getConnection("jdbc:mysql://localhost:3306/keyan","root","root");
return connection;
}
- получить ссылку Когда пользователь приходит в гости, мы должны дать пользователю соединение.Если в пуле нет соединения (все соединения заняты), то необходимо создать новое соединение и использовать функцию createConnection().Число не должно быть превышает максимальное количество подключений. Если эти два условия не выполняются, сразу создается исключение.
public Connection getConnection() {
if (pool.size() > 0){
//removeFirst删除第一个并且返回
//现在你一定看懂了我说的为什要用LinkedList了吧,因为下面的这个
//removeFirst()方法会将集合中的第一个元素删除,但是还会返回第一个元素
//这样就省去了我们很多不必要的麻烦
return pool.removeFirst();
}
if (current_count < max_count){
//记录当前使用的连接数
current_count++;
//创建链接
return createConnection();
}
throw new RuntimeException("当前链接已经达到最大连接数");
}
- освободить ресурсы Когда пользователь завершает использование соединения, нам нужно не закрыть соединение, а поместить соединение обратно в пул ресурсов LinkedList, что избавляет от необходимости закрывать соединение снова и снова. Это основное содержимое пула соединений. Разве это не просто?
public void releaseConnection(Connection connection){
if (pool.size() < init_count){
pool.addLast(connection);
current_count--;
}else {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
Весь процесс реализации такой, все коды я выложу ниже для всеобщего ознакомления.
//单元测试
@Test
public class MyPool {
private final int init_count = 3; //初始化链接数目
private final int max_count = 6; //最大
private int current_count = 0; //到当前连接数
//连接池,用来存放初始化链接
private LinkedList<Connection> pool = new LinkedList<Connection>();
//构造函数,初始化链接放入连接池
public MyPool() {
for (int i=0;i<init_count;i++){
//记录当前连接数
current_count++;
Connection connection = createConnection();
pool.addLast(connection);
}
}
//创建新的连接
public Connection createConnection() {
try {
Class.forName("com.mysql.jdbc.Driver");
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/keyan","root","root");
return connection;
}catch (Exception e){
System.out.println("数据库链接异常");
throw new RuntimeException();
}
}
//获取链接
public Connection getConnection() {
if (pool.size() > 0){
//removeFirst删除第一个并且返回
return pool.removeFirst();
}
if (current_count < max_count){
//记录当前使用的连接数
current_count++;
//创建链接
return createConnection();
}
throw new RuntimeException("当前链接已经达到最大连接数");
}
//释放链接
public void releaseConnection(Connection connection){
if (pool.size() < init_count){
pool.addLast(connection);
current_count--;
}else {
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
После самостоятельного просмотра кода вы обнаружили, что технология, которая изначально казалась сложной, не такая, как мы думали? Что ж, после представления основных принципов технологии пула соединений с базой данных мы представим две превосходные технологии пула соединений с открытым исходным кодом. На самом деле реальный пул соединений с базой данных должен учитывать более сложные вещи, чем то, что мы только что написали Нам не нужно писать такие сложные вещи на данном этапе, но если вам интересно, вы можете взглянуть на исходный код пул соединений с базой данных - нет Неверно, эти два пула соединений имеют открытый исходный код. Хорошо, давайте начнем!
Отличный пул соединений с базой данных
Прежде всего, компания Sun оговаривает, что технология пула соединений должна реализовывать интерфейс javax.sql.DataSource, то есть, если вы хотите реализовать пул соединений с базой данных самостоятельно, вы должны реализовать этот интерфейс. Разве это не очень хорошо? На самом деле, как установщик стандартов, Sun все еще имеет много требований. Это право установщика стандартов. Поэтому компании или страны часто берут на себя ведущую роль в разработке некоторых ключевых технических стандартов. Кровотечение. Ну далеко. . .
DBPC
На самом деле, вы можете не знать, что если ваш tomcat специально сконфигурирован, его также можно использовать в качестве пула соединений с базой данных, потому что встроенный tomcat — это DBPC. Для использования DBPC необходимо импортировать три файла jar: commons-dbcp2-2.2.0.jar, commons-pool2-2.5.0.jar, commons-logging-1.2.jar. Я думаю, с вашей смекалкой, если вы хотите получить эти три jar-файла, это должна быть груда мелкой посуды.Это обязательный навык для разработчика программного обеспечения - научитесь искать. Он очень прост в использовании.Есть два основных способа использования: один - жесткое кодирование, то есть вручную установить различные параметры самостоятельно, а другой - настроить соответствующий файл конфигурации, а затем загрузить его.
Жестко запрограммированная реализация DBPC
BasicDataSource dataSource = new BasicDataSource();
//参数配置:初始化连接数,最大连接数,连接字符串,驱动,用户,密码
dataSource.setInitialSize(3); //最大初始化链接
dataSource.setMaxTotal(6); //最大链接
dataSource.setMaxIdle(3000); //最大空闲时间
dataSource.setUrl("jdbc:mysql:///keyan"); //url
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUsername("root");
dataSource.setPassword("root");
//获取链接
Connection connection = dataSource.getConnection();
connection.prepareStatement("SELECT * FROM e_person").execute();
connection.close();
Используйте запрос, вы можете просто следовать исходной операции JDBC на линии, это ничего не сказать, чтобы добиться на линии, мы не должны забывать импортировать пакет в соответствии с моей конфигурацией выше.
Реализация режима профиля
//创建properties配置文件
Properties properties = new Properties();
//获取文件流
InputStream in = DBCPTest.class.getResourceAsStream("db.properties");
//加载配置文件
properties.load(in);
//创建数据源对象
BasicDataSource dataSource = BasicDataSourceFactory.createDataSource(properties);
//获取链接
Connection connection = dataSource.getConnection();
ResultSet resultSet = connection.prepareStatement("SELECT * FROM e_person").executeQuery();
while (resultSet.next()){
System.out.println(resultSet.getString("work_name"));
}
connection.close();
Выше приведен основной рабочий процесс, давайте посмотрим на конфигурацию этого xml-файла.
документdb.properties
url=jdbc:mysql:///keyan
driverClassName=com.mysql.jdbc.Driver
username=root
password=root
initialSize=3
maxActive=6
maxIdle=3000
Особо следует отметить, что этот файл конфигурации должен быть помещен в тот же пакет, что и ваш класс DBPC. После того, как все будет завершено, вы можете использовать его напрямую.
C3P0
c3p0 также является очень хорошей технологией пула подключений: файлов для импорта относительно немного, только один c3p0-0.9.1.2.jar. Просто зайдите на сайт и найдите его. Есть также два способа использования c3p0, которые также являются жестко запрограммированными и конфигурационными файлами.
жестко запрограммированный
//配置相关的参数
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setJdbcUrl("jdbc:mysql:///keyan");
dataSource.setDriverClass("com.mysql.jdbc.Driver");
dataSource.setUser("root");
dataSource.setPassword("root");
dataSource.setInitialPoolSize(3);
dataSource.setMaxPoolSize(6);
dataSource.setMaxIdleTime(1000);
Connection connection = dataSource.getConnection();
//sql语句
ResultSet resultSet = connection.prepareStatement("SELECT * FROM e_project").executeQuery();
while (resultSet.next()){
System.out.println(resultSet.getString("project_name"));
}
connection.close();
Как и выше, достаточно просто использовать его и знать, как его использовать. Что касается более глубоких вещей, если вам интересно, пожалуйста, изучайте это медленно.
конфигурационный файл
ComboPooledDataSource dataSource = new ComboPooledDataSource();
Connection connection = dataSource.getConnection();
ResultSet resultSet = connection.prepareStatement("SELECT * FROM e_project").executeQuery();
while (resultSet.next()){
System.out.println(resultSet.getString("project_name"));
}
connection.close();
На первый взгляд может возникнуть вопрос, а не реализовано ли это в виде конфигурационного файла? Все верно, это просто неявный вызов, его не нужно реализовывать, нужно просто создать новый объект ComboPooledDataSource, по умолчанию вызывается файл xml, а путь к файлу - это корневая директория src. Другими словами, вам нужно только записать файл конфигурации в каталог src. Дело в том, как написать этот xml-файл. Обратите внимание, что имя файла — c3p0-config.xml, имя файла нельзя изменить, оно должно быть таким, а путь к файлу должен быть корневым каталогом src, иначе он не может быть прочитан.
<c3p0-config>
<default-config>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/test</property>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="user">root</property>
<property name="password">root</property>
<property name="initialPoolSize">3</property>
<property name="maxPoolSize">6</property>
<property name="maxIdleTime">1000</property>
</default-config>
</c3p0-config>
Вообще говоря, параметров в конфигурационном файле не так уж и много.Конечно, вы также можете найти соответствующую информацию, чтобы понять значение параметров более подробно.Эти параметры достаточно для нашего повседневного использования.
Дополнительное содержание: Преимущества пула соединений с базой данных
Повторное использование ресурсов
Поскольку соединение с базой данных используется повторно, чтобы избежать частого создания и выпуска больших накладных расходов из-за соединения. С другой стороны, на основе системы для снижения потребления также повысилась стабильность операционной среды системы.
Более высокая скорость отклика системы
В процессе инициализации пула соединений с базой данных часто создается несколько соединений с базой данных, которые помещаются в резервный пул соединений. На этом инициализация соединения завершена. Для обработки бизнес-запросов существующие доступные соединения используются напрямую, чтобы избежать дополнительных затрат времени на инициализацию и освобождение соединения с базой данных, тем самым сокращая время отклика системы.
новые средства распределения ресурсов
Для системы, в которой несколько приложений совместно используют одну и ту же базу данных, конфигурация пула соединений с базой данных на уровне приложения может ограничить максимальное количество соединений с базой данных, доступных для приложения, и избежать монополизации приложением всех ресурсов базы данных.
Унифицированное управление соединениями для предотвращения утечки соединения с базой данных:
В относительно полной реализации бассейна базы данных занятые соединения могут быть насильственно восстановлены в соответствии с настройкой тайм-аута Pre-rocurge, тем самым избегая возможной утечки ресурсов в обычных операциях подключения к базе данных.
Эпилог
Спасибо за чтение, добро пожаловать на устранение проблем в блоге, вы также можете связаться со мной, чтобы добиться прогресса и общаться вместе!
Публичный аккаунт WeChat: программа «собака атаки» Электронная почта: roobtyan@outlook.com личный блог:roobtyan.cnОтсканируйте QR-код ниже, чтобы следовать за мной, вы получите что-то неожиданное... Я подготовил для вас очень хороший видеоурок по JAVA, от основ JAVA до JAVAWEB, а также очень мощный проект реального боя. Просто в моем публичном аккаунте WeChat вы можете просмотреть его, ответив на java, это бесплатно!