From 7c9740ed4c5686d80f947d3a9504d155aeb46e2d Mon Sep 17 00:00:00 2001
From: rainett <96131229+rainett@users.noreply.github.com>
Date: Tue, 3 Sep 2024 19:12:16 +0300
Subject: [PATCH 1/3] Implemented DAO and model for Book entity
---
pom.xml | 8 ++
src/main/java/mate/academy/Main.java | 39 ++++++
src/main/java/mate/academy/dao/BookDao.java | 17 +++
.../mate/academy/dao/impl/BookDaoImpl.java | 117 ++++++++++++++++++
.../exceptions/DataProcessingException.java | 11 ++
src/main/java/mate/academy/lib/Dao.java | 3 +
src/main/java/mate/academy/model/Book.java | 47 +++++++
.../mate/academy/util/ConnectionUtil.java | 30 +++++
src/main/resources/init_db.sql | 5 +
9 files changed, 277 insertions(+)
create mode 100644 src/main/java/mate/academy/dao/BookDao.java
create mode 100644 src/main/java/mate/academy/dao/impl/BookDaoImpl.java
create mode 100644 src/main/java/mate/academy/exceptions/DataProcessingException.java
create mode 100644 src/main/java/mate/academy/model/Book.java
create mode 100644 src/main/java/mate/academy/util/ConnectionUtil.java
create mode 100644 src/main/resources/init_db.sql
diff --git a/pom.xml b/pom.xml
index 683e84ec..e2ffb51a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -18,6 +18,14 @@
+
+
+ mysql
+ mysql-connector-java
+ 8.0.30
+
+
+
diff --git a/src/main/java/mate/academy/Main.java b/src/main/java/mate/academy/Main.java
index 0058fbf9..37f3136e 100644
--- a/src/main/java/mate/academy/Main.java
+++ b/src/main/java/mate/academy/Main.java
@@ -1,7 +1,46 @@
package mate.academy;
+import java.math.BigDecimal;
+import java.util.List;
+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);
+ List books = List.of(
+ new Book(null, "Book1", new BigDecimal(100)),
+ new Book(null, "Book2", new BigDecimal(150)),
+ new Book(null, "Book3", new BigDecimal(50))
+ );
+
+ books.forEach(bookDao::create);
+ System.out.println("Created books:");
+ books.forEach(System.out::println);
+ System.out.println();
+
+ Long bookId = 2L;
+ System.out.println("Book with id = [" + bookId + "]");
+ bookDao.findById(bookId).ifPresent(System.out::println);
+ System.out.println();
+
+ System.out.println("All books in the table:");
+ bookDao.findAll().forEach(System.out::println);
+ System.out.println();
+
+ Book anyBook = books.stream().findAny().orElseThrow();
+ anyBook.setTitle("Updated title");
+ Book anyUpdatedBook = bookDao.update(anyBook);
+ System.out.println("Updated book:");
+ System.out.println(anyUpdatedBook);
+ System.out.println();
+ boolean isDeleted = bookDao.deleteById(anyUpdatedBook.getId());
+ System.out.println("Is book with id = ["
+ + anyUpdatedBook.getId() + "] deleted = ["
+ + isDeleted + "]");
}
}
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..8accc494
--- /dev/null
+++ b/src/main/java/mate/academy/dao/impl/BookDaoImpl.java
@@ -0,0 +1,117 @@
+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.exceptions.DataProcessingException;
+import mate.academy.lib.Dao;
+import mate.academy.model.Book;
+import mate.academy.util.ConnectionUtil;
+
+@Dao
+public class BookDaoImpl implements BookDao {
+ @Override
+ public Book create(Book book) {
+ String query = "INSERT INTO books(title, price) VALUES (?, ?)";
+ try (Connection connection = ConnectionUtil.getConnection()) {
+ PreparedStatement statement =
+ connection.prepareStatement(query, Statement.RETURN_GENERATED_KEYS);
+ statement.setString(1, book.getTitle());
+ statement.setBigDecimal(2, book.getPrice());
+
+ int affectedRows = statement.executeUpdate();
+ if (affectedRows < 1) {
+ throw new DataProcessingException("Expected to affect at least one row, "
+ + "but got affected = [" + affectedRows + "]");
+ }
+ ResultSet resultSet = statement.getGeneratedKeys();
+ if (resultSet.next()) {
+ Long id = resultSet.getLong(1);
+ book.setId(id);
+ }
+ } catch (SQLException e) {
+ throw new DataProcessingException("Failed to create a book = [" + book + "]", e);
+ }
+ return book;
+ }
+
+ @Override
+ public Optional findById(Long id) {
+ String query = "SELECT * FROM books WHERE id = ?";
+ try (Connection connection = ConnectionUtil.getConnection()) {
+ PreparedStatement statement = connection.prepareStatement(query);
+ statement.setLong(1, id);
+ ResultSet resultSet = statement.executeQuery();
+ if (resultSet.next()) {
+ Book book = getBookFromResultSet(resultSet);
+ return Optional.of(book);
+ }
+ } catch (SQLException e) {
+ throw new DataProcessingException("Failed to find a book with id = [" + id + "]", e);
+ }
+ return Optional.empty();
+ }
+
+ @Override
+ public List findAll() {
+ String query = "SELECT * FROM books";
+ List books = new ArrayList<>();
+ try (Connection connection = ConnectionUtil.getConnection()) {
+ PreparedStatement statement = connection.prepareStatement(query);
+ ResultSet resultSet = statement.executeQuery();
+ while (resultSet.next()) {
+ Book book = getBookFromResultSet(resultSet);
+ books.add(book);
+ }
+ } catch (SQLException e) {
+ throw new DataProcessingException("Failed to fetch all books", e);
+ }
+ return books;
+ }
+
+ @Override
+ public Book update(Book book) {
+ String query = "UPDATE books SET title = ?, price = ? WHERE id = ?";
+ try (Connection connection = ConnectionUtil.getConnection()) {
+ PreparedStatement statement = connection.prepareStatement(query);
+ 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("Expected to affect at least one row, "
+ + "but got affected = [" + affectedRows + "]");
+ }
+ } catch (SQLException e) {
+ throw new DataProcessingException("Failed to update a book = [" + book + "]", e);
+ }
+ return book;
+ }
+
+ @Override
+ public boolean deleteById(Long id) {
+ String query = "DELETE FROM books WHERE id = ?";
+ try (Connection connection = ConnectionUtil.getConnection()) {
+ PreparedStatement statement = connection.prepareStatement(query);
+ statement.setLong(1, id);
+ return statement.executeUpdate() > 0;
+ } catch (SQLException e) {
+ throw new DataProcessingException("Failed to delete a book "
+ + "with 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");
+ return new Book(id, title, price);
+ }
+}
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..b39d20ac
--- /dev/null
+++ b/src/main/java/mate/academy/exceptions/DataProcessingException.java
@@ -0,0 +1,11 @@
+package mate.academy.exceptions;
+
+public class DataProcessingException extends RuntimeException {
+ public DataProcessingException(String message, Throwable e) {
+ super(message, e);
+ }
+
+ public DataProcessingException(String message) {
+ super(message);
+ }
+}
diff --git a/src/main/java/mate/academy/lib/Dao.java b/src/main/java/mate/academy/lib/Dao.java
index f558d09a..6c89c709 100644
--- a/src/main/java/mate/academy/lib/Dao.java
+++ b/src/main/java/mate/academy/lib/Dao.java
@@ -1,8 +1,11 @@
package mate.academy.lib;
+import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Dao {
}
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..d8828575
--- /dev/null
+++ b/src/main/java/mate/academy/model/Book.java
@@ -0,0 +1,47 @@
+package mate.academy.model;
+
+import java.math.BigDecimal;
+
+public class Book {
+ private Long id;
+ private String title;
+ private BigDecimal 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/ConnectionUtil.java b/src/main/java/mate/academy/util/ConnectionUtil.java
new file mode 100644
index 00000000..1577605a
--- /dev/null
+++ b/src/main/java/mate/academy/util/ConnectionUtil.java
@@ -0,0 +1,30 @@
+package mate.academy.util;
+
+import java.sql.Connection;
+import java.sql.DriverManager;
+import java.sql.SQLException;
+import java.util.Properties;
+import mate.academy.exceptions.DataProcessingException;
+
+public class ConnectionUtil {
+ private static final Properties DB_PROPERTIES;
+ private static final String URL = "jdbc:mysql://localhost:3306/mate";
+ private static final String USER = "root";
+ private static final String PASSWORD = "password";
+ private static final String DRIVER = "com.mysql.cj.jdbc.Driver";
+
+ static {
+ DB_PROPERTIES = new Properties();
+ DB_PROPERTIES.put("user", USER);
+ DB_PROPERTIES.put("password", PASSWORD);
+ try {
+ Class.forName(DRIVER);
+ } catch (ClassNotFoundException e) {
+ throw new DataProcessingException("Failed to load JDBC driver", e);
+ }
+ }
+
+ public static Connection getConnection() throws SQLException {
+ return DriverManager.getConnection(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..7b752a67
--- /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(10, 2) NOT NULL
+);
\ No newline at end of file
From a714556f0b7410ab2717b427556e87a21dc54634 Mon Sep 17 00:00:00 2001
From: rainett <96131229+rainett@users.noreply.github.com>
Date: Tue, 3 Sep 2024 19:14:03 +0300
Subject: [PATCH 2/3] removed redundant break
---
src/main/java/mate/academy/dao/impl/BookDaoImpl.java | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/main/java/mate/academy/dao/impl/BookDaoImpl.java b/src/main/java/mate/academy/dao/impl/BookDaoImpl.java
index 8accc494..3f9e8e7b 100644
--- a/src/main/java/mate/academy/dao/impl/BookDaoImpl.java
+++ b/src/main/java/mate/academy/dao/impl/BookDaoImpl.java
@@ -25,7 +25,6 @@ public Book create(Book book) {
connection.prepareStatement(query, Statement.RETURN_GENERATED_KEYS);
statement.setString(1, book.getTitle());
statement.setBigDecimal(2, book.getPrice());
-
int affectedRows = statement.executeUpdate();
if (affectedRows < 1) {
throw new DataProcessingException("Expected to affect at least one row, "
From 4d0c6bc1db5c5f9864722c00c55e4858a7517c5d Mon Sep 17 00:00:00 2001
From: rainett <96131229+rainett@users.noreply.github.com>
Date: Tue, 3 Sep 2024 19:20:21 +0300
Subject: [PATCH 3/3] moved from getLong to getObject in BookDaoImpl
---
src/main/java/mate/academy/dao/impl/BookDaoImpl.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/main/java/mate/academy/dao/impl/BookDaoImpl.java b/src/main/java/mate/academy/dao/impl/BookDaoImpl.java
index 3f9e8e7b..cc26df57 100644
--- a/src/main/java/mate/academy/dao/impl/BookDaoImpl.java
+++ b/src/main/java/mate/academy/dao/impl/BookDaoImpl.java
@@ -32,7 +32,7 @@ public Book create(Book book) {
}
ResultSet resultSet = statement.getGeneratedKeys();
if (resultSet.next()) {
- Long id = resultSet.getLong(1);
+ Long id = resultSet.getObject(1, Long.class);
book.setId(id);
}
} catch (SQLException e) {