diff --git a/pom.xml b/pom.xml
index 683e84ec..9e45dc54 100644
--- a/pom.xml
+++ b/pom.xml
@@ -18,6 +18,14 @@
+
+
+ com.mysql
+ mysql-connector-j
+ 8.4.0
+
+
+
diff --git a/src/main/java/mate/academy/Main.java b/src/main/java/mate/academy/Main.java
index 0058fbf9..376b038b 100644
--- a/src/main/java/mate/academy/Main.java
+++ b/src/main/java/mate/academy/Main.java
@@ -1,7 +1,65 @@
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");
+ private static Book bookBeauty = new Book();
+ private static final Book bookPeace = new Book();
+ private static final Book bookFun = new Book();
+ private static BookDao bookDao;
+
+ static {
+ bookBeauty.setTitle("Beauty");
+ bookBeauty.setPrice(BigDecimal.valueOf(20.99));
+ bookPeace.setTitle("Peace");
+ bookPeace.setPrice(BigDecimal.valueOf(100.00));
+ bookFun.setTitle("Fun");
+ bookFun.setPrice(BigDecimal.valueOf(15.80));
+ }
+
public static void main(String[] args) {
+ bookDao = (BookDao) injector.getInstance(BookDao.class);
+ Book bookBeautyWithId = createBook(bookBeauty);
+ System.out.println("Added new book to DB: " + bookBeautyWithId);
+ System.out.println("Added new book to DB: " + createBook(bookPeace));
+ System.out.println("Added new book to DB: " + createBook(bookFun));
+ Long bookBeautyId = bookBeautyWithId.getId();
+ Optional bookById = bookDao.findById(bookBeautyId);
+ System.out.println("Found book by id: " + bookBeautyId
+ + ". The book is: " + bookById);
+ List allBooks = bookDao.findAll();
+ System.out.println("List of all books: ");
+ outputAllBooksList(allBooks);
+ bookBeautyWithId.setPrice(BigDecimal.valueOf(25.00));
+ bookBeautyWithId.setTitle("BEAUTY");
+ bookDao.update(bookBeautyWithId);
+ System.out.println("Before updating, title: Beauty; price: 20.99. "
+ + "After updating should be: title: BEAUTY, price: 25.00. "
+ + System.lineSeparator() + "Updated book is: "
+ + bookDao.findById(bookBeautyId));
+ Long bookFunId = bookFun.getId();
+ bookDao.deleteById(bookFunId);
+ System.out.println("Deleted book with title \"Fun\", id: " + bookFunId);
+ List booksAfterDelete = bookDao.findAll();
+ System.out.println("List of all books after delete: ");
+ outputAllBooksList(booksAfterDelete);
+ }
+
+ private static Book createBook(Book book) {
+ return bookDao.create(bookBeauty);
+ }
+ private static void outputAllBooksList(List books) {
+ if (!books.isEmpty()) {
+ for (Book book : books) {
+ System.out.println(book);
+ }
+ }
}
}
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..23e8097c
--- /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/BookDaoImpl.java b/src/main/java/mate/academy/dao/BookDaoImpl.java
new file mode 100644
index 00000000..6ec9724f
--- /dev/null
+++ b/src/main/java/mate/academy/dao/BookDaoImpl.java
@@ -0,0 +1,116 @@
+package mate.academy.dao;
+
+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.exception.DataProcessingException;
+import mate.academy.lib.Dao;
+import mate.academy.model.Book;
+import mate.academy.service.ConnectionUtil;
+
+@Dao
+public class BookDaoImpl implements BookDao {
+ @Override
+ public Book create(Book book) {
+ String sql = "INSERT INTO books(title, price) VALUES(?, ?)";
+ try (Connection connection = ConnectionUtil.create();
+ PreparedStatement statement
+ = connection.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS)) {
+ statement.setString(1, book.getTitle());
+ statement.setObject(2, book.getPrice());
+ int affectedRows = statement.executeUpdate();
+ checkNumberOfAffectedRows(affectedRows);
+ ResultSet generatedKeys = statement.getGeneratedKeys();
+ if (generatedKeys.next()) {
+ Long id = generatedKeys.getObject(1, Long.class);
+ book.setId(id);
+ }
+ } catch (SQLException e) {
+ throw new DataProcessingException("Can't create new book in DB: "
+ + book, e);
+ }
+ return book;
+ }
+
+ @Override
+ public Optional findById(Long id) {
+ String sql = "SELECT * FROM books WHERE id = ?";
+ try (Connection connection = ConnectionUtil.create();
+ PreparedStatement statement = connection.prepareStatement(sql)) {
+ statement.setLong(1, id);
+ ResultSet resultSet = statement.executeQuery();
+ if (resultSet.next()) {
+ return Optional.of(mapResultSetToBook(resultSet));
+ }
+ } catch (SQLException e) {
+ throw new DataProcessingException("Can't find book by id = " + id, e);
+ }
+ return Optional.empty();
+ }
+
+ @Override
+ public List findAll() {
+ String sql = "SELECT * FROM books";
+ List allBooks = new ArrayList<>();
+ try (Connection connection = ConnectionUtil.create();
+ PreparedStatement statement = connection.prepareStatement(sql)) {
+ ResultSet resultSet = statement.executeQuery();
+ while (resultSet.next()) {
+ allBooks.add(mapResultSetToBook(resultSet));
+ }
+ } catch (SQLException e) {
+ throw new DataProcessingException("Can't create List of all books in DB; ", e);
+ }
+ return allBooks;
+ }
+
+ @Override
+ public Book update(Book book) {
+ String sql = "UPDATE books SET title = ?, price = ? WHERE id = ?";
+ try (Connection connection = ConnectionUtil.create();
+ PreparedStatement statement = connection.prepareStatement(sql)) {
+ statement.setString(1, book.getTitle());
+ statement.setBigDecimal(2, book.getPrice());
+ statement.setLong(3, book.getId());
+ int affectedRows = statement.executeUpdate();
+ checkNumberOfAffectedRows(affectedRows);
+ } catch (SQLException e) {
+ throw new DataProcessingException("Can't update info about book: "
+ + book, e);
+ }
+ return book;
+ }
+
+ @Override
+ public boolean deleteById(Long id) {
+ String sql = "DELETE FROM books WHERE id = ?";
+ try (Connection connection = ConnectionUtil.create();
+ PreparedStatement statement = connection.prepareStatement(sql)) {
+ statement.setLong(1, id);
+ int affectedRows = statement.executeUpdate();
+ return affectedRows > 0;
+ } catch (SQLException e) {
+ throw new DataProcessingException("Can't delete book with id = "
+ + id, e);
+ }
+ }
+
+ private Book mapResultSetToBook(ResultSet resultSet) throws SQLException {
+ Book book = new Book();
+ book.setId(resultSet.getObject("id", Long.class));
+ book.setTitle(resultSet.getString("title"));
+ book.setPrice(resultSet.getBigDecimal("price"));
+ return book;
+ }
+
+ private void checkNumberOfAffectedRows(int affectedRows) {
+ if (affectedRows < 1) {
+ throw new RuntimeException("Expected to modify at least 1 row, but modified 0 rows.");
+ }
+ }
+}
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..4750d839
--- /dev/null
+++ b/src/main/java/mate/academy/exception/DataProcessingException.java
@@ -0,0 +1,7 @@
+package mate.academy.exception;
+
+public class DataProcessingException extends RuntimeException {
+ 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..2cf9c7cc
--- /dev/null
+++ b/src/main/java/mate/academy/model/Book.java
@@ -0,0 +1,42 @@
+package mate.academy.model;
+
+import java.math.BigDecimal;
+
+public class Book {
+ private Long id;
+ private String title;
+ private BigDecimal 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/service/ConnectionUtil.java b/src/main/java/mate/academy/service/ConnectionUtil.java
new file mode 100644
index 00000000..cd2a9913
--- /dev/null
+++ b/src/main/java/mate/academy/service/ConnectionUtil.java
@@ -0,0 +1,29 @@
+package mate.academy.service;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.Properties;
+
+public class ConnectionUtil {
+ private static final String DB_USER_NAME = "root";
+ private static final String DB_PASSWORD = "getdataSQLjul";
+ private static final String DB_URL = "jdbc:mysql://localhost:3306/shop";
+ private static final String MYSQL_CLASS = "com.mysql.cj.jdbc.Driver";
+ private static final Properties DB_Properties;
+
+ static {
+ DB_Properties = new Properties();
+ DB_Properties.put("user", DB_USER_NAME);
+ DB_Properties.put("password", DB_PASSWORD);
+ try {
+ Class.forName(MYSQL_CLASS);
+ } catch (ClassNotFoundException e) {
+ throw new RuntimeException("Cannot load MySQL JDBC driver class", e);
+ }
+ }
+
+ public static Connection create() 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..cd1bb7bc
--- /dev/null
+++ b/src/main/resources/init_db.sql
@@ -0,0 +1,6 @@
+CREATE TABLE books (
+ id BIGINT AUTO_INCREMENT,
+ title VARCHAR(255),
+ price DECIMAL(10, 2) NOT NULL,
+ PRIMARY KEY (id)
+);
\ No newline at end of file