diff --git a/pom.xml b/pom.xml
index 683e84ec..ee12ea36 100644
--- a/pom.xml
+++ b/pom.xml
@@ -18,6 +18,14 @@
+
+
+ mysql
+ mysql-connector-java
+ 8.0.33
+
+
+
diff --git a/src/main/java/mate/academy/Main.java b/src/main/java/mate/academy/Main.java
index 0058fbf9..0684324f 100644
--- a/src/main/java/mate/academy/Main.java
+++ b/src/main/java/mate/academy/Main.java
@@ -1,7 +1,30 @@
package mate.academy;
+import java.math.BigDecimal;
+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 final BookDao bookDao = (BookDao) injector.getInstance(BookDao.class);
+
public static void main(String[] args) {
+ Book book1 = new Book();
+ book1.setTitle("SQL for Data Analysis");
+ book1.setPrice(BigDecimal.valueOf(500));
+ book1 = bookDao.create(book1);
+ Book book2 = new Book();
+ book2.setTitle("Effective Java");
+ book2.setPrice(BigDecimal.valueOf(800));
+ book2 = bookDao.create(book2);
+ System.out.println(bookDao.findById(book2.getId()));
+ System.out.println(bookDao.getAll());
+ System.out.println(bookDao.delete(book1.getId()));
+ book2.setTitle("Joshua Bloch: Effective Java");
+ book2.setPrice(BigDecimal.valueOf(850));
+ bookDao.update(book2);
+ System.out.println(bookDao.getAll());
}
}
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..9c521496
--- /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 getAll();
+
+ Book update(Book book);
+
+ boolean delete(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..16a37406
--- /dev/null
+++ b/src/main/java/mate/academy/dao/BookDaoImpl.java
@@ -0,0 +1,129 @@
+package mate.academy.dao;
+
+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.exceptions.DataProcessingException;
+import mate.academy.lib.Dao;
+import mate.academy.model.Book;
+import mate.academy.utils.ConnectionUtil;
+
+@Dao
+public class BookDaoImpl implements BookDao {
+ @Override
+ public Book create(Book book) {
+ String insertBookQuery = "INSERT INTO books (title, price) VALUES (?, ?);";
+ try (Connection connection = ConnectionUtil.getConnection();
+ PreparedStatement statement = connection
+ .prepareStatement(insertBookQuery, Statement.RETURN_GENERATED_KEYS)) {
+ statement.setString(1, book.getTitle());
+ statement.setBigDecimal(2, book.getPrice());
+ int affectedRows = statement.executeUpdate();
+ if (affectedRows < 1) {
+ throw new DataProcessingException("Excepted to insert at least one row, "
+ + "but inserted 0 rows",
+ new RuntimeException());
+ }
+ 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 book with title: "
+ + book.getTitle()
+ + ", and price: "
+ + book.getPrice() + ":", e);
+ }
+ return book;
+ }
+
+ @Override
+ public Optional findById(Long id) {
+ String findBookQuery = "SELECT * from books WHERE id = ? AND is_deleted = FALSE;";
+ try (Connection connection = ConnectionUtil.getConnection();
+ PreparedStatement statement = connection
+ .prepareStatement(findBookQuery)) {
+ statement.setLong(1, id);
+ ResultSet resultSet = statement.executeQuery();
+ Book book = null;
+ if (resultSet.next()) {
+ book = getBookFromResultSet(resultSet);
+ }
+ return Optional.ofNullable(book);
+ } catch (SQLException e) {
+ throw new DataProcessingException("Can't find book from id " + id + ":", e);
+ }
+ }
+
+ @Override
+ public List getAll() {
+ List books = new ArrayList<>();
+ String getAllBookQuery = "SELECT * FROM books WHERE is_deleted = FALSE;";
+ try (Connection connection = ConnectionUtil.getConnection();
+ PreparedStatement statement = connection
+ .prepareStatement(getAllBookQuery)) {
+ ResultSet resultSet = statement.executeQuery();
+ while (resultSet.next()) {
+ books.add(getBookFromResultSet(resultSet));
+ }
+ } catch (SQLException e) {
+ throw new DataProcessingException("Can't get all books from DB:", e);
+ }
+ return books;
+ }
+
+ @Override
+ public Book update(Book book) {
+ String updateBookQuery =
+ "UPDATE books SET title = ?, price = ? WHERE id = ? AND is_deleted = FALSE;";
+ try (Connection connection = ConnectionUtil.getConnection();
+ PreparedStatement statement = connection
+ .prepareStatement(updateBookQuery)) {
+ 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("Excepted to update at least one row, "
+ + "but updated 0 rows:",
+ new RuntimeException());
+ }
+ } catch (SQLException e) {
+ throw new DataProcessingException("Can't update book by id:" + book.getId(), e);
+ }
+ return book;
+ }
+
+ @Override
+ public boolean delete(Long id) {
+ String deleteBookQuery = "UPDATE books SET is_deleted = TRUE WHERE id = ?;";
+ try (Connection connection = ConnectionUtil.getConnection();
+ PreparedStatement statement = connection
+ .prepareStatement(deleteBookQuery)) {
+ statement.setLong(1, id);
+ int affectedRows = statement.executeUpdate();
+ return affectedRows > 0;
+ } catch (SQLException e) {
+ throw new DataProcessingException("Can't delete book by id:" + id + ":", e);
+ }
+ }
+
+ private Book getBookFromResultSet(ResultSet resultSet) throws SQLException {
+ Long id = resultSet.getObject("id", Long.class);
+ String title = resultSet.getString("title");
+ BigDecimal price = resultSet.getBigDecimal("price");
+ Book book = new Book();
+ book.setId(id);
+ book.setTitle(title);
+ book.setPrice(price);
+ return book;
+ }
+}
diff --git a/src/main/java/mate/academy/exceptions/DataProcessingException.java b/src/main/java/mate/academy/exceptions/DataProcessingException.java
new file mode 100644
index 00000000..798fcffc
--- /dev/null
+++ b/src/main/java/mate/academy/exceptions/DataProcessingException.java
@@ -0,0 +1,7 @@
+package mate.academy.exceptions;
+
+public class DataProcessingException extends RuntimeException {
+ public DataProcessingException(String message, Throwable ex) {
+ super(message, ex);
+ }
+}
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..e2cb4289
--- /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/resources/init_db.sql b/src/main/java/mate/academy/resources/init_db.sql
new file mode 100644
index 00000000..cf50286c
--- /dev/null
+++ b/src/main/java/mate/academy/resources/init_db.sql
@@ -0,0 +1,9 @@
+CREATE TABLE `books` (
+ `id` bigint NOT NULL AUTO_INCREMENT,
+ `title` varchar(45) DEFAULT NULL,
+ `price` decimal(10,2) DEFAULT NULL,
+ `is_deleted` bit(1) NOT NULL DEFAULT b'0',
+ PRIMARY KEY (`id`),
+ UNIQUE KEY `id_UNIQUE` (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
+
diff --git a/src/main/java/mate/academy/utils/ConnectionUtil.java b/src/main/java/mate/academy/utils/ConnectionUtil.java
new file mode 100644
index 00000000..0b83a4fe
--- /dev/null
+++ b/src/main/java/mate/academy/utils/ConnectionUtil.java
@@ -0,0 +1,29 @@
+package mate.academy.utils;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.Properties;
+
+public class ConnectionUtil {
+ private static final String USERNAME = "root";
+ private static final String PASSWORD = "12345678";
+ private static final String DB_URL = "jdbc:mysql://localhost:3306/library";
+ private static final String DRIVER_PACKAGE = "com.mysql.cj.jdbc.Driver";
+ private static final Properties DB_PROPERTIES;
+
+ static {
+ DB_PROPERTIES = new Properties();
+ DB_PROPERTIES.put("user", USERNAME);
+ DB_PROPERTIES.put("password", PASSWORD);
+ try {
+ Class.forName(DRIVER_PACKAGE);
+ } 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);
+ }
+}