From bc7339b0ea5abc70b78d4e32eb7dcfae73fef367 Mon Sep 17 00:00:00 2001 From: citruscaviar Date: Tue, 30 Jul 2024 17:57:33 +0300 Subject: [PATCH] completed the task --- src/main/java/mate/academy/Main.java | 23 ++++ src/main/java/mate/academy/dao/BookDao.java | 17 +++ .../java/mate/academy/dao/BookDaoImpl.java | 128 ++++++++++++++++++ .../java/mate/academy/dao/ConnectionUtil.java | 32 +++++ .../exception/DataProcessingException.java | 7 + src/main/java/mate/academy/lib/Dao.java | 1 + src/main/java/mate/academy/model/Book.java | 76 +++++++++++ src/main/resources/init_db.sql | 5 + 8 files changed, 289 insertions(+) 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/dao/ConnectionUtil.java create mode 100644 src/main/java/mate/academy/exception/DataProcessingException.java create mode 100644 src/main/java/mate/academy/model/Book.java create mode 100644 src/main/resources/init_db.sql diff --git a/src/main/java/mate/academy/Main.java b/src/main/java/mate/academy/Main.java index 0058fbf9..6da8a8a4 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 java.util.ArrayList; +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 = new ArrayList<>(); + books.add(new Book("Harry Potter", new BigDecimal(1200))); + books.add(new Book("Star Wars", new BigDecimal(1100))); + books.add(new Book("Dune", new BigDecimal(1700))); + + books.forEach(bookDao::create); + Book book = bookDao.findById(1L).orElseThrow(() -> + new RuntimeException("Couldn't find the book") + ); + List bookList = bookDao.findAll(); + System.out.println(bookList); + Book updatedBook = bookDao.update(new Book("Harry Potter", new BigDecimal(2500))); + System.out.println(bookDao.deleteById(1L)); } } 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/BookDaoImpl.java b/src/main/java/mate/academy/dao/BookDaoImpl.java new file mode 100644 index 00000000..13630fd7 --- /dev/null +++ b/src/main/java/mate/academy/dao/BookDaoImpl.java @@ -0,0 +1,128 @@ +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.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; + +@Dao +public class BookDaoImpl implements BookDao { + @Override + public Book create(Book book) { + String sql = "INSERT INTO books (title, price) VALUES (?, ?)"; + try (Connection connection = ConnectionUtil.getConnection(); + PreparedStatement preparedStatement = + connection.prepareStatement(sql, + PreparedStatement.RETURN_GENERATED_KEYS)) { + preparedStatement.setString(1, book.getTitle()); + preparedStatement.setBigDecimal(2, book.getPrice()); + + int affectedRows = preparedStatement.executeUpdate(); + if (affectedRows < 1) { + throw new RuntimeException("Expected to insert at least 1 row." + + " But was inserted 0"); + } + + ResultSet generatedKeys = preparedStatement.getGeneratedKeys(); + if (generatedKeys.next()) { + Long id = generatedKeys.getObject(1, Long.class); + book.setId(id); + } + + } catch (SQLException e) { + throw new RuntimeException("Cannot create a new book: " + book, e); + } + return book; + } + + @Override + public Optional findById(Long id) { + Book book = new Book(); + String sql = "SELECT id, title, price FROM books WHERE id = ?"; + try (Connection connection = ConnectionUtil.getConnection(); + PreparedStatement preparedStatement = connection.prepareStatement(sql)) { + preparedStatement.setLong(1, id); + + ResultSet resultSet = preparedStatement.executeQuery(); + if (resultSet.next()) { + book.setId(resultSet.getLong("id")); + book.setTitle(resultSet.getString("title")); + book.setPrice(resultSet.getBigDecimal("price")); + } + } catch (SQLException e) { + throw new DataProcessingException("The book with the id: " + id + + " wasn't found", e); + } + return Optional.ofNullable(book); + } + + @Override + public List findAll() { + List books = new ArrayList<>(); + String sql = "SELECT * FROM book"; + try (Connection connection = ConnectionUtil.getConnection(); + PreparedStatement preparedStatement = connection.prepareStatement(sql)) { + ResultSet resultSet = preparedStatement.executeQuery(); + while (resultSet.next()) { + Book book = getBookFromResultSet(resultSet); + books.add(book); + } + } catch (SQLException e) { + throw new DataProcessingException("Cannot find any books", e); + } + return books; + } + + @Override + public Book update(Book book) { + String sql = "UPDATE books SET title = ?, price = ? WHERE id = ?"; + try (Connection connection = ConnectionUtil.getConnection(); + PreparedStatement preparedStatement = connection.prepareStatement(sql)) { + preparedStatement.setString(1, book.getTitle()); + preparedStatement.setBigDecimal(2, book.getPrice()); + preparedStatement.setLong(3, book.getId()); + int affectedRows = preparedStatement.executeUpdate(); + if (affectedRows < 1) { + throw new RuntimeException("Failed to update the book with id: " + + book.getId()); + } + } catch (SQLException e) { + throw new DataProcessingException("Cannot update the book", e); + } + return book; + } + + @Override + public boolean deleteById(Long id) { + String sql = "DELETE FROM books WHERE id = ?"; + try (Connection connection = ConnectionUtil.getConnection(); + PreparedStatement preparedStatement = connection.prepareStatement(sql)) { + preparedStatement.setLong(1, id); + int affectedRows = preparedStatement.executeUpdate(); + return affectedRows > 0; + } catch (SQLException e) { + throw new RuntimeException("Failed to delete the 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"); + + Book book = new Book(); + book.setId(id); + book.setTitle(title); + book.setPrice(price); + return book; + } +} diff --git a/src/main/java/mate/academy/dao/ConnectionUtil.java b/src/main/java/mate/academy/dao/ConnectionUtil.java new file mode 100644 index 00000000..a5194c26 --- /dev/null +++ b/src/main/java/mate/academy/dao/ConnectionUtil.java @@ -0,0 +1,32 @@ +package mate.academy.dao; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.util.Properties; +import mate.academy.exception.DataProcessingException; + +public class ConnectionUtil { + private static final String DB_URL = "jdbc:mysql://localhost:3306/jv_jdbc_intro"; + private static final Properties DB_PROPERTIES; + + static { + DB_PROPERTIES = new Properties(); + DB_PROPERTIES.put("user","root"); + DB_PROPERTIES.put("password","3McuPdh25LoKc1_"); + + try { + Class.forName("com.mysql.cj.jdbc.Driver"); + } catch (ClassNotFoundException e) { + throw new DataProcessingException("Failed to connect to the Database." + + "Check the connection setting. Make sure that your URL is correct" + + DB_URL + + "Verify user id and credentials", e); + + } + } + + public static Connection getConnection() throws SQLException { + return DriverManager.getConnection(DB_URL,DB_PROPERTIES); + } +} 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..63b937dc --- /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/lib/Dao.java b/src/main/java/mate/academy/lib/Dao.java index f558d09a..bc8d11a0 100644 --- a/src/main/java/mate/academy/lib/Dao.java +++ b/src/main/java/mate/academy/lib/Dao.java @@ -5,4 +5,5 @@ @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..fd085b4d --- /dev/null +++ b/src/main/java/mate/academy/model/Book.java @@ -0,0 +1,76 @@ +package mate.academy.model; + +import java.math.BigDecimal; +import java.util.Objects; + +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 + + '}'; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + Book book = (Book) o; + return Objects.equals(id, book.id) + && Objects.equals(title, book.title) + && Objects.equals(price, book.price); + } + + @Override + public int hashCode() { + return Objects.hash(id, title, price); + } +} diff --git a/src/main/resources/init_db.sql b/src/main/resources/init_db.sql new file mode 100644 index 00000000..ccade19d --- /dev/null +++ b/src/main/resources/init_db.sql @@ -0,0 +1,5 @@ +CREATE TABLE 'book' ( + 'id' BIGINT AUTO_INCREMENT PRIMARY KEY, + 'title' VARCHAR(255) NOT NULL, + 'price' DECIMAL(10, 2) NOT NULL +); \ No newline at end of file