diff --git a/pom.xml b/pom.xml
index 969b5f3e..1466d4de 100644
--- a/pom.xml
+++ b/pom.xml
@@ -13,5 +13,12 @@
17
UTF-8
+
+
+ mysql
+ mysql-connector-java
+ 8.0.24
+
+
\ No newline at end of file
diff --git a/src/main/java/mate/academy/Main.java b/src/main/java/mate/academy/Main.java
index 0058fbf9..41df75ba 100644
--- a/src/main/java/mate/academy/Main.java
+++ b/src/main/java/mate/academy/Main.java
@@ -1,7 +1,29 @@
package mate.academy;
+import mate.academy.dao.BookDao;
+import mate.academy.lib.Injector;
+import mate.academy.model.Book;
+
+import java.math.BigDecimal;
+
public class Main {
+ private static Injector injector = Injector.getInstance("mate.academy");
public static void main(String[] args) {
-
+ BookDao bookDao = (BookDao) injector.getInstance(BookDao.class);
+ Book firstBook = new Book();
+ firstBook.setTitle("Harry Potter");
+ firstBook.setPrice(BigDecimal.valueOf(100));
+ firstBook = bookDao.create(firstBook);
+ Book secondBook = new Book();
+ secondBook.setTitle("Witcher");
+ secondBook.setPrice(BigDecimal.valueOf(120));
+ secondBook = bookDao.create(secondBook);
+ System.out.println(bookDao.findById(firstBook.getId()));
+ System.out.println(bookDao.findById(secondBook.getId()));
+ System.out.println(bookDao.findAll());
+ System.out.println(bookDao.deleteById(firstBook.getId()));
+ secondBook.setPrice(BigDecimal.valueOf(140));
+ bookDao.update(secondBook);
+ System.out.println(bookDao.findAll());
}
}
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..5c3db0dd
--- /dev/null
+++ b/src/main/java/mate/academy/dao/BookDao.java
@@ -0,0 +1,17 @@
+package mate.academy.dao;
+
+import mate.academy.model.Book;
+import java.util.List;
+import java.util.Optional;
+
+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..aa4351db
--- /dev/null
+++ b/src/main/java/mate/academy/dao/impl/BookDaoImpl.java
@@ -0,0 +1,119 @@
+package mate.academy.dao.impl;
+
+import mate.academy.dao.BookDao;
+import mate.academy.exception.DataProcessingException;
+import mate.academy.lib.Dao;
+import mate.academy.model.Book;
+import mate.academy.util.ConnectionUtil;
+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;
+
+@Dao
+public class BookDaoImpl implements BookDao {
+ @Override
+ public Book create(Book book) {
+ String createBookQuery = "INSERT INTO books (title, price) VALUES (?, ?);";
+ try (Connection connection = ConnectionUtil.getConnection();
+ PreparedStatement createBookStatement =
+ connection.prepareStatement(createBookQuery,
+ Statement.RETURN_GENERATED_KEYS)) {
+ createBookStatement.setString(1, book.getTitle());
+ createBookStatement.setBigDecimal(2, book.getPrice());
+ int insertedRows = createBookStatement.executeUpdate();
+ if (insertedRows < 1) {
+ throw new DataProcessingException("Expected to insert at least 1 row," +
+ " but nothing was inserted by adding book: " + book);
+ }
+ ResultSet generatedKeys = createBookStatement.getGeneratedKeys();
+ if (generatedKeys.next()) {
+ Long id = generatedKeys.getObject(1, Long.class);
+ book.setId(id);
+ }
+ return book;
+ } catch (SQLException e) {
+ throw new DataProcessingException("Can t insert the book in db: " + book, e);
+ }
+ }
+
+ @Override
+ public Optional findById(Long id) {
+ String getByIdQuery = "SELECT * FROM books WHERE id = ? AND is_deleted = FALSE;";
+ try (Connection connection = ConnectionUtil.getConnection();
+ PreparedStatement getByIdStatement =
+ connection.prepareStatement(getByIdQuery)) {
+ getByIdStatement.setLong(1, id);
+ ResultSet resultSet = getByIdStatement.executeQuery();
+ Book book = null;
+ if (resultSet.next()) {
+ book = parseBookFromResultSet(resultSet);
+ }
+ return Optional.ofNullable(book);
+ } catch (SQLException e) {
+ throw new DataProcessingException("Can't find book by id: " + id, e);
+ }
+ }
+
+ @Override
+ public List findAll() {
+ String getAllQuery = "SELECT * FROM books WHERE is_deleted = FALSE;";
+ try (Connection connection = ConnectionUtil.getConnection();
+ PreparedStatement getAllStatement =
+ connection.prepareStatement(getAllQuery)) {
+ ResultSet resultSet = getAllStatement.executeQuery();
+ List booksList = new ArrayList<>();
+ while (resultSet.next()) {
+ booksList.add(parseBookFromResultSet(resultSet));
+ }
+ return booksList;
+ } catch (SQLException e) {
+ throw new DataProcessingException("Can't get all books from db", e);
+ }
+ }
+
+ @Override
+ public Book update(Book book) {
+ String updateBookQuery = "UPDATE books SET title = ?, price = ? WHERE is_deleted = FALSE;";
+ try (Connection connection = ConnectionUtil.getConnection();
+ PreparedStatement updateBookStatement =
+ connection.prepareStatement(updateBookQuery)) {
+ updateBookStatement.setString(1, book.getTitle());
+ updateBookStatement.setBigDecimal(2, book.getPrice());
+ int updatedRows = updateBookStatement.executeUpdate();
+ if (updatedRows < 1) {
+ throw new DataProcessingException("Rows were not updated for book" + book);
+ }
+ return book;
+ } catch (SQLException e) {
+ throw new DataProcessingException("Can't update book: " + book, e);
+ }
+ }
+
+ @Override
+ public boolean deleteById(Long id) {
+ String deleteByIdQuery = "UPDATE books SET is_deleted = TRUE WHERE id = ?;";
+ try (Connection connection = ConnectionUtil.getConnection();
+ PreparedStatement deleteByIdStatement =
+ connection.prepareStatement(deleteByIdQuery)) {
+ deleteByIdStatement.setLong(1, id);
+ int deletedRows = deleteByIdStatement.executeUpdate();
+ return deletedRows > 0;
+ } catch (SQLException e) {
+ throw new DataProcessingException("Can't delete book by id: " + id, e);
+ }
+ }
+
+ private Book parseBookFromResultSet(ResultSet resultSet) throws SQLException {
+ Book book = new Book();
+ book.setId(resultSet.getObject("id", Long.class));
+ book.setTitle(resultSet.getString("title"));
+ book.setPrice(resultSet.getObject("price", BigDecimal.class));
+ return book;
+ }
+}
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..c6f86d61
--- /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 cause) {
+ super(message, cause);
+ }
+}
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..b43614b9
--- /dev/null
+++ b/src/main/java/mate/academy/model/Book.java
@@ -0,0 +1,72 @@
+package mate.academy.model;
+
+import java.math.BigDecimal;
+import java.util.Objects;
+
+public class Book {
+ private Long id;
+ private String title;
+ private BigDecimal price;
+
+ public Book() {
+
+ }
+
+ public Book(Long id, String title, BigDecimal price) {
+ this.id = id;
+ this.price = price;
+ this.title = title;
+ }
+
+ 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 int hashCode() {
+ return Objects.hash(id, title, price);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null || getClass() != obj.getClass()) {
+ return false;
+ }
+ Book book = (Book) obj;
+ return Objects.equals(id, book.id)
+ && Objects.equals(title, book.title)
+ && Objects.equals(price, book.price);
+ }
+
+ @Override
+ public String toString() {
+ return "Car{"
+ + "id=" + id
+ + ", title='" + title + '\''
+ + ", price='" + price + '\''
+ + '}';
+ }
+}
diff --git a/src/main/java/mate/academy/util/ConnectionUtil.java b/src/main/java/mate/academy/util/ConnectionUtil.java
new file mode 100644
index 00000000..9d3c7785
--- /dev/null
+++ b/src/main/java/mate/academy/util/ConnectionUtil.java
@@ -0,0 +1,32 @@
+package mate.academy.util;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.Properties;
+
+public class ConnectionUtil {
+ private static final String URL = "jdbc:mysql://localhost:3306/library_db";
+ private static final String USERNAME = "root";
+ private static final String PASSWORD = "Ghfnfnbg123";
+ private static final String JDBC_DRIVER = "com.mysql.cj.jdbc.Driver";
+
+ static {
+ try {
+ Class.forName(JDBC_DRIVER);
+ } catch (ClassNotFoundException e) {
+ throw new RuntimeException("Can't find SQL Driver", e);
+ }
+ }
+
+ public static Connection getConnection() {
+ Properties dbProperties = new Properties();
+ dbProperties.setProperty("user", USERNAME);
+ dbProperties.setProperty("password", PASSWORD);
+ try {
+ return DriverManager.getConnection(URL, dbProperties);
+ } catch (SQLException e) {
+ throw new RuntimeException("Can't create connection to DB ", e);
+ }
+ }
+}
diff --git a/src/main/java/resources/init_db.sql b/src/main/java/resources/init_db.sql
new file mode 100644
index 00000000..f3be32d7
--- /dev/null
+++ b/src/main/java/resources/init_db.sql
@@ -0,0 +1,8 @@
+CREATE DATABASE `library_db` /*!40100 DEFAULT CHARACTER SET utf8mb3 */ /*!80016 DEFAULT ENCRYPTION='N' */;
+CREATE TABLE `book` (
+ `id` bigint NOT NULL AUTO_INCREMENT,
+ `title` varchar(255) DEFAULT NULL,
+ `price` decimal(10,0) DEFAULT NULL,
+ `is_deleted` tinyint NOT NULL DEFAULT '0',
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;