Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/iksergey/spring-boot-todo-mastery
🔥 🚀 Экспресс-погружение в Spring Boot
https://github.com/iksergey/spring-boot-todo-mastery
Last synced: 7 days ago
JSON representation
🔥 🚀 Экспресс-погружение в Spring Boot
- Host: GitHub
- URL: https://github.com/iksergey/spring-boot-todo-mastery
- Owner: iksergey
- Created: 2024-06-27T23:34:12.000Z (5 months ago)
- Default Branch: main
- Last Pushed: 2024-06-28T00:00:55.000Z (5 months ago)
- Last Synced: 2024-06-28T01:31:03.753Z (5 months ago)
- Language: Java
- Size: 18.6 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: readme.md
Awesome Lists containing this project
README
# Прежде чем начать
## Поддержите проект звездочкой на GitHub!
Если вам понравился проект, не забудьте поставить ему звездочку на GitHub. Это простое действие имеет огромное значение для меня.
### Как поставить звездочку?
Просто нажмите на кнопку "Star" в верхнем правом углу репозитория на GitHub. Это займет всего секунду, но принесет нам море позитива и мотивации! 🙏🏼
# Начало проекта
## 1. Настройка проекта
1. Перейдите на сайт Spring Initializr (https://start.spring.io/).
2. Выберите похожие параметры:
Project: `Maven`
Language: `Java`Spring Boot: `3.3.1`
Group: `ru.ksergey`
Artifact: `todolist`
Name: `todolist`
Description: `ToDo List Project for Spring Boot`
Packaging: `Jar`
Java: `22`3. Добавьте следующие зависимости:
Dependencies- MySQL Driver SQL
_MySQL JDBC driver._- Spring Web WEB
_Build web, including RESTful, applications using Spring MVC. Uses Apache Tomcat as the default embedded container._- JDBC API SQL
_Database Connectivity API that defines how a client may connect and query a database._**Вариативно**
- Lombok DEVELOPER TOOLS
_Java annotation library which helps to reduce boilerplate code._
Либо руками через `pom.xml` [projectlombok](https://mvnrepository.com/artifact/org.projectlombok/lombok)4. Нажмите "Generate" и распакуйте полученный ZIP-файл.
## 2. Настройка базы данных
[Если разворачиваете в Doker](https://t.me/iksergeyru/90)
```bash
docker run --name mysql-container -p 3306:3306 -e MYSQL_ROOT_PASSWORD=12345678 -d mysql
```1. Создайте базу данных MySQL:
```sql
DROP DATABASE IF EXISTS todolist_db;
CREATE DATABASE IF NOT EXISTS todolist_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;USE todolist_db;
```2. Создайте таблицу
```sql
CREATE TABLE todo_items (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(255) NOT NULL,
description TEXT,
status ENUM('PENDING', 'IN_PROGRESS', 'COMPLETED') DEFAULT 'PENDING',
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
```3. Наполните, при необходимости
```sql
INSERT INTO todo_items (title, description, status, created_at) VALUES
('Завершить проект по Spring Boot', 'Реализовать все основные функции получения одной записи и обновления имеющейся', 'IN_PROGRESS', NOW()),
('Разобраться с REST API', 'Изучить принципы RESTful архитектуры и применить их в проекте', 'IN_PROGRESS', NOW() - INTERVAL 1 DAY),
('Подготовиться к собеседованию', 'Повторить алгоритмы и структуры данных, подготовить вопросы для работодателя', 'PENDING', NOW()),
('Прочитать книгу "Чистый код"', 'Прочитать первые 5 глав и сделать заметки', 'IN_PROGRESS', NOW() - INTERVAL 1 DAY),
('Ознакомиться со Spring Data JPA', 'Разобраться с основами ORM, написать репозитории и сущности', 'PENDING', NOW());
```4. Выборка всех записей
```sql
SELECT * FROM todo_items;
```5. Отредактируйте файл `src/main/resources/application.properties`:
```properties
spring.application.name=todolist
server.servlet.encoding.charset=UTF-8
server.servlet.encoding.enabled=true
server.servlet.encoding.force=truespring.datasource.url=jdbc:mysql://localhost:3306/todolist_db?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC
spring.datasource.username=your_username
spring.datasource.password=your_password
```## 3. Создание модели
Создайте класс `TodoItem` в пакете `ru.ksergey.todolist.model`:
```java
package ru.ksergey.todolist.model;import java.time.LocalDateTime;
public class TodoItem {
private Long id;
private String title;
private String description;
private TodoStatus status;
private LocalDateTime createdAt;public enum TodoStatus {
PENDING, IN_PROGRESS, COMPLETED
}// Конструкторы, геттеры и сеттеры
}
```## 4. Создание DAO (Data Access Object)
Создайте интерфейс `TodoItemDao` и его реализацию `TodoItemDaoImpl` в пакете `ru.ksergey.todolist.dao`:
```java
package ru.ksergey.todolist.dao;import ru.ksergey.todolist.model.TodoItem;
import java.util.List;public interface TodoItemDao {
List getAllTodoItems();
TodoItem createTodoItem(TodoItem todoItem);
}```
```java
package ru.ksergey.todolist.dao;import org.springframework.jdbc.support.GeneratedKeyHolder;
import org.springframework.jdbc.support.KeyHolder;
import ru.ksergey.todolist.model.TodoItem;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;import java.sql.*;
import java.util.List;import java.sql.ResultSet;
import java.util.Objects;@Repository
public class TodoItemDaoImpl implements TodoItemDao {@Autowired
private JdbcTemplate jdbcTemplate;private final RowMapper todoItemRowMapper = (ResultSet rs, int rowNum) -> {
TodoItem todoItem = new TodoItem();
todoItem.setId(rs.getLong("id"));
todoItem.setTitle(rs.getString("title"));
todoItem.setDescription(rs.getString("description"));
todoItem.setStatus(TodoItem.TodoStatus.valueOf(rs.getString("status")));
todoItem.setCreatedAt(rs.getTimestamp("created_at").toLocalDateTime());
return todoItem;
};@Override
public List getAllTodoItems() {
String sql = "SELECT * FROM todo_items";
return jdbcTemplate.query(sql, todoItemRowMapper);
}@Override
public TodoItem createTodoItem(TodoItem todoItem) {
String sql = "INSERT INTO todo_items (title, description, status) VALUES (?, ?, ?)";
KeyHolder keyHolder = new GeneratedKeyHolder();jdbcTemplate.update(connection -> {
PreparedStatement ps = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
ps.setString(1, todoItem.getTitle());
ps.setString(2, todoItem.getDescription());
ps.setString(3, todoItem.getStatus().name());
return ps;
}, keyHolder);Long id = Objects.requireNonNull(keyHolder.getKey()).longValue();
todoItem.setId(id);String selectSql = "SELECT * FROM todo_items WHERE id = ?";
return jdbcTemplate.queryForObject(selectSql, todoItemRowMapper, id);
}
}
```## 5. Создание контроллера
Создайте класс `TodoItemController` в пакете `ru.ksergey.todolist.controller`:
```java
package ru.ksergey.todolist.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import ru.ksergey.todolist.dao.TodoItemDao;
import ru.ksergey.todolist.model.TodoItem;
import java.util.List;
@RestController
@RequestMapping("/api/todo")
public class TodoItemController {
@Autowired
private TodoItemDao todoItemDao;
@GetMapping("items")
public List getAllTodoItems() {
return todoItemDao.getAllTodoItems();
}
@PostMapping
public TodoItem createTodoItem(@RequestBody TodoItem todoItem) {
return todoItemDao.createTodoItem(todoItem);
}
}
```## 6. Запуск приложения
1. Запустите приложение, выполнив метод `main` в классе `TodolistApplication`.
2. Приложение будет доступно по адресу `http://localhost:8080`.
3. GET-запрос на получение всех записей http://localhost:8080/api/todo/items
4. POST-запрос на добавление записи http://localhost:8080/api/todo/Модель
```json
{
"title": "Тестовые запись",
"description": "Тестовое описание",
"status": "IN_PROGRESS",
"createdAt": "2024-06-28T03:48:12"
}
```## 7. Postman
Для выполнения POST-запроса можно воспользоваться [postman](https://www.postman.com)
1. Скачайте и установите
2. Импортируйте коллекцию `java-todo.postman_collection.json`
3. Выполните POST-запрос `add item`# Техническое задание
Есть всё получилось можете потренироваться и доработать проект
### Расширение функциональности TodoItemController
Цель: Добавить в существующий TodoItemController методы для получения одной записи по ID и обновления существующей записи.
Задачи:
1. Реализация метода получения TodoItem по ID:
- Создать новый метод в контроллере с названием `getTodoItemById`.
- Использовать аннотацию @GetMapping с путём "/{id}".
- Метод должен принимать параметр Long id с аннотацией @PathVariable.
- Реализовать логику получения TodoItem из базы данных по указанному ID.
- Вернуть найденный TodoItem. Если запись не найдена, выбросить исключение.2. Реализация метода обновления TodoItem:
- Создать новый метод в контроллере с названием `updateTodoItem`.
- Использовать аннотацию @PutMapping с путём "/{id}".
- Метод должен принимать два параметра:
* Long id с аннотацией @PathVariable
* TodoItem todoItem с аннотацией @RequestBody
- Реализовать логику обновления существующей записи в базе данных.
- Вернуть обновленный TodoItem. Если запись не найдена, выбросить исключение.3. Обновление интерфейса TodoItemDao:
- Добавить методы `getTodoItemById` и `updateTodoItem` в интерфейс.4. Реализация новых методов в TodoItemDaoImpl:
- Реализовать логику получения записи по ID в методе `getTodoItemById`.
- Реализовать логику обновления записи в методе `updateTodoItem`.5. Обработка ошибок:
- Создать пользовательское исключение, например, `TodoItemNotFoundException`.
- Реализовать глобальный обработчик исключений для корректной обработки ошибок.Требования к реализации:
- Использовать Spring аннотации для маппинга HTTP-запросов.
- Обеспечить корректную обработку случаев, когда запись не найдена.
- Использовать DTO (Data Transfer Object) при необходимости для разделения логики представления и бизнес-логики.
- Следовать принципам RESTful API при проектировании эндпоинтов.Ожидаемый результат:
- Работающие эндпоинты для получения TodoItem по ID и обновления существующего TodoItem.