Java spring jdbc postgresql

Spring Boot Connect to PostgreSQL Database Examples

Through this Spring Boot tutorial, you will learn how to configure and write code for connecting to a PostgreSQL database server in a Spring Boot application. I’ll share with you the two common ways:

  • Use Spring JDBC with JdbcTemplate to connect to a PostgreSQL database
  • Use Spring Data JPA to connect to a PostgreSQL database
  • Add a dependency for PostgreSQL JDBC driver, which is required to allow Java applications to be able to talk with a PostgreSQL database server.
  • Configure data source properties for the database connection information
  • Add a dependency for Spring JDBC or Spring Data JPA, depending on your need:
    • Use Spring JDBC for executing plain SQL statements
    • Use Spring Data JPA for more advanced use, e.g. mapping Java classes to tables and Java objects to rows, and take advantages of the Spring Data JPA API.

    1. Add dependency for PostgreSQL JDBC Driver

     org.postgresql postgresql runtime 

    This will use the default version specified by Spring Boot. If you want to explicitly specify a PostgreSQL JDBC version, refer to this page.

    2. Configure Data Source Properties

    Next, you need to specify some database connection information in the Spring Boot application configuration file ( application.properties ) as follows:

    spring.datasource.url=jdbc:postgresql://localhost:5432/shopme spring.datasource.username=postgres spring.datasource.password=password

    Here, the JDBC URL points to a PostgreSQL database server running on localhost. Update the JDBC URL, username and password according to your environment.

    3. Connect to PostgreSQL Database with Spring JDBC

    In the simplest case, you can use Spring JDBC with JdbcTemplate to work with a relational database. So add the following dependency to your Maven project file:

     org.springframework.boot spring-boot-starter-jdbc 

    And the following code example is of a Spring Boot console program uses JdbcTemplate to execute a SQL Insert statement:

    package net.codejava; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.CommandLineRunner; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.jdbc.core.JdbcTemplate; @SpringBootApplication public class SpringJdbcTemplate2PostgreSqlApplication implements CommandLineRunner < @Autowired private JdbcTemplate jdbcTemplate; public static void main(String[] args) < SpringApplication.run(SpringJdbcTemplate2PostgreSqlApplication.class, args); >@Override public void run(String. args) throws Exception < String sql = "INSERT INTO students (name, email) VALUES (" + "'Nam Ha Minh', 'nam@codejava.net')"; int rows = jdbcTemplate.update(sql); if (rows >0) < System.out.println("A new row has been inserted."); >> >

    This program will insert a new row into the students table in a PostgreSQL database, using Spring JDBC which is a thin API built on top of JDBC.

    For details about using Spring JdbcTemplate, I recommend you to read this tutorial.

    4. Connect to PostgreSQL Database with Spring Data JPA

    If you want to map Java classes to tables and Java objects to rows and take advantages of an Object-Relational Mapping (ORM) framework like Hibernate, you can use Spring Data JPA. So declare the following dependency to your project:

     org.springframework.boot spring-boot-starter-data-jpa 

    Besides the JDBC URL, username and password, you can also specify some additional properties as follows:

    spring.jpa.hibernate.ddl-auto=update spring.jpa.show-sql=true spring.jpa.properties.hibernate.format_sql=true spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQL81Dialect

    And you need to code an entity class (a POJO Java class) to map with the corresponding table in the database, as follows:

    package net.codejava; import javax.persistence.*; @Entity @Table(name = "students") public class Student < @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; private String name; private String email; // getters and setters. >

    package net.codejava; import org.springframework.data.jpa.repository.JpaRepository; public interface StudentRepository extends JpaRepository

    @Controller public class StudentController < @Autowired private StudentRepository studentRepo; @GetMapping("/students") public String listAll(Model model) < ListlistStudents = studentRepo.findAll(); model.addAttribute("listStudents", listStudents); return "students"; > >

    I recommend you to follow this article: Understand Spring Data JPA with Simple Example to learn more about Spring Data JPA.

    Those are some code examples for connecting to PostgreSQL database in Spring Boot. As you have seen, Spring Boot greatly simplifies the programming, and you can choose to use Spring JDBC or Spring Data JPA.

    Watch the following video to see the coding in action:

    Other Spring Boot Tutorials:

    • How to create a Spring Boot Web Application (Spring MVC with JSP/ThymeLeaf)
    • Spring Boot CRUD Example with Spring MVC – Spring Data JPA – ThymeLeaf — Hibernate — MySQL
    • Spring Boot Hello World RESTful Web Services Tutorial
    • Spring Boot Thymeleaf Form Handling Tutorial
    • Spring Data JPA Paging and Sorting Examples
    • Spring Boot Error Handling Guide
    • Spring Boot Logging Basics
    • Spring Security Role-based Authorization Tutorial
    • Spring Security Customize Login and Logout
    • How to Get Logged-in User’s Details with Spring Security
    • Spring Security: Prevent User from Going Back to Login Page if Already logged in

    About the Author:

    Nam Ha Minh is certified Java programmer (SCJP and SCWCD). He started programming with Java in the time of Java 1.4 and has been falling in love with Java since then. Make friend with him on Facebook and watch his Java videos you YouTube.

    Add comment

    Comments

    spring.jpa.properties.hibernate.dialect is incorrect, i think it should be
    org.hibernate.dialect.PostgreSQL8Dialect

    Источник

    Введение в Spring Data JDBC

    Для будущих студентов курса «Java Developer. Professional» подготовили перевод полезного материала.

    Spring Data JDBC был анонсирован в 2018 году. Целью было предоставить разработчикам более простую альтернативу JPA, продолжая при этом следовать принципам Spring Data. Подробнее узнать о мотивах, лежащих в основе проекта, вы можете в документации.

    В этой статье я покажу несколько примеров использования Spring Data JDBC. Здесь не будет подробного руководства, но, надеюсь, приведенной информации хватит, чтобы попробовать его самостоятельно. Очень хорошо, если вы уже знакомы со Spring Data JPA. Исходный код вы можете найти в github.

    Для быстрого старта я использовал этот шаблон.

    Предварительная подготовка

    Из зависимостей нам нужны data-jdbc — стартер, flyway для управления схемой и драйвер postgres для подключения к базе данных.

    Далее настраиваем приложение для подключения к базе данных:

    # application.yml spring: application: name: template-app datasource: url: jdbc:postgresql://localhost:5432/demo_app?currentSchema=app username: app_user password: change_me driver-class-name: org.postgresql.Driver

    Маппинг сущностей

    Для этого примера будем использовать следующую таблицу:

    create table book ( id varchar(32) not null, title varchar(255) not null, author varchar(255), isbn varchar(15), published_date date, page_count integer, primary key (id) );

    И соответствующий java-класс (обратите внимание, что @Id импортируется из org.springframework.data.annotation.Id ):

    // Book.java public class Book
    // BookRepositoryTest.java @Test void canSaveBook()

    То увидим ошибку — ERROR: null value in column «id» violates not-null constraint. Это происходит, потому что мы не определили ни способ генерации id ни значение по умолчанию. Поведение Spring Data JDBC в части идентификаторов немного отличается от Spring Data JPA. В нашем примере нужно определить ApplicationListener для BeforeSaveEvent :

    // PersistenceConfig.java @Bean public ApplicationListener idGenerator() < return event -> < var entity = event.getEntity(); if (entity instanceof Book) < ((Book) entity).setId(UUID.randomUUID().toString()); >>; >

    Теперь тест пройдет, потому что поле Id заполняется. Полный список поддерживаемых событий жизненного цикла смотрите в документации.

    Методы запросов

    Одной из особенностей проектов Spring Data является возможность определять методы запросов в репозиториях. Spring Data JDBC использует здесь несколько иной подход. Для демонстрации определим метод запроса в BookRepository :

    Optional findByTitle(String title);

    И если запустим соответствующий тест:

    @Test void canFindBookByTitle()

    Получим ошибку — Caused by: java.lang.IllegalStateException: No query specified on findByTitle . В настоящее время Spring Data JDBC поддерживает только явные запросы, задаваемые через @Query. Напишем sql-запрос для нашего метода:

    @Query("select * from Book b where b.title = :title") Optional findByTitle(@Param("title") String title);

    Тест пройден! Не забывайте об этом при создании репозиториев.

    Примечание переводчика: в Spring Data JDBC 2.0 появилась поддержка генерации запросов по именам методов.

    Связи

    Для работы со связями Spring Data JDBC также использует другой подход. Основное отличие в том, что отсутствует ленивая загрузка. Поэтому если вам не нужна связь в сущности, то просто не добавляйте ее туда. Такой подход основан на одной из концепций предметно-ориентированного проектирования (Domain Driven Design), согласно которой сущности, которые мы загружаем, являются корнями агрегатов, поэтому проектировать надо так, чтобы корни агрегатов тянули за собой загрузку других классов.

    Один-к-одному

    Для связей «один-к-одному» и «один-ко-многим» используется аннотация @MappedCollection . Сначала посмотрим на «один-к-одному». Класс UserAccount будет ссылаться на Address . Вот соответствующий sql:

    create table address ( id varchar(36) not null, city varchar(255), state varchar(255), street varchar(255), zipcode varchar(255), primary key (id) ); create table user_account ( id varchar(36) not null, name varchar(255) not null, email varchar(255) not null, address_id varchar(36), primary key (id), constraint fk_user_account_address_id foreign key (address_id) references address (id) );

    Класс UserAccount выглядит примерно так:

    // UserAccount.java public class UserAccount implements GeneratedId < // . other fields @MappedCollection(idColumn = "id") private Address address; >

    Здесь опущены другие поля, чтобы показать маппинг address . Значение в idColumn — это имя поля идентификатора класса Address . Обратите внимание, что в классе Address нет ссылки на класс UserAccount , поскольку агрегатом является UserAccount . Это продемонстрировано в тесте:

    //UserAccountRepositoryTest.java @Test void canSaveUserWithAddress()

    Один-ко-многим

    Вот sql, который будем использовать для демонстрации связи «один-ко-многим»:

    create table warehouse ( id varchar(36) not null, location varchar(255), primary key (id) ); create table inventory_item ( id varchar(36) not null, name varchar(255), count integer, warehouse varchar(36), primary key (id), constraint fk_inventory_item_warehouse_id foreign key (warehouse) references warehouse (id) );

    В этом примере на складе (warehouse) есть много товаров/объектов (inventoryitems). Поэтому в классе Warehouse мы также будем использовать @MappedCollection для InventoryItem :

    public class Warehouse < // . other fields @MappedCollection SetinventoryItems = new HashSet<>(); public void addInventoryItem(InventoryItem inventoryItem) < var itemWithId = inventoryItem.toBuilder().id(UUID.randomUUID().toString()).build(); this.inventoryItems.add(itemWithId); >> public class InventoryItem

    В этом примере мы устанавливаем поле id во вспомогательном методе addInventoryItem . Можно также определить ApplicationListener для класса Warehouse с обработкой BeforeSaveEvent , в котором установить поле id для всех InventoryItem . Вам не обязательно делать в точности так, как сделано у меня. Посмотрите тесты с демонстрацией некоторых особенностей поведения связи «один-ко-многим». Главное то, что сохранение или удаление экземпляра Warehouse влияет на соответствующие InventoryItem .

    В нашем случае InventoryItem не должен знать о Warehouse . Таким образом, у этого класса есть только те поля, которые описывают его. В JPA принято делать двусторонние связи, но это может быть громоздким и провоцировать ошибки, если вы забудете поддерживать обе стороны связи. Spring Data JDBC способствует созданию только необходимых вам связей, поэтому обратная связь «многие-к-одному» здесь не используется.

    Многие-к-одному и многие-ко-многим

    В рамках этого руководства я не буду вдаваться в подробности о связях «многие-к-одному» или «многие ко многим». Я советую избегать связей «многие-ко-многим» и использовать их только в крайнем случае. Хотя иногда они могут быть неизбежны. Оба этих типа связей реализуются в Spring Data JDBC через ссылки на Id связанных сущностей. Поэтому имейте ввиду, что здесь вам предстоит еще немного потрудиться.

    Заключение

    Если вы использовали Spring Data JPA, то большая часть из того, что я рассказал, должна быть вам знакома. Я уже упоминал ранее, что Spring Data JDBC стремится быть проще, и поэтому отсутствует ленивая загрузка. Помимо этого, отсутствует кеширование, отслеживание «грязных» объектов (dirty tracking) и сессии (session). Если в Spring Data JDBC вы загружаете объект, то он загружается полностью (включая связи) и сохраняется тогда, когда вы сохраняете его в репозиторий. Примеры, которые я показал, очень похожи на свои аналоги в JPA, но помните, что многие концепции Spring Data JPA отсутствуют в Spring Data JDBC.

    В целом мне нравится Spring Data JDBC. Признаю, что это может быть не лучший выбор для всех приложений, однако я бы рекомендовал его попробовать. Как человек, который в прошлом боролся с ленивой загрузкой и dirty tracking, я ценю его простоту. Я думаю, что это хороший выбор для простых предметных областей, которые не требуют большого количества нестандартных запросов.

    На этом пока все, спасибо за чтение! Надеюсь, вы нашли это руководство полезным и оно будет отправной точкой для использования Spring Data JDBC.

    Источник

    Читайте также:  Класс комплексных чисел java
Оцените статью