From 63175438c0d7c2da08a3adc20c4c3a79809e3c0a Mon Sep 17 00:00:00 2001 From: olexanderbondarenko Date: Tue, 28 May 2024 14:41:00 +0200 Subject: [PATCH 1/9] added dependencies --- pom.xml | 8 ++++++++ 1 file changed, 8 insertions(+) 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 + + + From bc5b093137f761a6f8a02cb0be1b7697f6247732 Mon Sep 17 00:00:00 2001 From: olexanderbondarenko Date: Tue, 28 May 2024 14:41:33 +0200 Subject: [PATCH 2/9] added init sql script file for table creation --- src/main/resources/init_db.sql | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 src/main/resources/init_db.sql diff --git a/src/main/resources/init_db.sql b/src/main/resources/init_db.sql new file mode 100644 index 00000000..7c0200ef --- /dev/null +++ b/src/main/resources/init_db.sql @@ -0,0 +1,6 @@ +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 +)ENGINE=InnoDB DEFAULT CHARSET=utf8mb3; \ No newline at end of file From 3977e7de2a31e153ef84f3132a9b602039914999 Mon Sep 17 00:00:00 2001 From: olexanderbondarenko Date: Tue, 28 May 2024 14:41:52 +0200 Subject: [PATCH 3/9] added custom exception class --- .../academy/exception/DataProcessingException.java | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/main/java/mate/academy/exception/DataProcessingException.java 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); + } +} From 5a6c191d5518c7ba39123f36b03a3d67eb5f54d5 Mon Sep 17 00:00:00 2001 From: olexanderbondarenko Date: Tue, 28 May 2024 14:42:26 +0200 Subject: [PATCH 4/9] added model --- src/main/java/mate/academy/model/Book.java | 53 ++++++++++++++++++++++ 1 file changed, 53 insertions(+) create mode 100644 src/main/java/mate/academy/model/Book.java 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 + '}'; + } +} From c8eae8fd08d582075080ca9b5db957fd0b972cc5 Mon Sep 17 00:00:00 2001 From: olexanderbondarenko Date: Tue, 28 May 2024 14:42:40 +0200 Subject: [PATCH 5/9] added db connector --- .../mate/academy/util/db/ConnectionUtil.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 src/main/java/mate/academy/util/db/ConnectionUtil.java 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); + } +} From 34a3878d536322cde6014d155b39b656da3f8c1d Mon Sep 17 00:00:00 2001 From: olexanderbondarenko Date: Tue, 28 May 2024 14:43:00 +0200 Subject: [PATCH 6/9] implemented dao --- src/main/java/mate/academy/dao/BookDao.java | 17 +++ .../mate/academy/dao/impl/BookDaoImpl.java | 115 ++++++++++++++++++ 2 files changed, 132 insertions(+) create mode 100644 src/main/java/mate/academy/dao/BookDao.java create mode 100644 src/main/java/mate/academy/dao/impl/BookDaoImpl.java 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..5a54a22c --- /dev/null +++ b/src/main/java/mate/academy/dao/impl/BookDaoImpl.java @@ -0,0 +1,115 @@ +package mate.academy.dao.impl; + +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 = "; + + @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); + } + } 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 = 0"; + 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 = 0"; + 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 = 0"; + Long id = book.getId(); + try (Connection connection = ConnectionUtil.getConnection(); + PreparedStatement statement = connection.prepareStatement(updateQuery)) { + statement.setString(1, book.getTitle()); + statement.setBigDecimal(2, book.getPrice()); + statement.setLong(3, id); + int affectedRows = statement.executeUpdate(); + if (affectedRows > 0) { + return book; + } + } catch (SQLException e) { + throw new DataProcessingException(CANT_UPDATE + id, e); + } + throw new DataProcessingException(CANT_FIND_BY_ID + id); + } + + @Override + public boolean deleteById(Long id) { + String deletedQuery = "UPDATE books SET is_deleted = 1 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.getLong("id"), + resultSet.getString("title"), + resultSet.getBigDecimal("price")); + } +} From 92bc63f4dc3878ef4938ff4eaf2f744493862ff1 Mon Sep 17 00:00:00 2001 From: olexanderbondarenko Date: Tue, 28 May 2024 14:43:09 +0200 Subject: [PATCH 7/9] tested the app --- src/main/java/mate/academy/Main.java | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/main/java/mate/academy/Main.java b/src/main/java/mate/academy/Main.java index 0058fbf9..1ce666f4 100644 --- a/src/main/java/mate/academy/Main.java +++ b/src/main/java/mate/academy/Main.java @@ -1,7 +1,33 @@ 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 final BookDao bookDao = (BookDao) injector.getInstance(BookDao.class); + public static void main(String[] args) { + 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); } } From 180a878c6926032d437ebfa23bf9df30ea59b111 Mon Sep 17 00:00:00 2001 From: olexanderbondarenko Date: Tue, 28 May 2024 16:49:46 +0200 Subject: [PATCH 8/9] fixed --- .../java/mate/academy/dao/impl/BookDaoImpl.java | 15 ++++++++------- src/main/resources/init_db.sql | 3 +-- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main/java/mate/academy/dao/impl/BookDaoImpl.java b/src/main/java/mate/academy/dao/impl/BookDaoImpl.java index 5a54a22c..29b99bb0 100644 --- a/src/main/java/mate/academy/dao/impl/BookDaoImpl.java +++ b/src/main/java/mate/academy/dao/impl/BookDaoImpl.java @@ -1,5 +1,6 @@ package mate.academy.dao.impl; +import java.math.BigDecimal; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; @@ -44,7 +45,7 @@ public Book create(Book book) { @Override public Optional findById(Long id) { - String getByIdQuery = "SELECT * FROM books WHERE id = ? AND is_deleted = 0"; + 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); @@ -60,7 +61,7 @@ public Optional findById(Long id) { @Override public List findAll() { - String getAllQuery = "SELECT * FROM books WHERE is_deleted = 0"; + String getAllQuery = "SELECT * FROM books WHERE is_deleted = FALSE"; List books = new ArrayList<>(); try (Connection connection = ConnectionUtil.getConnection(); PreparedStatement statement = connection.prepareStatement(getAllQuery)) { @@ -77,7 +78,7 @@ public List findAll() { @Override public Book update(Book book) { String updateQuery = "UPDATE books SET title = ?, price = ? " - + "WHERE id = ? AND is_deleted = 0"; + + "WHERE id = ? AND is_deleted = FALSE"; Long id = book.getId(); try (Connection connection = ConnectionUtil.getConnection(); PreparedStatement statement = connection.prepareStatement(updateQuery)) { @@ -96,7 +97,7 @@ public Book update(Book book) { @Override public boolean deleteById(Long id) { - String deletedQuery = "UPDATE books SET is_deleted = 1 WHERE 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); @@ -108,8 +109,8 @@ public boolean deleteById(Long id) { private Book createBook(ResultSet resultSet) throws SQLException { return new Book( - resultSet.getLong("id"), - resultSet.getString("title"), - resultSet.getBigDecimal("price")); + resultSet.getObject("id", Long.class), + resultSet.getObject("title", String.class), + resultSet.getObject("price", BigDecimal.class)); } } diff --git a/src/main/resources/init_db.sql b/src/main/resources/init_db.sql index 7c0200ef..d76795fe 100644 --- a/src/main/resources/init_db.sql +++ b/src/main/resources/init_db.sql @@ -2,5 +2,4 @@ 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 -)ENGINE=InnoDB DEFAULT CHARSET=utf8mb3; \ No newline at end of file + is_deleted TINYINT NOT NULL DEFAULT 0); \ No newline at end of file From e42429d043b4df54e10f59603e5d9c58b3a4998c Mon Sep 17 00:00:00 2001 From: olexanderbondarenko Date: Wed, 29 May 2024 10:34:39 +0200 Subject: [PATCH 9/9] fixed --- src/main/java/mate/academy/Main.java | 3 ++- .../mate/academy/dao/impl/BookDaoImpl.java | 19 ++++++++++++------- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/main/java/mate/academy/Main.java b/src/main/java/mate/academy/Main.java index 1ce666f4..fe717f89 100644 --- a/src/main/java/mate/academy/Main.java +++ b/src/main/java/mate/academy/Main.java @@ -9,9 +9,10 @@ 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) { + BookDao bookDao = (BookDao) injector.getInstance(BookDao.class); + Book book = new Book("book", BigDecimal.valueOf(100)); Book createdBook = bookDao.create(book); System.out.println(createdBook); diff --git a/src/main/java/mate/academy/dao/impl/BookDaoImpl.java b/src/main/java/mate/academy/dao/impl/BookDaoImpl.java index 29b99bb0..dd79bf86 100644 --- a/src/main/java/mate/academy/dao/impl/BookDaoImpl.java +++ b/src/main/java/mate/academy/dao/impl/BookDaoImpl.java @@ -22,6 +22,10 @@ public class BookDaoImpl implements BookDao { 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) { @@ -36,6 +40,8 @@ public Book create(Book book) { 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); @@ -79,20 +85,19 @@ public List findAll() { public Book update(Book book) { String updateQuery = "UPDATE books SET title = ?, price = ? " + "WHERE id = ? AND is_deleted = FALSE"; - Long id = book.getId(); try (Connection connection = ConnectionUtil.getConnection(); PreparedStatement statement = connection.prepareStatement(updateQuery)) { statement.setString(1, book.getTitle()); statement.setBigDecimal(2, book.getPrice()); - statement.setLong(3, id); + statement.setLong(3, book.getId()); int affectedRows = statement.executeUpdate(); - if (affectedRows > 0) { - return book; + if (affectedRows < 1) { + throw new DataProcessingException(UPDATE_FAILED); } } catch (SQLException e) { - throw new DataProcessingException(CANT_UPDATE + id, e); + throw new DataProcessingException(CANT_UPDATE + book.getId(), e); } - throw new DataProcessingException(CANT_FIND_BY_ID + id); + return book; } @Override @@ -101,7 +106,7 @@ public boolean deleteById(Long id) { try (Connection connection = ConnectionUtil.getConnection(); PreparedStatement statement = connection.prepareStatement(deletedQuery)) { statement.setLong(1, id); - return statement.executeUpdate() != 0; + return statement.executeUpdate() > 0; } catch (SQLException e) { throw new DataProcessingException(CANT_DELETE + id, e); }