Добавляем БД PostgreSQL к RESTful сервису на Spring Boot. Часть 1
Начну с того, что мне очень понравился цикл статей от Эллеоноры Керри под названием «Обзор REST». Вот ссылки на эти статьи:
- Обзор REST. Часть 1: что такое REST
- Обзор REST. Часть 2: коммуникация между клиентом и сервером
- Обзор REST. Часть 3: создание RESTful сервиса на Spring Boot
В общем, я решил взять на себя смелость, и немного дополнить их. А именно, рассказать как создать базу данных и подключить ее к этому приложению. С чего начать? Наверное с самой базы данных. Я решил использовать PostgreSQL , так как мне понравился дружественный интерфейс ее админки. Для начала нам нужно скачать установщик PostgreSQL, например отсюда: PostgreSQL Database Download Полный процесс установки я описывать не буду, т.к. он может отличаться в зависимости от вашей ОС. Однако отмечу, что в процессе вам потребуется придумать пароль администратора для дефолтной роли (учетной записи) postgres и ввести его 2 раза. Для простоты я установил пароль 123 . Конечно, в реальных проектах необходимо придумать что-то посложнее. Далее программа установки предлагает выбрать порт, я оставил его значение по умолчанию. Locale тоже оставил по умолчанию. Установили, дальше открываем интерфейс администратора pgAdmin . Oткроется браузер со всплывающим окошком, где нас попросят ввести созданный ранее пароль. Теперь нам нужно установить язык интерфейса. Для этого нажимаем Configure pgAdmin —> Miscellaneous —> User Language , выбираем нужный язык —> Save , и перезагружаем страницу браузера . В левом верхнем углу страницы нажимаем Server , появляется окошко « Подключиться к серверу ». Вводим наш пароль еще раз и ставим галку Save Password , чтобы не вводить его каждый раз. Можно было бы и далее использовать роль администратора для всех баз данных, но лучше создадим новую роль, ведь у нас может быть много баз данных и много программ, которые их используют. Для этого в левом верхнем углу жмем на PostgreSQL 12 —> ПКМ на Роли входа/группы —> Создать —> Роль входа/группы Во всплывающем окне на вкладке « Общие » вписываем имя роли. Я назвал роль root . На вкладке « Определение » создаем новый пароль, я оставил 123 , просто чтобы не запутаться. Переходим на вкладку « Права » и отмечаем все необходимые пункты. Я установил все пункты « ДА ». Нажимаем « Сохранить » Переходим к созданию базы данных. Жмем ПКМ на «Базы данных» —> Создать —> База данных На вкладке « Общие » создаем название базы данных. Пусть это будет, например, customers . Владельцем назначаем root , которого мы создали на предыдущем этапе. На вкладке « Определение » проверяем, что у нас установлена кодировка UTF8 . Нажимаем « Сохранить ». Всё, наша база данных создана (пока что пустая). На этом можно было бы закончить с pgAdmin, т.к. таблицы мы будем создавать программно, но, на всякий случай, покажу как создать таблицу вручную. Разворачиваем дерево customers —> Схемы —> public . Жмем ПКМ Таблицы —> Создать —> Таблица . Откроется всплывающее окно. На вкладке « Общие » назначаем имя нашей таблице, например test_table , владельцем назначаем root . Переходим на вкладку « Столбцы », нажимаем на » + » для создания нового столбца. Вводим имя “ id ” и тип данных bigserial , что эквивалентно типу Long в Java, но с авто-инкрементом (при добавлении новой записи, id будет автоматически увеличиваться на единицу). Не NULL отмечаем как « Да », первичный ключ тоже « Да ». Создаем таким же образом столбцы ” name ”, “ email ” и ” phone ”. Тип данных выбираем character varying , это соответствует типу String , но позволяет задать максимальную длину. Задаем максимальную длину имени в 200 символов для заполнения Ф.И.О. в одном столбце. Задаем максимальную длину email в 254 символа. Почему у email такая максимальная длина можно узнать здесь. Для телефонного номера выделяем 20 символов, этого должно хватить. Немного о телефонных номерах: Заблуждения программистов о телефонных номерах (Хабр) Не NULL во всех столбцах отмечаем как « Да », если хотим, чтобы эти данные были обязательными. Нажимаем « Сохранить ». Всё, таблица создана. Для удаления нашей тестовой таблицы нажмите ПКМ по ней (в дереве) и « удалить », т.к. она нам больше не нужна, ведь мы будем создавать таблицы из нашей программы. Закрываем pgAdmin , и переходим к нашей программе. Открываем IDEA с нашим проектом. Нажимаем Database в правом столбце интерфейса, нажимаем на » + » для добавления нашей БД. Далее Data Source —> PostgreSQL . Во всплывающем окне вписываем в поле User роль root , которую мы создали ранее, и наш пароль 123 в поле password . В поле Database пишем название нашей БД customers . Нажимаем кнопку Test Connection , и если видим зеленую галку под ней, то все в порядке, и нажимаем кнопку OK . Всё, к БД подключились, теперь переходим к файлу pom.xml и добавим зависимости. Для работы с БД ORM :
org.springframework.boot spring-boot-starter-data-jpa
org.springframework.boot spring-boot-starter-data-rest
org.springframework.boot spring-boot-starter-tomcat
org.postgresql postgresql 42.2.10
Разобрались с pom.xml, перейдем в папку resources, и заполним файл application.properties следующим образом:
spring.datasource.url=jdbc:postgresql://localhost:5432/customers spring.datasource.username=root spring.datasource.password=123 spring.datasource.driver-class-name=org.postgresql.Driver spring.jpa.database=postgresql spring.jpa.database-platform=org.hibernate.dialect.PostgreSQL10Dialect
Здесь мы прописали URL нашей базы данных, сообщили логин и пароль для нее, прописали драйвер для PostgreSQL, обозначили, что будем использовать тип данных PostgreSQL и прописали диалект для Hibernate. Далее создадим в той же папке resources новую директорию под названием database . В этой директории создадим 2 файла: initDB.sql и populateDB.sql . Первый будет отвечать за создание таблиц, второй за первоначальное их заполнение. Откроем initDB.sql и увидим сверху зеленую полоску с надписью SQL dialect is not configured . Это означает, что мы не выбрали диалект SQL для нашего проекта (а их существует несколько). Нажимаем справа на этой же полоске на надпись Change dialect to… . Во всплывающем окошке жмем Project SQL Dialect , и поскольку база данных у нас PostgreSQL , то выбираем одноименный диалект. Жмем ОК Перейдем к заполнению наших файлов .sql . Заполним сначала файл initDB.sql :
CREATE TABLE IF NOT EXISTS clients ( id BIGSERIAL PRIMARY KEY , name VARCHAR(200) NOT NULL , email VARCHAR(254) NOT NULL , phone VARCHAR(20) NOT NULL );
Если у вас после заполнения файла какие-то слова кроме clients написаны белым шрифтом, то нажмите ПКМ внутри текста, и выберите еще раз Change Dialect —> PostgreSQL . Как вы наверное уже поняли, это те же самые данные, которые мы заполняли при создании тестовой таблицы вручную. Здесь они оформлены на диалекте PostgreSQL языка SQL. Теперь заполним файл populateDB.sql :
INSERT INTO clients VALUES (1, 'Vassily Petrov', 'vpetrov@jr.com', '+7 (191) 322-22-33)'), (2, 'Pjotr Vasechkin', 'pvasechkin@jr.com', '+7 (191) 223-33-22)');
Если название таблицы clients у вас написано красными буквами, то ничего страшного. Дело в том, что мы еще не создали эту таблицу, и IDEA ее пока что не узнает. Для того, чтобы создать и заполнить таблицу, нам нужно вернуться в файл application.properties и добавить туда три следующие строчки:
spring.datasource.initialization-mode=ALWAYS spring.datasource.schema=classpath*:database/initDB.sql spring.datasource.data=classpath*:database/populateDB.sql
В этих строках мы говорим, что хотим инициализировать БД программно и указываем какие файлы нужно для этого использовать. Далее переходим в метод main нашего приложения, и запускаем его . После этого идем в pgAdmin —> Servers —> PostgreSQL 12 —> Базы данных —> customers —> Схемы —> public , нажимаем ПКМ на « Таблицы », « Обновить ». Если всё прошло успешно, то видим созданную нами таблицу clients . После этого переходим обратно в файл application.properties и закомментируем строку.
spring.datasource.data=classpath*:database/populateDB.sql
spring.datasource.url=jdbc:postgresql://localhost:5432/customers spring.datasource.username=root spring.datasource.password=123 spring.datasource.driver-class-name=org.postgresql.Driver spring.jpa.database=postgresql spring.jpa.database-platform=org.hibernate.dialect.PostgreSQL10Dialect spring.datasource.initialization-mode=ALWAYS spring.datasource.schema=classpath*:database/initDB.sql #spring.datasource.data=classpath*:database/populateDB.sql
Если мы этого не сделаем, то при следующем запуске программы получим такую ошибку: org.postgresql.util.PSQLException: ОШИБКА: повторяющееся значение ключа нарушает ограничение уникальности «clients_pkey». Это происходит потому, что у нас уже заполнены в таблице поля с id 1 и 2 (еще при первом запуске). В созданной нами таблице поле id указано как bigserial , что соответствует типу Long в Java. Однако в нашей программе для этого поля используется тип Integer . Я решил показать как использовать Long (BIGSERIAL), потому что это больший диапазон чем Integer. Дело в том, что в таблицах поле, обозначенное как Primary Key может использоваться не только для хранения id юзеров, но и для хранения индексов самых различных данных, и количество таких записей может превысить максимальное значение Integer. Например, если наша программа ежесекундно производит какие-то измерения и записывает данные в таблицу. Для того, чтобы переписать наши классы под использование типа данных Long, нам необходимо поменять тип с Integer на Long во всех классах и методах, где используется поле id . Мы этого делать не будем, потому что изначально программа была написана автором под тип id Integer, значит в этом есть какой-то смысл. Чтобы продолжить, давайте еще раз удалим созданную нами таблицу clients из нашей БД, но теперь мы попробуем сделать это программно, а не вручную. Для этого закомментируем наш код в файле initDB.sql , и добавим одну строчку:
-- CREATE TABLE IF NOT EXISTS clients -- ( -- id BIGSERIAL PRIMARY KEY , -- name VARCHAR(200) NOT NULL , -- email VARCHAR(254) NOT NULL , -- phone VARCHAR(20) NOT NULL -- ); DROP TABLE IF EXISTS clients
Запустим программу, перейдем в pgAdmin , нажмем ПКМ на « Таблицы » (в нашей базе данных customers ) — -> « Обновить », и увидим, что наша таблица пропала. NB! Будьте осторожны с использованием этой команды, иначе вы рискуете потерять все данные, которые были в вашей таблице! Вернемся в файл initDB.sql и перепишем его следующим образом:
CREATE TABLE IF NOT EXISTS clients ( id SERIAL PRIMARY KEY , name VARCHAR(200) NOT NULL , email VARCHAR(254) NOT NULL , phone VARCHAR(50) NOT NULL );
Здесь мы поменяли тип id на SERIAL , что соответствует типу Integer , который мы используем для поля id в нашей программе. Кроме того, была увеличена максимальная длина поля phone, чтобы мы могли свободно использовать пробелы и специальные символы (скобки, тире и др.) в его написании. Максимальное количество цифр в телефонном номере на данный момент составляет 18 цифр (если мне не изменяет память). Я установил размер в 50 символов, чтобы хватило наверняка. Перейдем в файл application.properties, раскомментируем строку:
spring.datasource.data=classpath*:database/populateDB.sql
Запустим нашу программу, зайдем в pgAdmin, проверим что наша таблица создана, И закомментируем эту строку обратно.
#spring.datasource.data=classpath*:database/populateDB.sql
На этом первую часть статьи пожалуй закончу. Надеюсь, что она вам понравится, пишите комментарии (даже если не понравилось). Во второй части мы перепишем наши классы, чтобы они могли работать с реальными базами данных. Продолжение: Добавляем БД PostgreSQL к RESTful сервису на Spring Boot. Часть 2 UPD Спасибо модераторам, что поправили мои картинки и форматирование текста!