diff --git a/pom.xml b/pom.xml
index 683e84ec..fc0fcfa1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -18,6 +18,14 @@
+
+
+ mysql
+ mysql-connector-java
+ 8.0.28
+
+
+
diff --git a/src/main/java/mate/academy/Main.java b/src/main/java/mate/academy/Main.java
index 0058fbf9..fe717f89 100644
--- a/src/main/java/mate/academy/Main.java
+++ b/src/main/java/mate/academy/Main.java
@@ -1,7 +1,34 @@
package mate.academy;
+import java.math.BigDecimal;
+import java.util.List;
+import java.util.Optional;
+import mate.academy.dao.BookDao;
+import mate.academy.lib.Injector;
+import mate.academy.model.Book;
+
public class Main {
+ private static final Injector injector = Injector.getInstance("mate.academy");
+
public static void main(String[] args) {
+ BookDao bookDao = (BookDao) injector.getInstance(BookDao.class);
+
+ Book book = new Book("book", BigDecimal.valueOf(100));
+ Book createdBook = bookDao.create(book);
+ System.out.println(createdBook);
+
+ Optional getBookById = bookDao.findById(1L);
+ System.out.println("Book by id " + getBookById);
+
+ book.setTitle("Updated Book");
+ book.setPrice(BigDecimal.valueOf(200));
+ Book updatedBook = bookDao.update(book);
+ System.out.println("Updated Book: " + updatedBook);
+
+ List getAllBook = bookDao.findAll();
+ System.out.println("All Books : " + getAllBook);
+ boolean deleteBook = bookDao.deleteById(3L);
+ System.out.println("Deleted book: " + deleteBook);
}
}
diff --git a/src/main/java/mate/academy/dao/BookDao.java b/src/main/java/mate/academy/dao/BookDao.java
new file mode 100644
index 00000000..d60c063d
--- /dev/null
+++ b/src/main/java/mate/academy/dao/BookDao.java
@@ -0,0 +1,17 @@
+package mate.academy.dao;
+
+import java.util.List;
+import java.util.Optional;
+import mate.academy.model.Book;
+
+public interface BookDao {
+ Book create(Book book);
+
+ Optional findById(Long id);
+
+ List findAll();
+
+ Book update(Book book);
+
+ boolean deleteById(Long id);
+}
diff --git a/src/main/java/mate/academy/dao/impl/BookDaoImpl.java b/src/main/java/mate/academy/dao/impl/BookDaoImpl.java
new file mode 100644
index 00000000..dd79bf86
--- /dev/null
+++ b/src/main/java/mate/academy/dao/impl/BookDaoImpl.java
@@ -0,0 +1,121 @@
+package mate.academy.dao.impl;
+
+import java.math.BigDecimal;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import mate.academy.dao.BookDao;
+import mate.academy.exception.DataProcessingException;
+import mate.academy.lib.Dao;
+import mate.academy.model.Book;
+import mate.academy.util.db.ConnectionUtil;
+
+@Dao
+public class BookDaoImpl implements BookDao {
+ private static final String CANT_CREATE = "Can't store the book to the DB";
+ private static final String CANT_FIND_BY_ID = "Can't find the book with id = ";
+ private static final String CANT_FIND_ALL = "Can't find all books";
+ private static final String CANT_UPDATE = "Can't update the book with id = ";
+ private static final String CANT_DELETE = "Can't delete the book with id = ";
+ private static final String UPDATE_FAILED
+ = "Expected to update at least 1 row, but 0 was updated.";
+ private static final String INSERT_FAILED
+ = "Expected to update at least 1 row, but 0 was updated.";
+
+ @Override
+ public Book create(Book book) {
+ String insertQuery = "INSERT INTO books (title,price) VALUES (?,?);";
+ try (Connection connection = ConnectionUtil.getConnection();
+ PreparedStatement statement = connection.prepareStatement(
+ insertQuery, Statement.RETURN_GENERATED_KEYS)) {
+ statement.setString(1, book.getTitle());
+ statement.setBigDecimal(2, book.getPrice());
+ statement.executeUpdate();
+ ResultSet generatedKey = statement.getGeneratedKeys();
+ if (generatedKey.next()) {
+ Long id = generatedKey.getObject(1, Long.class);
+ book.setId(id);
+ } else {
+ throw new DataProcessingException(INSERT_FAILED);
+ }
+ } catch (SQLException e) {
+ throw new DataProcessingException(CANT_CREATE, e);
+ }
+ return book;
+ }
+
+ @Override
+ public Optional findById(Long id) {
+ String getByIdQuery = "SELECT * FROM books WHERE id = ? AND is_deleted = FALSE";
+ try (Connection connection = ConnectionUtil.getConnection();
+ PreparedStatement statement = connection.prepareStatement(getByIdQuery)) {
+ statement.setLong(1, id);
+ ResultSet resultSet = statement.executeQuery();
+ if (resultSet.next()) {
+ return Optional.of(createBook(resultSet));
+ }
+ } catch (SQLException e) {
+ throw new DataProcessingException(CANT_FIND_BY_ID + id, e);
+ }
+ return Optional.empty();
+ }
+
+ @Override
+ public List findAll() {
+ String getAllQuery = "SELECT * FROM books WHERE is_deleted = FALSE";
+ List books = new ArrayList<>();
+ try (Connection connection = ConnectionUtil.getConnection();
+ PreparedStatement statement = connection.prepareStatement(getAllQuery)) {
+ ResultSet resultSet = statement.executeQuery();
+ while (resultSet.next()) {
+ books.add(createBook(resultSet));
+ }
+ } catch (SQLException e) {
+ throw new DataProcessingException(CANT_FIND_ALL, e);
+ }
+ return books;
+ }
+
+ @Override
+ public Book update(Book book) {
+ String updateQuery = "UPDATE books SET title = ?, price = ? "
+ + "WHERE id = ? AND is_deleted = FALSE";
+ try (Connection connection = ConnectionUtil.getConnection();
+ PreparedStatement statement = connection.prepareStatement(updateQuery)) {
+ statement.setString(1, book.getTitle());
+ statement.setBigDecimal(2, book.getPrice());
+ statement.setLong(3, book.getId());
+ int affectedRows = statement.executeUpdate();
+ if (affectedRows < 1) {
+ throw new DataProcessingException(UPDATE_FAILED);
+ }
+ } catch (SQLException e) {
+ throw new DataProcessingException(CANT_UPDATE + book.getId(), e);
+ }
+ return book;
+ }
+
+ @Override
+ public boolean deleteById(Long id) {
+ String deletedQuery = "UPDATE books SET is_deleted = TRUE WHERE id = ?";
+ try (Connection connection = ConnectionUtil.getConnection();
+ PreparedStatement statement = connection.prepareStatement(deletedQuery)) {
+ statement.setLong(1, id);
+ return statement.executeUpdate() > 0;
+ } catch (SQLException e) {
+ throw new DataProcessingException(CANT_DELETE + id, e);
+ }
+ }
+
+ private Book createBook(ResultSet resultSet) throws SQLException {
+ return new Book(
+ resultSet.getObject("id", Long.class),
+ resultSet.getObject("title", String.class),
+ resultSet.getObject("price", BigDecimal.class));
+ }
+}
diff --git a/src/main/java/mate/academy/exception/DataProcessingException.java b/src/main/java/mate/academy/exception/DataProcessingException.java
new file mode 100644
index 00000000..65af6fdf
--- /dev/null
+++ b/src/main/java/mate/academy/exception/DataProcessingException.java
@@ -0,0 +1,11 @@
+package mate.academy.exception;
+
+public class DataProcessingException extends RuntimeException {
+ public DataProcessingException(String message) {
+ super(message);
+ }
+
+ public DataProcessingException(String message, Throwable exception) {
+ super(message, exception);
+ }
+}
diff --git a/src/main/java/mate/academy/model/Book.java b/src/main/java/mate/academy/model/Book.java
new file mode 100644
index 00000000..2e2e75c8
--- /dev/null
+++ b/src/main/java/mate/academy/model/Book.java
@@ -0,0 +1,53 @@
+package mate.academy.model;
+
+import java.math.BigDecimal;
+
+public class Book {
+ private Long id;
+ private String title;
+ private BigDecimal price;
+
+ public Book() {
+ }
+
+ public Book(String title, BigDecimal price) {
+ this.title = title;
+ this.price = price;
+ }
+
+ public Book(Long id, String title, BigDecimal price) {
+ this.id = id;
+ this.title = title;
+ this.price = price;
+ }
+
+ public Long getId() {
+ return id;
+ }
+
+ public void setId(Long id) {
+ this.id = id;
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ this.title = title;
+ }
+
+ public BigDecimal getPrice() {
+ return price;
+ }
+
+ public void setPrice(BigDecimal price) {
+ this.price = price;
+ }
+
+ @Override
+ public String toString() {
+ return "Book{id=" + id + ", title='" + title
+ + '\'' + ", price=" + price + '}';
+ }
+}
diff --git a/src/main/java/mate/academy/util/db/ConnectionUtil.java b/src/main/java/mate/academy/util/db/ConnectionUtil.java
new file mode 100644
index 00000000..dd4d91be
--- /dev/null
+++ b/src/main/java/mate/academy/util/db/ConnectionUtil.java
@@ -0,0 +1,26 @@
+package mate.academy.util.db;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.Properties;
+
+public class ConnectionUtil {
+ private static final String DB_URL = "jdbc:mysql://localhost:3306/mate";
+ private static final Properties DB_PROPERTIES;
+
+ static {
+ DB_PROPERTIES = new Properties();
+ DB_PROPERTIES.put("user", "root");
+ DB_PROPERTIES.put("password", "12345678");
+ try {
+ Class.forName("com.mysql.cj.jdbc.Driver");
+ } catch (ClassNotFoundException e) {
+ throw new RuntimeException("Can not load JDBC driver", e);
+ }
+ }
+
+ public static Connection getConnection() throws SQLException {
+ return DriverManager.getConnection(DB_URL, DB_PROPERTIES);
+ }
+}
diff --git a/src/main/resources/init_db.sql b/src/main/resources/init_db.sql
new file mode 100644
index 00000000..d76795fe
--- /dev/null
+++ b/src/main/resources/init_db.sql
@@ -0,0 +1,5 @@
+CREATE TABLE books (
+ id BIGINT AUTO_INCREMENT PRIMARY KEY,
+ title VARCHAR(255) NOT NULL,
+ price DECIMAL(6, 2) NOT NULL,
+ is_deleted TINYINT NOT NULL DEFAULT 0);
\ No newline at end of file