Skip to main content
Spring Boot подключается к Postgres через JDBC-драйвер PostgreSQL (pgjdbc) и пул соединений HikariCP, а при запуске приложения выполняет миграции Flyway. В этом руководстве вы создадите таблицу todos с помощью миграции Flyway и реализуете REST-контроллер на Spring Data JPA, обрабатывающий запросы на создание, чтение, обновление и удаление. Все соединения защищены TLS с полной проверкой сертификата.

Предварительные требования

  • JDK 17 или новее (этого требует Spring Boot 4). Руководство протестировано с Java 25, Spring Boot 4.1.1, pgjdbc 42.7.13, Hibernate 7.4.5, HikariCP 7.0.2 и Flyway 12.4.0.
  • Аккаунт ClickHouse Cloud
  • psql для создания базы данных. Вместо этого можно выполнить оператор CREATE DATABASE в консоли SQL.

Создание сервиса ClickHouse Managed Postgres

В консоли ClickHouse Cloud нажмите New service и выберите Postgres. Инстанс будет готов через несколько минут. Пошаговое описание процесса приведено в кратком руководстве по началу работы.

Получение сведений о подключении

Нажмите Подключение на левой боковой панели вашего сервиса. В открывшемся модальном окне указаны имя пользователя, пароль, сервер и порт, а также есть переключатель Directly / via PgBouncer. Выбрав Directly, включите Use SSL и откройте вкладку jdbc. На ней приведён JDBC URL, который можно использовать в Spring Boot, внеся в него два изменения (см. раздел Настройка соединения): заменить имя базы данных и имя файла CA‑сертификата.
JDBC URL не содержит имени пользователя и пароля: Spring Boot считывает их из отдельных свойств. В этом руководстве подключение к Postgres выполняется напрямую через порт 5432. Приложение Spring Boot — это долгоживущий процесс с собственным пулом HikariCP (по умолчанию 10 соединений), поэтому дополнительный пулер перед Postgres ему не нужен. Следите за тем, чтобы количество инстансов приложения, умноженное на размер пула, не превышало значения max_connections сервиса. Если вы запускаете много инстансов, см. раздел Использование PgBouncer. В модальном окне нажмите Download CA certificate. CA‑сертификат также можно скачать в разделе Settings → CA Certificate. Сертификат уникален для вашего инстанса, поэтому с его помощью драйвер может убедиться, что подключается именно к вашему серверу.

Настройка проекта

Создайте проект Maven с помощью Spring Initializr, добавив зависимости Spring Web, Spring Data JPA, Flyway Migration и PostgreSQL Driver:
Добавляете в существующее приложение?Пропустите команду curl. В файле pom.xml добавьте зависимости spring-boot-starter-data-jpa, spring-boot-starter-flyway и org.flywaydb:flyway-database-postgresql, а также org.postgresql:postgresql с областью видимости runtime. Если ваше приложение использует H2, удалите com.h2database:h2. Затем перейдите к разделу Настройка соединения.

Настройка соединения

Переместите скачанный CA‑сертификат в каталог проекта и переименуйте его в ca-certificate.pem. Создайте базу данных для приложения. Замените <PASSWORD> и хост значениями из модального окна Подключение:
Замените содержимое файла src/main/resources/application.properties следующим. Если приложение уже существует, добавьте строки spring.datasource и spring.jpa и удалите все остальные параметры spring.datasource, например URL для H2. Возьмите URL со вкладки jdbc, заменив в нём базу данных на guide_spring, а значение sslrootcert — на путь к переименованному файлу:
src/main/resources/application.properties
pgjdbc считывает sslmode=verify-full и sslrootcert из URL. Драйвер загружает все сертификаты из файла CA и проверяет как цепочку сертификатов, так и имя хоста, поэтому дополнительный код для TLS писать не нужно. Spring Boot берёт пароль из переменной окружения DATABASE_PASSWORD, так что в файле он не хранится. Остальные параметры:
  • ddl-auto=validate — Hibernate при запуске проверяет, что ваши сущности соответствуют таблицам, которые создаёт Flyway. Сам Hibernate схему не изменяет.
  • open-in-view=false — каждое соединение возвращается в пул сразу по завершении его транзакции, а не удерживается до записи HTTP-ответа.
Относительный путь sslrootcert разрешается относительно рабочего каталога JVM. ./mvnw spring-boot:run запускает приложение в каталоге проекта, поэтому там путь ca-certificate.pem работает. Если вы запускаете упакованный JAR из другого места, укажите абсолютный путь. pgjdbc не раскрывает ~.Если скопировать URL с выключенным параметром Use SSL, в нём не будет sslmode, и тогда pgjdbc использует режим prefer: соединение шифруется, но сервер не проверяется. При неверном CA подключение завершается ошибкой PKIX path building failed. Если файл отсутствует, возникает ошибка Could not open SSL root certificate file. Если хост не соответствует сертификату, например при подключении по IP-адресу, возникает ошибка The hostname ... could not be verified by hostnameverifier PgjdbcHostnameVerifier.

Создание таблицы с помощью Flyway

При запуске приложения Flyway выполняет SQL-файлы из каталога src/main/resources/db/migration в порядке их версий — ещё до того, как Hibernate проверит схему. Создайте файл src/main/resources/db/migration/V1__create_todos.sql:
src/main/resources/db/migration/V1__create_todos.sql
Flyway записывает каждый применённый файл в таблицу flyway_schema_history и при последующих запусках выполняет только новые файлы. Чтобы изменить схему, добавьте новый файл, например V2__add_due_date.sql, а не редактируйте уже выполненный.
В приложении, использовавшем H2, таблицы обычно создавал сам Hibernate, поскольку для встроенных баз данных ddl-auto по умолчанию имеет значение create-drop. Для Postgres значение по умолчанию — none, поэтому добавьте миграцию, которая создаёт ваши существующие таблицы. Кроме того, для @Id с простой аннотацией @GeneratedValue нужна последовательность, названная по имени сущности (например, employee_seq для Employee), с шагом 50 — это размер выделения в Hibernate по умолчанию. Иначе при запуске возникнет ошибка Schema validation: missing sequence [employee_seq], а если шаг последовательности равен 1 — ошибка The increment size of the [employee_seq] sequence is set to [50] in the entity mapping but the mapped database sequence increment size is [1]:

Выполнение запросов к базе данных

Создайте сущность в файле src/main/java/com/example/todos/Todo.java. Spring Boot сопоставляет поле createdAt со столбцом created_at:
src/main/java/com/example/todos/Todo.java
Создайте репозиторий Spring Data в файле src/main/java/com/example/todos/TodoRepository.java. Реализацию этого интерфейса Spring Data создаёт во время выполнения:
src/main/java/com/example/todos/TodoRepository.java
Создайте REST-контроллер в src/main/java/com/example/todos/TodoController.java, в котором каждому маршруту соответствует один вызов репозитория:
src/main/java/com/example/todos/TodoController.java
Каждый вызов репозитория выполняется в отдельной транзакции через соединение из пула HikariCP. Чтобы объединить несколько вызовов в одну транзакцию, поместите их в метод с аннотацией @Transactional.

Запуск и проверка

Задайте пароль и запустите приложение:
При первом запуске Flyway применяет миграцию ещё до старта веб-сервера. В журнале появляются следующие строки (здесь они приведены без временных меток и имён потоков):
Во втором терминале создайте две задачи, отметьте первую как выполненную и удалите вторую:
Запросы POST возвращают новые строки, а запрос PATCH — обновлённую строку. Параметр -w '\n' добавляет перевод строки после каждого ответа:
Откройте http://localhost:3113/todos в браузере, чтобы просмотреть список оставшихся задач. Ответ будет выглядеть так:
Чтобы убедиться, что приложение устанавливает соединения по TLS, выполните запрос к pg_stat_ssl, пока приложение работает:
Эти 10 соединений — пул HikariCP. Остановите приложение сочетанием клавиш Ctrl+C. Чтобы просмотреть данные в консоли, откройте консоль SQL на левой боковой панели вашего сервиса, разверните guide_spring, затем public и выберите таблицу todos. В соседней таблице flyway_schema_history хранится история миграций. В таблице todos осталась одна строка:

Использование PgBouncer

Если суммарное число соединений от множества инстансов приложения приближается к лимиту Postgres, подключайте приложение через встроенный PgBouncer на порту 6432, а Flyway оставьте на прямом соединении. В файле application.properties замените порт в spring.datasource.url на 6432 и добавьте под ним строки spring.flyway:
src/main/resources/application.properties
Если задан spring.flyway.url, Flyway открывает собственное соединение и не использует имя пользователя и пароль из spring.datasource, поэтому задайте также spring.flyway.user и spring.flyway.password. Один и тот же CA‑сертификат подходит для обоих портов. PgBouncer работает в режиме пулинга транзакций, поэтому каждая транзакция может выполняться в отдельном соединении с Postgres. При использовании Spring Boot:
  • Подготовленные операторы работают с настройками драйвера по умолчанию, поэтому prepareThreshold=0 не требуется. Начиная с пятого выполнения оператора в рамках одного соединения (prepareThreshold), pgjdbc использует именованный серверный подготовленный оператор. Операторы освобождаются сообщением Close на уровне протокола, и встроенный PgBouncer его поддерживает.
  • Требуется pgjdbc 42.7.5 или новее. Более старые версии передают параметр запуска extra_float_digits, и PgBouncer отклоняет соединение с ошибкой FATAL: unsupported startup parameter: extra_float_digits. Spring Boot 4 уже содержит более новую версию pgjdbc. В более старых версиях Spring Boot укажите <postgresql.version>42.7.13</postgresql.version> в разделе <properties> файла pom.xml.
  • Настройки сеанса не сохраняются. Операторы SET и метод Connection.setSchema, который использует свойство HikariCP spring.datasource.hikari.schema, действуют только в том соединении с Postgres, где они выполнены, и могут затронуть других клиентов. Параметры URL currentSchema и options приводят к ошибке FATAL: unsupported startup parameter. Используйте имена таблиц с указанием схемы или SET LOCAL внутри транзакции.
  • Flyway по умолчанию работает через PgBouncer, поскольку использует advisory-блокировку на уровне транзакции. Для миграций с CREATE INDEX CONCURRENTLY требуется spring.flyway.postgresql.transactional-lock=false: эта настройка переключает Flyway на блокировку уровня сеанса. Через PgBouncer такая блокировка завершается ошибкой Unable to release PostgreSQL advisory lock и продолжает удерживаться на соединении из пула, поэтому для Flyway используйте прямое соединение.
  • Размер пула: каждое соединение HikariCP — это недорогое клиентское соединение с PgBouncer. PgBouncer ограничивает число соединений с Postgres, которые он открывает для каждой пары «база данных — пользователь» (default_pool_size), независимо от того, сколько клиентских соединений открывают инстансы вашего приложения. Транзакции сверх этого ограничения ждут в PgBouncer до query_wait_timeout (по умолчанию 120 секунд), а не завершаются ошибкой в HikariCP. Увеличение пула HikariCP повышает параллелизм лишь до этого предела, поэтому значение по умолчанию — 10 на инстанс — хорошая отправная точка. См. Ограничения соединений PgBouncer и Postgres.
pg_stat_ssl отображает соединение между PgBouncer и Postgres, поэтому TLS-запрос из раздела Запуск и проверка не показывает соединения приложения через PgBouncer. Тем не менее соединение приложения с PgBouncer тоже проверяется: при неверном CA‑сертификате оно точно так же завершится ошибкой.

Дальнейшие шаги

Последнее изменение 14 октября 2026 г.