Статьи

Установите приложение Spring Boot с PostgreSQL

В этой статье мы рассмотрим шаги по настройке приложения Spring Boot с PostgreSQL. У нас будет простая операция CRUD в базе данных Postgres, представив приложение через Rest API. Мы будем использовать POSTMAN для тестирования приложения.

Настройка Postgres Server

  • Загрузите сервер Postgres по ссылке: https://www.postgresql.org/download/
  • Запустите установщик. Он также спросит пароль для суперпользователя:  postgres
  • Нажмите на pgAdmin4.exe, расположенный в папке PostgreSQL внутри Program Files.

Настройка Spring Boot Application

Необходимое условие:

Установлен ли JDK 1.8?

  • Загрузите пример проекта Spring Boot с https://start.spring.io/
  • Обновите файл pom.xml, как показано ниже:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.1.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.sample</groupId>
<artifactId>postgress</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>postgress</name>
<description>Demo project for Spring Boot</description>

<properties>
<java.version>1.8</java.version>
</properties>

<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

</project>

spring-boot-starter-jdbc артефакт даст все jar jbc связанные с весной банки

org.postgresql.postgresql будет зависеть от драйвера postgres jdbc во время выполнения.

  • Создайте schema.sql в папке ресурсов. Таблица сотрудника будет создана при запуске сервера. Это можно игнорировать, если вы не хотите, чтобы исходная база данных была настроена во время запуска сервера. Как правило, для создания готового к работе приложения этот шаг можно игнорировать, поскольку таблицы будут создаваться с помощью сценария непосредственно в БД.
CREATE TABLE employee
(
 employeeName varchar(100) NOT NULL,
  employeeId varchar(11) NOT NULL ,
 employeeAddress varchar(100) DEFAULT NULL,
 employeeEmail varchar(100) DEFAULT NULL,
 PRIMARY KEY (employeeId)
);
  • Создайте data.sql в папке ресурсов для загрузки первого набора сотрудников во время запуска. Иначе можно пропустить:

insert into employee(employeeId, employeeName , employeeAddress,employeeEmail) values('1','Jack','USA','jack@gmail.com');

  • Изменения в application.properties для настройки источника данных с URL, именем пользователя и паролем БД Postgres. 5432 порт по умолчанию Postgres. Hibernate автоматически выберет postgressSQLDialect.
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect
spring.jpa.hibernate.ddl-auto=none
spring.jpa.hibernate.show-sql=true
spring.datasource.url=jdbc:postgresql://localhost:5432/postgres
spring.datasource.username=postgres
spring.datasource.password=admin


spring.datasource.initialization-mode=always
spring.datasource.initialize=true
spring.datasource.schema=classpath:/schema.sql
spring.datasource.continue-on-error=true

spring.jpa.hibernate.ddl-autoотключит автоматическое создание таблиц в спящем режиме из объектов-сущностей. Обычно Hibernate запускает его, если определен объект. Но мы будем использовать собственный SQL-запрос с JdbcTemplate, поэтому мы можем отключить это, поскольку не будем создавать Entity.

spring.datasource.initialization-modeпомечен как всегда, поскольку мы хотим, чтобы инициализация базы данных происходила при каждом запуске. Это необязательно и сделано для этой цели.

spring.datasource.initialize=true отметит инициализацию как истинную.

spring.datasource.continue-on-error=true продолжит запуск приложения, несмотря на любые ошибки при инициализации данных.

spring.datasource.schema путь к схеме, который необходимо инициализировать.

spring.datasource.urlURL БД Postgres. Это может быть и удаленная БД.

spring.datasource.username имя пользователя для базы данных.

spring.datasource.password пароль для базы данных.

  • Создайте интерфейс dao и реализацию dao.
package com.sample.postgress.dao;

import java.util.List;

import com.sample.postgress.entity.Employee;

public interface EmployeeDao {

List<Employee> findAll();

void insertEmployee(Employee emp);

void updateEmployee(Employee emp);

void executeUpdateEmployee(Employee emp);

public void deleteEmployee(Employee emp);
}
package com.sample.postgress.dao;

import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.dao.DataAccessException;
import org.springframework.jdbc.core.PreparedStatementCallback;
import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.core.namedparam.SqlParameterSource;
import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import org.springframework.stereotype.Repository;

import com.sample.postgress.entity.Employee;
import com.sample.postgress.mapper.EmployeeRowMapper;
@Repository
public class EmployeeDaoImpl implements EmployeeDao{

public EmployeeDaoImpl(NamedParameterJdbcTemplate template) {  
        this.template = template;  
}  
NamedParameterJdbcTemplate template;  

@Override
public List<Employee> findAll() {
return template.query("select * from employee", new EmployeeRowMapper());
}
@Override
public void insertEmployee(Employee emp) {
 final String sql = "insert into employee(employeeId, employeeName , employeeAddress,employeeEmail) values(:employeeId,:employeeName,:employeeEmail,:employeeAddress)";

        KeyHolder holder = new GeneratedKeyHolder();
        SqlParameterSource param = new MapSqlParameterSource()
.addValue("employeeId", emp.getEmployeeId())
.addValue("employeeName", emp.getEmployeeName())
.addValue("employeeEmail", emp.getEmployeeEmail())
.addValue("employeeAddress", emp.getEmployeeAddress());
        template.update(sql,param, holder);

}

@Override
public void updateEmployee(Employee emp) {
 final String sql = "update employee set employeeName=:employeeName, employeeAddress=:employeeAddress, employeeEmail=:employeeEmail where employeeId=:employeeId";

        KeyHolder holder = new GeneratedKeyHolder();
        SqlParameterSource param = new MapSqlParameterSource()
.addValue("employeeId", emp.getEmployeeId())
.addValue("employeeName", emp.getEmployeeName())
.addValue("employeeEmail", emp.getEmployeeEmail())
.addValue("employeeAddress", emp.getEmployeeAddress());
        template.update(sql,param, holder);

}

@Override
public void executeUpdateEmployee(Employee emp) {
 final String sql = "update employee set employeeName=:employeeName, employeeAddress=:employeeAddress, employeeEmail=:employeeEmail where employeeId=:employeeId";


 Map<String,Object> map=new HashMap<String,Object>();  
 map.put("employeeId", emp.getEmployeeId());
 map.put("employeeName", emp.getEmployeeName());
 map.put("employeeEmail", emp.getEmployeeEmail());
 map.put("employeeAddress", emp.getEmployeeAddress());

 template.execute(sql,map,new PreparedStatementCallback<Object>() {  
    @Override  
    public Object doInPreparedStatement(PreparedStatement ps)  
            throws SQLException, DataAccessException {  
        return ps.executeUpdate();  
    }  
});  


}

@Override
public void deleteEmployee(Employee emp) {
 final String sql = "delete from employee where employeeId=:employeeId";


 Map<String,Object> map=new HashMap<String,Object>();  
 map.put("employeeId", emp.getEmployeeId());

 template.execute(sql,map,new PreparedStatementCallback<Object>() {  
    @Override  
    public Object doInPreparedStatement(PreparedStatement ps)  
            throws SQLException, DataAccessException {  
        return ps.executeUpdate();  
    }  
});  


}

}
  • findAll () извлекает всех сотрудников, а затем сопоставляет набор результатов с объектом Employee, используя RowMapper, описанный ниже.

  • insertEmployee () вставит сотрудника, используя, template.update(sql,param, holder) где param — SqlParameterSource, который будет динамически отображать значения в запросе, отмеченном двоеточием. GeneratedKeyHolder вернет автоматически сгенерированное значение при вставке данных.

  • executeUpdateEmployee () обновит сотрудника, используя template.execute

 template.execute(sql,map,new PreparedStatementCallback<Object>() {  
    @Override  
    public Object doInPreparedStatement(PreparedStatement ps)  
            throws SQLException, DataAccessException {  
        return ps.executeUpdate();  
    }  
}); 
  • EmployeeRowMapper для сопоставления результирующего набора, полученного из запроса выбора, с POJO.
package com.sample.postgress.mapper;

import java.sql.ResultSet;
import java.sql.SQLException;

import org.springframework.jdbc.core.RowMapper;

import com.sample.postgress.entity.Employee;

public class EmployeeRowMapper implements RowMapper<Employee> {

@Override
public Employee mapRow(ResultSet rs, int arg1) throws SQLException {
Employee emp = new Employee();
emp.setEmployeeId(rs.getString("employeeId"));
emp.setEmployeeName(rs.getString("employeeName"));
emp.setEmployeeEmail(rs.getString("employeeEmail"));

        return emp;
}


}
  • Вы можете создать контроллер и класс обслуживания следующим образом:
package com.sample.postgress.controller;

import java.util.List;

import javax.annotation.Resource;

import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.sample.postgress.entity.Employee;
import com.sample.postgress.service.EmployeeService;

@RestController
@RequestMapping("/postgressApp")
public class ApplicationController {

@Resource 
EmployeeService employeeService;

@GetMapping(value = "/employeeList")
public List<Employee> getEmployees() {
return employeeService.findAll();

}

@PostMapping(value = "/createEmp")
public void createEmployee(@RequestBody Employee emp) {
 employeeService.insertEmployee(emp);

}
@PutMapping(value = "/updateEmp")
public void updateEmployee(@RequestBody Employee emp) {
 employeeService.updateEmployee(emp);

}
@PutMapping(value = "/executeUpdateEmp")
public void executeUpdateEmployee(@RequestBody Employee emp) {
 employeeService.executeUpdateEmployee(emp);

}

@DeleteMapping(value = "/deleteEmpById")
public void deleteEmployee(@RequestBody Employee emp) {
 employeeService.deleteEmployee(emp);

}


}

Теперь давайте использовать POSTMAN для проверки изменений:

Тест 1: Получить список сотрудников

HTTP: // локальный: 8080 / postgressApp / employeeList

Название изображения

Тест 2: Создать сотрудника

HTTP: // локальный: 8080 / postgressApp / createEmp

Название изображения

Мы видим запись, вставленную с Джонсом.

Название изображения

Тест 3: Обновление сотрудника

HTTP: // локальный: 8080 / postgressApp / executeUpdateEmp

Название изображения

Название изображения

Тест 4: Удалить сотрудника

HTTP: // локальный: 8080 / postgressApp / deleteEmpById

Название изображения

Название изображения

Заключение

Мы узнали, как настроить приложение Spring Boot с Postgres и как выполнить операцию CRUD. Вы найдете полный код здесь

Удачного кодирования!