From 7d9647fbcee373f3a53af5210b55acae517952f1 Mon Sep 17 00:00:00 2001 From: Mykhailo Kazarian Date: Sat, 6 Jul 2024 19:56:02 +0300 Subject: [PATCH 1/5] init_db.sql implementation --- 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..93a111c6 --- /dev/null +++ b/src/main/resources/init_db.sql @@ -0,0 +1,6 @@ +CREATE TABLE `books`( + `id` INT NOT NULL AUTO_INCREMENT, + `title` VARCHAR(255), + `price` DECIMAL, + PRIMARY KEY (`id`) +); \ No newline at end of file From ba508f6b1874275972cc2573df76ad49198f0211 Mon Sep 17 00:00:00 2001 From: Mykhailo Kazarian Date: Sat, 6 Jul 2024 19:56:56 +0300 Subject: [PATCH 2/5] Creating dependencies for drivers --- pom.xml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pom.xml b/pom.xml index 683e84ec..d6035896 100644 --- a/pom.xml +++ b/pom.xml @@ -55,4 +55,11 @@ + + + com.mysql + mysql-connector-j + 9.0.0 + + From e78cc91c08d6f8ac8d3115cb790df472b96e6a46 Mon Sep 17 00:00:00 2001 From: Mykhailo Kazarian Date: Sat, 6 Jul 2024 19:57:40 +0300 Subject: [PATCH 3/5] jdbc-intro solution --- src/main/java/mate/academy/Main.java | 43 ++++++ src/main/java/mate/academy/dao/BookDao.java | 18 +++ .../java/mate/academy/dao/BookDaoImpl.java | 137 ++++++++++++++++++ src/main/java/mate/academy/models/Book.java | 27 ++++ 4 files changed, 225 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/models/Book.java diff --git a/src/main/java/mate/academy/Main.java b/src/main/java/mate/academy/Main.java index 0058fbf9..c1f0b5b5 100644 --- a/src/main/java/mate/academy/Main.java +++ b/src/main/java/mate/academy/Main.java @@ -1,7 +1,50 @@ package mate.academy; +import java.math.BigDecimal; +import java.util.List; +import mate.academy.dao.BookDao; +import mate.academy.lib.Injector; +import mate.academy.models.Book; + public class Main { + private static final Injector injector = Injector.getInstance("mate.academy.dao"); + public static void main(String[] args) { + BookDao bookDao = (BookDao) injector.getInstance(BookDao.class); + + bookDao.create(new Book(1L, "Java Programming", new BigDecimal("1000.00"))); + bookDao.create(new Book(2L, "Effective Java", new BigDecimal("1500.00"))); + bookDao.create(new Book(3L, "Clean Code", new BigDecimal("2000.00"))); + bookDao.create(new Book(4L, "Head First Java", new BigDecimal("2500.00"))); + bookDao.create(new Book(5L, "Java Concurrency in Practice", new BigDecimal("3000.00"))); + + System.out.println("FULL list of books"); + List list = bookDao.findAll(); + for (Book book : list) { + System.out.println(book.getId() + " " + book.getTitle() + " " + book.getPrice()); + } + + System.out.println("\n" + "Finding book by index:" + list.get(0).getId()); + Book book1 = bookDao.findById(list.get(0).getId()) + .orElseThrow(() -> + new RuntimeException("Objects with the specified ID do not exist")); + System.out.println(book1.getId() + " " + book1.getTitle() + " " + book1.getPrice()); + + System.out.println("\n" + "Updating book by index:" + list.get(0).getId()); + bookDao.update(new Book(list.get(0).getId(), "Nikilen", new BigDecimal(100))); + + Book book2 = bookDao.findById(list.get(0).getId()) + .orElseThrow(() -> + new RuntimeException("Objects with the specified ID do not exist")); + + System.out.println(book2.getId() + " " + book2.getTitle() + " " + book2.getPrice()); + + System.out.println("\n" + "Deleting an object by index:" + list.get(0).getId()); + if (bookDao.deleteById(list.get(0).getId())) { + System.out.println("The object is deleted"); + } else { + System.out.println("The object does not exist"); + } } } 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..c3a06963 --- /dev/null +++ b/src/main/java/mate/academy/dao/BookDao.java @@ -0,0 +1,18 @@ +package mate.academy.dao; + +import java.util.List; +import java.util.Optional; +import mate.academy.models.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..99e0a2de --- /dev/null +++ b/src/main/java/mate/academy/dao/BookDaoImpl.java @@ -0,0 +1,137 @@ +package mate.academy.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.sql.Statement; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import mate.academy.lib.Dao; +import mate.academy.models.Book; + +@Dao +public class BookDaoImpl implements BookDao { + private static final String URL = "jdbc:mysql://localhost:3306/test"; + private static final String USER = "root"; + private static final String PASSWORD = "henghfdf"; + + @Override + public Book create(Book book) { + String sqlCommand = "INSERT INTO books (title,price) VALUE (?,?)"; + + try (Connection connection = DriverManager.getConnection(URL, USER, PASSWORD); + PreparedStatement preparedStatement = + connection.prepareStatement(sqlCommand, Statement.RETURN_GENERATED_KEYS)) { + + preparedStatement.setString(1, book.getTitle()); + preparedStatement.setBigDecimal(2, book.getPrice()); + + int affectedRows = preparedStatement.executeUpdate(); + if (affectedRows < 1) { + throw new RuntimeException("None of the rows have been added"); + } + + try (ResultSet generatedKeys = preparedStatement.getGeneratedKeys()) { + if (generatedKeys.next()) { + long id = generatedKeys.getLong(1); + return new Book(id, book.getTitle(), book.getPrice()); + } else { + throw new RuntimeException("Failed to retrieve the generated key"); + } + } + } catch (SQLException e) { + throw new RuntimeException("Cannot create a connection to the DB", e); + } + } + + @Override + public Optional findById(Long id) { + String sqlCommand = "SELECT * FROM books WHERE id = ?"; + + try (Connection connection = DriverManager.getConnection(URL, USER, PASSWORD); + PreparedStatement preparedStatement = connection.prepareStatement(sqlCommand)) { + preparedStatement.setLong(1, id); + + try (ResultSet resultSet = preparedStatement.executeQuery()) { + if (resultSet.next()) { + String title = resultSet.getObject("title", String.class); + BigDecimal price = resultSet.getObject("price", BigDecimal.class); + + return Optional.of(new Book(id, title, price)); + } + } + } catch (SQLException e) { + throw new RuntimeException("Cannot create a connection to the DB", e); + } + + return Optional.empty(); + } + + @Override + public List findAll() { + String sqlCommand = "SELECT * FROM books"; + List result = new ArrayList<>(); + + try (Connection connection = DriverManager.getConnection(URL, USER, PASSWORD); + PreparedStatement preparedStatement = connection.prepareStatement(sqlCommand); + ResultSet resultSet = preparedStatement.executeQuery()) { + + while (resultSet.next()) { + Long id = resultSet.getObject("id", Long.class); + String title = resultSet.getObject("title", String.class); + BigDecimal price = resultSet.getObject("price", BigDecimal.class); + + result.add(new Book(id, title, price)); + } + + } catch (SQLException e) { + throw new RuntimeException("Cannot create a connection to the DB", e); + } + + return result; + } + + @Override + public Book update(Book book) { + String sqlCommand = "UPDATE books SET title=?, price=? WHERE id = ?"; + + try (Connection connection = DriverManager.getConnection(URL, USER, PASSWORD); + PreparedStatement preparedStatement = connection.prepareStatement(sqlCommand)) { + + 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("None of the rows have been updated"); + } + + return book; + + } catch (SQLException e) { + throw new RuntimeException("Cannot create a connection to the DB", e); + } + } + + @Override + public boolean deleteById(Long id) { + String sqlCommand = "DELETE FROM books WHERE id = ?"; + + try (Connection connection = DriverManager.getConnection(URL, USER, PASSWORD); + PreparedStatement preparedStatement = connection.prepareStatement(sqlCommand)) { + + preparedStatement.setLong(1, id); + + int affectedRows = preparedStatement.executeUpdate(); + return affectedRows > 0; + + } catch (SQLException e) { + throw new RuntimeException("Cannot create a connection to the DB", e); + } + } +} diff --git a/src/main/java/mate/academy/models/Book.java b/src/main/java/mate/academy/models/Book.java new file mode 100644 index 00000000..9cd3d9cd --- /dev/null +++ b/src/main/java/mate/academy/models/Book.java @@ -0,0 +1,27 @@ +package mate.academy.models; + +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 String getTitle() { + return title; + } + + public BigDecimal getPrice() { + return price; + } +} From 964d4012f457ce39f28accb431aad694c4c14db6 Mon Sep 17 00:00:00 2001 From: Mykhailo Kazarian Date: Wed, 10 Jul 2024 12:11:33 +0300 Subject: [PATCH 4/5] jdbc-intro solution (first fix) --- src/main/java/mate/academy/dao/BookDao.java | 1 - .../java/mate/academy/dao/BookDaoImpl.java | 56 +++++++++---------- .../java/mate/academy/dao/ConnectionUtil.java | 22 ++++++++ .../academy/dao/DataProcessingException.java | 12 ++++ src/main/java/mate/academy/models/Book.java | 12 ++++ src/main/resources/init_db.sql | 2 +- 6 files changed, 73 insertions(+), 32 deletions(-) create mode 100644 src/main/java/mate/academy/dao/ConnectionUtil.java create mode 100644 src/main/java/mate/academy/dao/DataProcessingException.java diff --git a/src/main/java/mate/academy/dao/BookDao.java b/src/main/java/mate/academy/dao/BookDao.java index c3a06963..b47ae78f 100644 --- a/src/main/java/mate/academy/dao/BookDao.java +++ b/src/main/java/mate/academy/dao/BookDao.java @@ -14,5 +14,4 @@ public interface BookDao { 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 index 99e0a2de..bea983b7 100644 --- a/src/main/java/mate/academy/dao/BookDaoImpl.java +++ b/src/main/java/mate/academy/dao/BookDaoImpl.java @@ -2,7 +2,6 @@ import java.math.BigDecimal; import java.sql.Connection; -import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; @@ -15,15 +14,11 @@ @Dao public class BookDaoImpl implements BookDao { - private static final String URL = "jdbc:mysql://localhost:3306/test"; - private static final String USER = "root"; - private static final String PASSWORD = "henghfdf"; - @Override public Book create(Book book) { String sqlCommand = "INSERT INTO books (title,price) VALUE (?,?)"; - try (Connection connection = DriverManager.getConnection(URL, USER, PASSWORD); + try (Connection connection = ConnectionUtil.getConnection(); PreparedStatement preparedStatement = connection.prepareStatement(sqlCommand, Statement.RETURN_GENERATED_KEYS)) { @@ -32,19 +27,20 @@ public Book create(Book book) { int affectedRows = preparedStatement.executeUpdate(); if (affectedRows < 1) { - throw new RuntimeException("None of the rows have been added"); + throw new DataProcessingException("None of the rows have been added"); } try (ResultSet generatedKeys = preparedStatement.getGeneratedKeys()) { if (generatedKeys.next()) { - long id = generatedKeys.getLong(1); - return new Book(id, book.getTitle(), book.getPrice()); + long id = generatedKeys.getObject(1, Long.class); + book.setId(id); + return book; } else { - throw new RuntimeException("Failed to retrieve the generated key"); + throw new DataProcessingException("Failed to retrieve the generated key"); } } } catch (SQLException e) { - throw new RuntimeException("Cannot create a connection to the DB", e); + throw new DataProcessingException("Cannot create a connection to the DB", e); } } @@ -52,22 +48,18 @@ public Book create(Book book) { public Optional findById(Long id) { String sqlCommand = "SELECT * FROM books WHERE id = ?"; - try (Connection connection = DriverManager.getConnection(URL, USER, PASSWORD); + try (Connection connection = ConnectionUtil.getConnection(); PreparedStatement preparedStatement = connection.prepareStatement(sqlCommand)) { preparedStatement.setLong(1, id); try (ResultSet resultSet = preparedStatement.executeQuery()) { if (resultSet.next()) { - String title = resultSet.getObject("title", String.class); - BigDecimal price = resultSet.getObject("price", BigDecimal.class); - - return Optional.of(new Book(id, title, price)); + return Optional.of(getBookFromResultSet(resultSet)); } } } catch (SQLException e) { - throw new RuntimeException("Cannot create a connection to the DB", e); + throw new DataProcessingException("Cannot create a connection to the DB", e); } - return Optional.empty(); } @@ -76,20 +68,16 @@ public List findAll() { String sqlCommand = "SELECT * FROM books"; List result = new ArrayList<>(); - try (Connection connection = DriverManager.getConnection(URL, USER, PASSWORD); + try (Connection connection = ConnectionUtil.getConnection(); PreparedStatement preparedStatement = connection.prepareStatement(sqlCommand); ResultSet resultSet = preparedStatement.executeQuery()) { while (resultSet.next()) { - Long id = resultSet.getObject("id", Long.class); - String title = resultSet.getObject("title", String.class); - BigDecimal price = resultSet.getObject("price", BigDecimal.class); - - result.add(new Book(id, title, price)); + result.add(getBookFromResultSet(resultSet)); } } catch (SQLException e) { - throw new RuntimeException("Cannot create a connection to the DB", e); + throw new DataProcessingException("Cannot create a connection to the DB", e); } return result; @@ -99,7 +87,7 @@ public List findAll() { public Book update(Book book) { String sqlCommand = "UPDATE books SET title=?, price=? WHERE id = ?"; - try (Connection connection = DriverManager.getConnection(URL, USER, PASSWORD); + try (Connection connection = ConnectionUtil.getConnection(); PreparedStatement preparedStatement = connection.prepareStatement(sqlCommand)) { preparedStatement.setString(1, book.getTitle()); @@ -108,13 +96,13 @@ public Book update(Book book) { int affectedRows = preparedStatement.executeUpdate(); if (affectedRows < 1) { - throw new RuntimeException("None of the rows have been updated"); + throw new DataProcessingException("None of the rows have been updated"); } return book; } catch (SQLException e) { - throw new RuntimeException("Cannot create a connection to the DB", e); + throw new DataProcessingException("Cannot create a connection to the DB", e); } } @@ -122,7 +110,7 @@ public Book update(Book book) { public boolean deleteById(Long id) { String sqlCommand = "DELETE FROM books WHERE id = ?"; - try (Connection connection = DriverManager.getConnection(URL, USER, PASSWORD); + try (Connection connection = ConnectionUtil.getConnection(); PreparedStatement preparedStatement = connection.prepareStatement(sqlCommand)) { preparedStatement.setLong(1, id); @@ -131,7 +119,15 @@ public boolean deleteById(Long id) { return affectedRows > 0; } catch (SQLException e) { - throw new RuntimeException("Cannot create a connection to the DB", e); + throw new DataProcessingException("Cannot create a connection to the DB", e); } } + + private Book getBookFromResultSet(ResultSet resultSet) throws SQLException { + Long id = resultSet.getObject("id", Long.class); + String title = resultSet.getObject("title", String.class); + BigDecimal price = resultSet.getObject("price", BigDecimal.class); + + return new Book(id, title, price); + } } 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..49b8f78c --- /dev/null +++ b/src/main/java/mate/academy/dao/ConnectionUtil.java @@ -0,0 +1,22 @@ +package mate.academy.dao; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.util.Properties; + +public class ConnectionUtil { + + private static final String URL = "jdbc:mysql://localhost:3306/test"; + private static final Properties DB_PROPERTIES; + + static { + DB_PROPERTIES = new Properties(); + DB_PROPERTIES.put("user", "root"); + DB_PROPERTIES.put("password", "henghfdf"); + } + + public static Connection getConnection() throws SQLException { + return DriverManager.getConnection(URL, DB_PROPERTIES); + } +} diff --git a/src/main/java/mate/academy/dao/DataProcessingException.java b/src/main/java/mate/academy/dao/DataProcessingException.java new file mode 100644 index 00000000..62926376 --- /dev/null +++ b/src/main/java/mate/academy/dao/DataProcessingException.java @@ -0,0 +1,12 @@ +package mate.academy.dao; + +public class DataProcessingException extends RuntimeException { + public DataProcessingException(String message) { + super(message); + } + + public DataProcessingException(String message, Throwable cause) { + super(message, cause); + } +} + diff --git a/src/main/java/mate/academy/models/Book.java b/src/main/java/mate/academy/models/Book.java index 9cd3d9cd..8d0f2a87 100644 --- a/src/main/java/mate/academy/models/Book.java +++ b/src/main/java/mate/academy/models/Book.java @@ -13,6 +13,18 @@ public Book(Long id, String title, BigDecimal price) { this.price = price; } + public void setId(Long id) { + this.id = id; + } + + public void setTitle(String title) { + this.title = title; + } + + public void setPrice(BigDecimal price) { + this.price = price; + } + public Long getId() { return id; } diff --git a/src/main/resources/init_db.sql b/src/main/resources/init_db.sql index 93a111c6..2c95d888 100644 --- a/src/main/resources/init_db.sql +++ b/src/main/resources/init_db.sql @@ -1,5 +1,5 @@ CREATE TABLE `books`( - `id` INT NOT NULL AUTO_INCREMENT, + `id` BIGINT AUTO_INCREMENT, `title` VARCHAR(255), `price` DECIMAL, PRIMARY KEY (`id`) From d06daa0b44b3f29f80c5a5c36ab678d40b33a2a6 Mon Sep 17 00:00:00 2001 From: Mykhailo Kazarian Date: Thu, 11 Jul 2024 22:43:07 +0300 Subject: [PATCH 5/5] jdbc-intro solution (second fix) --- src/main/java/mate/academy/dao/BookDaoImpl.java | 12 +++++++----- .../{dao => exceptions}/DataProcessingException.java | 2 +- .../mate/academy/{dao => util}/ConnectionUtil.java | 2 +- 3 files changed, 9 insertions(+), 7 deletions(-) rename src/main/java/mate/academy/{dao => exceptions}/DataProcessingException.java (88%) rename src/main/java/mate/academy/{dao => util}/ConnectionUtil.java (95%) diff --git a/src/main/java/mate/academy/dao/BookDaoImpl.java b/src/main/java/mate/academy/dao/BookDaoImpl.java index bea983b7..ebc2f6e1 100644 --- a/src/main/java/mate/academy/dao/BookDaoImpl.java +++ b/src/main/java/mate/academy/dao/BookDaoImpl.java @@ -9,8 +9,10 @@ import java.util.ArrayList; import java.util.List; import java.util.Optional; +import mate.academy.exceptions.DataProcessingException; import mate.academy.lib.Dao; import mate.academy.models.Book; +import mate.academy.util.ConnectionUtil; @Dao public class BookDaoImpl implements BookDao { @@ -40,7 +42,7 @@ public Book create(Book book) { } } } catch (SQLException e) { - throw new DataProcessingException("Cannot create a connection to the DB", e); + throw new DataProcessingException("Can't add a book", e); } } @@ -58,7 +60,7 @@ public Optional findById(Long id) { } } } catch (SQLException e) { - throw new DataProcessingException("Cannot create a connection to the DB", e); + throw new DataProcessingException("Can't find book by id", e); } return Optional.empty(); } @@ -77,7 +79,7 @@ public List findAll() { } } catch (SQLException e) { - throw new DataProcessingException("Cannot create a connection to the DB", e); + throw new DataProcessingException("Can't find all books", e); } return result; @@ -102,7 +104,7 @@ public Book update(Book book) { return book; } catch (SQLException e) { - throw new DataProcessingException("Cannot create a connection to the DB", e); + throw new DataProcessingException("Can't update book", e); } } @@ -119,7 +121,7 @@ public boolean deleteById(Long id) { return affectedRows > 0; } catch (SQLException e) { - throw new DataProcessingException("Cannot create a connection to the DB", e); + throw new DataProcessingException("Can't delete book by id", e); } } diff --git a/src/main/java/mate/academy/dao/DataProcessingException.java b/src/main/java/mate/academy/exceptions/DataProcessingException.java similarity index 88% rename from src/main/java/mate/academy/dao/DataProcessingException.java rename to src/main/java/mate/academy/exceptions/DataProcessingException.java index 62926376..ae3a0b25 100644 --- a/src/main/java/mate/academy/dao/DataProcessingException.java +++ b/src/main/java/mate/academy/exceptions/DataProcessingException.java @@ -1,4 +1,4 @@ -package mate.academy.dao; +package mate.academy.exceptions; public class DataProcessingException extends RuntimeException { public DataProcessingException(String message) { diff --git a/src/main/java/mate/academy/dao/ConnectionUtil.java b/src/main/java/mate/academy/util/ConnectionUtil.java similarity index 95% rename from src/main/java/mate/academy/dao/ConnectionUtil.java rename to src/main/java/mate/academy/util/ConnectionUtil.java index 49b8f78c..93151965 100644 --- a/src/main/java/mate/academy/dao/ConnectionUtil.java +++ b/src/main/java/mate/academy/util/ConnectionUtil.java @@ -1,4 +1,4 @@ -package mate.academy.dao; +package mate.academy.util; import java.sql.Connection; import java.sql.DriverManager;