From 3b22a03c646991e89d4dbfc1430fdcb6c1eeec7c Mon Sep 17 00:00:00 2001 From: Bob Date: Sun, 5 May 2024 15:01:37 +0200 Subject: [PATCH] bookDao methods implemented and tested --- pom.xml | 7 + src/main/java/mate/academy/Main.java | 7 - .../java/mate/academy/lib/dao/BookDao.java | 17 +++ .../mate/academy/lib/dao/BookDaoImpl.java | 127 ++++++++++++++++++ .../exception/DataProcessingException.java | 7 + .../java/mate/academy/lib/model/Book.java | 56 ++++++++ .../academy/lib/service/ConnectionUtil.java | 30 +++++ .../java/mate/academy/lib/service/Main.java | 27 ++++ src/main/resources/init_db.sql | 5 + 9 files changed, 276 insertions(+), 7 deletions(-) delete mode 100644 src/main/java/mate/academy/Main.java create mode 100644 src/main/java/mate/academy/lib/dao/BookDao.java create mode 100644 src/main/java/mate/academy/lib/dao/BookDaoImpl.java create mode 100644 src/main/java/mate/academy/lib/exception/DataProcessingException.java create mode 100644 src/main/java/mate/academy/lib/model/Book.java create mode 100644 src/main/java/mate/academy/lib/service/ConnectionUtil.java create mode 100644 src/main/java/mate/academy/lib/service/Main.java create mode 100644 src/main/resources/init_db.sql diff --git a/pom.xml b/pom.xml index 683e84ec..4bb521a5 100644 --- a/pom.xml +++ b/pom.xml @@ -55,4 +55,11 @@ + + + com.mysql + mysql-connector-j + 8.3.0 + + diff --git a/src/main/java/mate/academy/Main.java b/src/main/java/mate/academy/Main.java deleted file mode 100644 index 0058fbf9..00000000 --- a/src/main/java/mate/academy/Main.java +++ /dev/null @@ -1,7 +0,0 @@ -package mate.academy; - -public class Main { - public static void main(String[] args) { - - } -} diff --git a/src/main/java/mate/academy/lib/dao/BookDao.java b/src/main/java/mate/academy/lib/dao/BookDao.java new file mode 100644 index 00000000..ff9cc8e3 --- /dev/null +++ b/src/main/java/mate/academy/lib/dao/BookDao.java @@ -0,0 +1,17 @@ +package mate.academy.lib.dao; + +import java.util.List; +import java.util.Optional; +import mate.academy.lib.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/lib/dao/BookDaoImpl.java b/src/main/java/mate/academy/lib/dao/BookDaoImpl.java new file mode 100644 index 00000000..5ef533a1 --- /dev/null +++ b/src/main/java/mate/academy/lib/dao/BookDaoImpl.java @@ -0,0 +1,127 @@ +package mate.academy.lib.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.lib.Dao; +import mate.academy.lib.exception.DataProcessingException; +import mate.academy.lib.model.Book; +import mate.academy.lib.service.ConnectionUtil; + +@Dao +public class BookDaoImpl implements BookDao { + private static final String ID = "id"; + private static final String TITLE = "title"; + private static final String PRICE = "price"; + + @Override + public Book create(Book book) { + String sql = "INSERT INTO books (title, price) VALUES (?, ?)"; + try (Connection connection = ConnectionUtil.getConnection(); + PreparedStatement statement = connection.prepareStatement(sql, + 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 insert at least 1 row," + + " inserted 0 rows", null); + } + + ResultSet generatedKeys = statement.getGeneratedKeys(); + if (generatedKeys.next()) { + long id = generatedKeys.getObject(1, Long.class); + book.setId(id); + } + } catch (SQLException e) { + throw new DataProcessingException("Failed to add new book: " + book, e); + } + return book; + } + + @Override + public Optional findById(Long id) { + String sql = "SELECT * FROM books WHERE id = ?"; + try (Connection connection = ConnectionUtil.getConnection(); + PreparedStatement statement = connection.prepareStatement(sql)) { + statement.setLong(1, id); + try (ResultSet resultSet = statement.executeQuery()) { + if (resultSet.next()) { + long bookId = resultSet.getObject(ID, Long.class); + String title = resultSet.getString(TITLE); + BigDecimal price = resultSet.getBigDecimal(PRICE); + Book book = new Book(bookId, title, price); + return Optional.of(book); + } else { + return Optional.empty(); + } + } + } catch (SQLException e) { + throw new DataProcessingException("Failed to find a book with id: " + id, e); + } + } + + @Override + public List findAll() { + String sql = "SELECT * FROM books"; + List books = new ArrayList<>(); + try (Connection connection = ConnectionUtil.getConnection(); + PreparedStatement statement = connection.prepareStatement(sql)) { + ResultSet resultSet = statement.executeQuery(); + + while (resultSet.next()) { + long id = resultSet.getLong(ID); + String title = resultSet.getString(TITLE); + BigDecimal price = resultSet.getBigDecimal(PRICE); + Book book = new Book(id, title, price); + books.add(book); + } + } catch (SQLException e) { + throw new DataProcessingException("Failed to retrieve books from the database", e); + } + return books; + } + + @Override + public Book update(Book book) { + String sql = "UPDATE books SET title = ?, price = ? WHERE id = ?"; + try (Connection connection = ConnectionUtil.getConnection(); + PreparedStatement statement = connection.prepareStatement(sql)) { + 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 insert at least 1 row," + + " inserted 0 rows", null); + } + } catch (SQLException e) { + throw new DataProcessingException("Failed to add new book: " + book, e); + } + return book; + } + + @Override + public boolean deleteById(Long id) { + String sql = "DELETE FROM books WHERE id = ?"; + try (Connection connection = ConnectionUtil.getConnection(); + PreparedStatement statement = connection.prepareStatement(sql)) { + statement.setLong(1, id); + + int affectedRows = statement.executeUpdate(); + if (affectedRows < 1) { + return false; + } + } catch (SQLException e) { + throw new DataProcessingException("Failed to delete a book with id: " + id, e); + } + return true; + } +} diff --git a/src/main/java/mate/academy/lib/exception/DataProcessingException.java b/src/main/java/mate/academy/lib/exception/DataProcessingException.java new file mode 100644 index 00000000..8e856153 --- /dev/null +++ b/src/main/java/mate/academy/lib/exception/DataProcessingException.java @@ -0,0 +1,7 @@ +package mate.academy.lib.exception; + +public class DataProcessingException extends RuntimeException { + public DataProcessingException(String message, Throwable ex) { + super(message, ex); + } +} diff --git a/src/main/java/mate/academy/lib/model/Book.java b/src/main/java/mate/academy/lib/model/Book.java new file mode 100644 index 00000000..c2735b52 --- /dev/null +++ b/src/main/java/mate/academy/lib/model/Book.java @@ -0,0 +1,56 @@ +package mate.academy.lib.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 + + '}'; + } +} diff --git a/src/main/java/mate/academy/lib/service/ConnectionUtil.java b/src/main/java/mate/academy/lib/service/ConnectionUtil.java new file mode 100644 index 00000000..6b614c8b --- /dev/null +++ b/src/main/java/mate/academy/lib/service/ConnectionUtil.java @@ -0,0 +1,30 @@ +package mate.academy.lib.service; + +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 String DB_DRIVER = "com.mysql.cj.jdbc.Driver"; + private static final String DB_USERNAME = "root"; + private static final String DB_PASSWORD = "MySQL1914#"; + private static final Properties DB_PROPERTIES; + + static { + DB_PROPERTIES = new Properties(); + DB_PROPERTIES.put("user", DB_USERNAME); + DB_PROPERTIES.put("password", DB_PASSWORD); + + try { + Class.forName(DB_DRIVER); + } catch (ClassNotFoundException e) { + throw new RuntimeException("Can't load JDBC driver : " + DB_DRIVER, e); + } + } + + public static Connection getConnection() throws SQLException { + return DriverManager.getConnection(DB_URL, DB_PROPERTIES); + } +} diff --git a/src/main/java/mate/academy/lib/service/Main.java b/src/main/java/mate/academy/lib/service/Main.java new file mode 100644 index 00000000..041f8d7e --- /dev/null +++ b/src/main/java/mate/academy/lib/service/Main.java @@ -0,0 +1,27 @@ +package mate.academy.lib.service; + +import java.math.BigDecimal; +import mate.academy.lib.Injector; +import mate.academy.lib.dao.BookDao; +import mate.academy.lib.model.Book; + +public class Main { + private static final Injector injector = Injector.getInstance("mate.academy.lib"); + + public static void main(String[] args) { + BookDao bookDao = (BookDao) injector.getInstance(BookDao.class); + + Book airport = new Book("Airport", BigDecimal.valueOf(29.00)); + bookDao.create(airport); + System.out.println(airport); + + System.out.println(bookDao.findById(2L)); + + airport.setTitle("Waterport"); + System.out.println(bookDao.update(airport)); + + bookDao.deleteById(1L); + + System.out.println(bookDao.findAll()); + } +} diff --git a/src/main/resources/init_db.sql b/src/main/resources/init_db.sql new file mode 100644 index 00000000..438bc2fb --- /dev/null +++ b/src/main/resources/init_db.sql @@ -0,0 +1,5 @@ +CREATE TABLE `books` ( + `id` BIGINT AUO_INCREMENT PRIMARY KEY, + `title` VARCHAR(255), + `price` DECIMAL(10, 2) +);