From 15c78f6ff1b1c9edf24a426647af1757486b88db Mon Sep 17 00:00:00 2001 From: Ihor Vasylenko Date: Fri, 11 Aug 2023 17:15:10 +0300 Subject: [PATCH 1/3] implemented task --- pom.xml | 8 ++ .../mate/academy/DataProcessingException.java | 7 + src/main/java/mate/academy/Main.java | 20 ++- src/main/java/mate/academy/dao/BookDao.java | 13 ++ .../java/mate/academy/dao/BookDaoImpl.java | 126 ++++++++++++++++++ src/main/java/mate/academy/model/Book.java | 36 +++++ src/main/resources/init_db.sql | 6 + 7 files changed, 215 insertions(+), 1 deletion(-) create mode 100644 src/main/java/mate/academy/DataProcessingException.java create mode 100644 src/main/java/mate/academy/dao/BookDao.java create mode 100644 src/main/java/mate/academy/dao/BookDaoImpl.java create mode 100644 src/main/java/mate/academy/model/Book.java create mode 100644 src/main/resources/init_db.sql diff --git a/pom.xml b/pom.xml index 526fbcf3..c2144278 100644 --- a/pom.xml +++ b/pom.xml @@ -14,4 +14,12 @@ UTF-8 + + + com.mysql + mysql-connector-j + 8.1.0 + + + diff --git a/src/main/java/mate/academy/DataProcessingException.java b/src/main/java/mate/academy/DataProcessingException.java new file mode 100644 index 00000000..7ad0ffea --- /dev/null +++ b/src/main/java/mate/academy/DataProcessingException.java @@ -0,0 +1,7 @@ +package mate.academy; + +public class DataProcessingException extends RuntimeException { + public DataProcessingException(String message, Throwable ex) { + super(message, ex); + } +} diff --git a/src/main/java/mate/academy/Main.java b/src/main/java/mate/academy/Main.java index 0058fbf9..7c466faa 100644 --- a/src/main/java/mate/academy/Main.java +++ b/src/main/java/mate/academy/Main.java @@ -1,7 +1,25 @@ package mate.academy; +import mate.academy.dao.BookDao; +import mate.academy.lib.Injector; +import mate.academy.model.Book; +import java.math.BigDecimal; +import java.util.Optional; + public class Main { - public static void main(String[] args) { + private static final Injector injector = Injector.getInstance("mate.academy.dao"); + public static void main(String[] args) { + BookDao bookDao = (BookDao) injector.getInstance(BookDao.class); + Book book = new Book(); + book.setTitle("Sample"); + book.setPrice(BigDecimal.valueOf(5.99)); + bookDao.create(book); + Long bookId = 1L; + Optional foundBook = bookDao.findById(bookId); + bookDao.findAll(); + Book updatedBook = foundBook.orElseThrow(); + bookDao.update(updatedBook); + bookDao.deleteById(bookId); } } 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..a5833433 --- /dev/null +++ b/src/main/java/mate/academy/dao/BookDao.java @@ -0,0 +1,13 @@ +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); +} \ No newline at end of file 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..155154e0 --- /dev/null +++ b/src/main/java/mate/academy/dao/BookDaoImpl.java @@ -0,0 +1,126 @@ +package mate.academy.dao; + +import mate.academy.DataProcessingException; +import mate.academy.model.Book; +import mate.academy.lib.Dao; +import java.math.BigDecimal; +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.Properties; + +@Dao +public class BookDaoImpl implements BookDao { + private static final String CREATE_QUERY = "INSERT INTO books (title, price) VALUES (?, ?)"; + private static final String FIND_BY_ID_QUERY = "SELECT * FROM books WHERE id = ?"; + private static final String FIND_ALL_QUERY = "SELECT * FROM books"; + private static final String UPDATE_QUERY = "UPDATE books SET title = ?, price = ? WHERE id = ?"; + private static final String DELETE_BY_ID_QUERY = "DELETE FROM books WHERE id = ?"; + + @Override + public Book create(Book book) { + try (Connection connection = getConnection(); + PreparedStatement statement = connection.prepareStatement(CREATE_QUERY, + PreparedStatement.RETURN_GENERATED_KEYS)) { + setBookParameters(statement, book); + statement.executeUpdate(); + try (ResultSet generatedKeys = statement.getGeneratedKeys()) { + if (generatedKeys.next()) { + book.setId(generatedKeys.getLong(1)); + } else { + throw new SQLException("Creating book " + book + " failed, no ID obtained."); + } + } + return book; + } catch (SQLException e) { + throw new DataProcessingException("Failed to create book " + book, e); + } + } + + @Override + public Optional findById(Long id) { + try (Connection connection = getConnection(); + PreparedStatement statement = connection.prepareStatement(FIND_BY_ID_QUERY)) { + + statement.setLong(1, id); + try (ResultSet resultSet = statement.executeQuery()) { + if (resultSet.next()) { + return Optional.of(parseBook(resultSet)); + } + } + return Optional.empty(); + } catch (SQLException e) { + throw new DataProcessingException("Failed to find book by ID " + id, e); + } + } + + @Override + public List findAll() { + try (Connection connection = getConnection(); + PreparedStatement statement = connection.prepareStatement(FIND_ALL_QUERY); + ResultSet resultSet = statement.executeQuery()) { + + List books = new ArrayList<>(); + while (resultSet.next()) { + books.add(parseBook(resultSet)); + } + return books; + } catch (SQLException e) { + throw new DataProcessingException("Failed to get all books", e); + } + } + + @Override + public Book update(Book book) { + try (Connection connection = getConnection(); + PreparedStatement statement = connection.prepareStatement(UPDATE_QUERY)) { + setBookParameters(statement, book); + statement.setLong(3, book.getId()); + statement.executeUpdate(); + return book; + } catch (SQLException e) { + throw new DataProcessingException("Failed to update book" + book, e); + } + } + + @Override + public boolean deleteById(Long id) { + try (Connection connection = getConnection(); + PreparedStatement statement = connection.prepareStatement(DELETE_BY_ID_QUERY)) { + + statement.setLong(1, id); + int rowsDeleted = statement.executeUpdate(); + return rowsDeleted > 0; + } catch (SQLException e) { + throw new DataProcessingException("Failed to delete book by ID " + id, e); + } + } + + private Connection getConnection() throws SQLException { + Properties dbProperties = new Properties(); + dbProperties.put("user", "root"); + dbProperties.put("password", "Vika07012000"); + return DriverManager.getConnection("jdbc:mysql://localhost:3306/books", dbProperties); + } + + private Book parseBook(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; + } + + private void setBookParameters(PreparedStatement statement, Book book) throws SQLException { + statement.setString(1, book.getTitle()); + statement.setBigDecimal(2, book.getPrice()); + } +} \ No newline at end of file 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..05cb1e8f --- /dev/null +++ b/src/main/java/mate/academy/model/Book.java @@ -0,0 +1,36 @@ +package mate.academy.model; + +import java.math.BigDecimal; + +public class Book { + private Long id; + private String title; + private BigDecimal price; + + public Book() { + } + + 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; + } +} \ No newline at end of file diff --git a/src/main/resources/init_db.sql b/src/main/resources/init_db.sql new file mode 100644 index 00000000..da00befd --- /dev/null +++ b/src/main/resources/init_db.sql @@ -0,0 +1,6 @@ +CREATE TABLE `books` ( + `id` BIGINT NOT NULL AUTO_INCREMENT, + `title` VARCHAR(255) NOT NULL, + `price` DECIMAL(10, 2) NOT NULL, + PRIMARY KEY (id) +); From 7f4c569b1a145775fcf3b4f97fb0d35022eaba4c Mon Sep 17 00:00:00 2001 From: Ihor Vasylenko Date: Mon, 14 Aug 2023 11:26:45 +0300 Subject: [PATCH 2/3] improved solution --- .../java/mate/academy/DataProcessingException.java | 4 ++++ src/main/java/mate/academy/Main.java | 5 ++--- src/main/java/mate/academy/dao/BookDaoImpl.java | 10 ++++++++-- 3 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/main/java/mate/academy/DataProcessingException.java b/src/main/java/mate/academy/DataProcessingException.java index 7ad0ffea..d6f0acab 100644 --- a/src/main/java/mate/academy/DataProcessingException.java +++ b/src/main/java/mate/academy/DataProcessingException.java @@ -4,4 +4,8 @@ public class DataProcessingException extends RuntimeException { public DataProcessingException(String message, Throwable ex) { super(message, ex); } + + public DataProcessingException(String message) { + super(message); + } } diff --git a/src/main/java/mate/academy/Main.java b/src/main/java/mate/academy/Main.java index 7c466faa..c3468a63 100644 --- a/src/main/java/mate/academy/Main.java +++ b/src/main/java/mate/academy/Main.java @@ -15,11 +15,10 @@ public static void main(String[] args) { book.setTitle("Sample"); book.setPrice(BigDecimal.valueOf(5.99)); bookDao.create(book); - Long bookId = 1L; - Optional foundBook = bookDao.findById(bookId); + Optional foundBook = bookDao.findById(book.getId()); bookDao.findAll(); Book updatedBook = foundBook.orElseThrow(); bookDao.update(updatedBook); - bookDao.deleteById(bookId); + bookDao.deleteById(book.getId()); } } diff --git a/src/main/java/mate/academy/dao/BookDaoImpl.java b/src/main/java/mate/academy/dao/BookDaoImpl.java index 155154e0..be216dc3 100644 --- a/src/main/java/mate/academy/dao/BookDaoImpl.java +++ b/src/main/java/mate/academy/dao/BookDaoImpl.java @@ -28,7 +28,10 @@ public Book create(Book book) { PreparedStatement statement = connection.prepareStatement(CREATE_QUERY, PreparedStatement.RETURN_GENERATED_KEYS)) { setBookParameters(statement, book); - statement.executeUpdate(); + int updatedRows = statement.executeUpdate(); + if (updatedRows < 1) { + throw new DataProcessingException("Failed to create book: no rows were updated."); + } try (ResultSet generatedKeys = statement.getGeneratedKeys()) { if (generatedKeys.next()) { book.setId(generatedKeys.getLong(1)); @@ -81,7 +84,10 @@ public Book update(Book book) { PreparedStatement statement = connection.prepareStatement(UPDATE_QUERY)) { setBookParameters(statement, book); statement.setLong(3, book.getId()); - statement.executeUpdate(); + int updatedRows = statement.executeUpdate(); + if (updatedRows < 1) { + throw new DataProcessingException("Failed to create book: no rows were updated."); + } return book; } catch (SQLException e) { throw new DataProcessingException("Failed to update book" + book, e); From 593776b66b0e99b092b27eeac3065da7950c5d57 Mon Sep 17 00:00:00 2001 From: Ihor Vasylenko Date: Mon, 14 Aug 2023 13:47:22 +0300 Subject: [PATCH 3/3] fixed mistakes --- src/main/java/mate/academy/dao/BookDao.java | 6 +++- .../java/mate/academy/dao/BookDaoImpl.java | 36 ++++++++----------- src/main/java/mate/academy/model/Book.java | 2 +- 3 files changed, 21 insertions(+), 23 deletions(-) diff --git a/src/main/java/mate/academy/dao/BookDao.java b/src/main/java/mate/academy/dao/BookDao.java index a5833433..5c3db0dd 100644 --- a/src/main/java/mate/academy/dao/BookDao.java +++ b/src/main/java/mate/academy/dao/BookDao.java @@ -6,8 +6,12 @@ public interface BookDao { Book create(Book book); + Optional findById(Long id); + List findAll(); + Book update(Book book); + boolean deleteById(Long id); -} \ No newline at end of file +} diff --git a/src/main/java/mate/academy/dao/BookDaoImpl.java b/src/main/java/mate/academy/dao/BookDaoImpl.java index be216dc3..c5139323 100644 --- a/src/main/java/mate/academy/dao/BookDaoImpl.java +++ b/src/main/java/mate/academy/dao/BookDaoImpl.java @@ -16,25 +16,18 @@ @Dao public class BookDaoImpl implements BookDao { - private static final String CREATE_QUERY = "INSERT INTO books (title, price) VALUES (?, ?)"; - private static final String FIND_BY_ID_QUERY = "SELECT * FROM books WHERE id = ?"; - private static final String FIND_ALL_QUERY = "SELECT * FROM books"; - private static final String UPDATE_QUERY = "UPDATE books SET title = ?, price = ? WHERE id = ?"; - private static final String DELETE_BY_ID_QUERY = "DELETE FROM books WHERE id = ?"; - @Override public Book create(Book book) { + String query = "INSERT INTO books (title, price) VALUES (?, ?)"; try (Connection connection = getConnection(); - PreparedStatement statement = connection.prepareStatement(CREATE_QUERY, + PreparedStatement statement = connection.prepareStatement(query, PreparedStatement.RETURN_GENERATED_KEYS)) { setBookParameters(statement, book); - int updatedRows = statement.executeUpdate(); - if (updatedRows < 1) { - throw new DataProcessingException("Failed to create book: no rows were updated."); - } + statement.executeUpdate(); try (ResultSet generatedKeys = statement.getGeneratedKeys()) { if (generatedKeys.next()) { - book.setId(generatedKeys.getLong(1)); + Long id = generatedKeys.getObject(1, Long.class); + book.setId(id); } else { throw new SQLException("Creating book " + book + " failed, no ID obtained."); } @@ -47,8 +40,9 @@ public Book create(Book book) { @Override public Optional findById(Long id) { + String query = "SELECT * FROM books WHERE id = ?"; try (Connection connection = getConnection(); - PreparedStatement statement = connection.prepareStatement(FIND_BY_ID_QUERY)) { + PreparedStatement statement = connection.prepareStatement(query)) { statement.setLong(1, id); try (ResultSet resultSet = statement.executeQuery()) { @@ -64,8 +58,9 @@ public Optional findById(Long id) { @Override public List findAll() { + String query = "SELECT * FROM books"; try (Connection connection = getConnection(); - PreparedStatement statement = connection.prepareStatement(FIND_ALL_QUERY); + PreparedStatement statement = connection.prepareStatement(query); ResultSet resultSet = statement.executeQuery()) { List books = new ArrayList<>(); @@ -80,14 +75,12 @@ public List findAll() { @Override public Book update(Book book) { + String query = "UPDATE books SET title = ?, price = ? WHERE id = ?"; try (Connection connection = getConnection(); - PreparedStatement statement = connection.prepareStatement(UPDATE_QUERY)) { + PreparedStatement statement = connection.prepareStatement(query)) { setBookParameters(statement, book); statement.setLong(3, book.getId()); - int updatedRows = statement.executeUpdate(); - if (updatedRows < 1) { - throw new DataProcessingException("Failed to create book: no rows were updated."); - } + statement.executeUpdate(); return book; } catch (SQLException e) { throw new DataProcessingException("Failed to update book" + book, e); @@ -96,8 +89,9 @@ public Book update(Book book) { @Override public boolean deleteById(Long id) { + String query = "DELETE FROM books WHERE id = ?"; try (Connection connection = getConnection(); - PreparedStatement statement = connection.prepareStatement(DELETE_BY_ID_QUERY)) { + PreparedStatement statement = connection.prepareStatement(query)) { statement.setLong(1, id); int rowsDeleted = statement.executeUpdate(); @@ -129,4 +123,4 @@ private void setBookParameters(PreparedStatement statement, Book book) throws SQ statement.setString(1, book.getTitle()); statement.setBigDecimal(2, book.getPrice()); } -} \ No newline at end of file +} diff --git a/src/main/java/mate/academy/model/Book.java b/src/main/java/mate/academy/model/Book.java index 05cb1e8f..9c0a70b8 100644 --- a/src/main/java/mate/academy/model/Book.java +++ b/src/main/java/mate/academy/model/Book.java @@ -33,4 +33,4 @@ public BigDecimal getPrice() { public void setPrice(BigDecimal price) { this.price = price; } -} \ No newline at end of file +}