diff --git a/pom.xml b/pom.xml index 526fbcf3..cd5f57ad 100644 --- a/pom.xml +++ b/pom.xml @@ -14,4 +14,12 @@ UTF-8 + + + com.mysql + mysql-connector-j + 8.0.33 + + + diff --git a/src/main/java/mate/academy/Main.java b/src/main/java/mate/academy/Main.java index 0058fbf9..90c66b38 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; + public class Main { + public static final Injector injector = Injector.getInstance("mate.academy"); + public static void main(String[] args) { + BookDao bookDao = (BookDao) injector.getInstance(BookDao.class); + Book mist = new Book(); + mist.setTitle("Mist"); + mist.setPrice(BigDecimal.valueOf(100)); + bookDao.create(mist); + mist.setTitle("Mist by S.King"); + mist.setPrice(BigDecimal.valueOf(101)); + bookDao.update(mist); + System.out.println(bookDao.findById(mist.getId())); + bookDao.findAll().forEach(System.out::println); + System.out.println("delete successful: " + bookDao.deleteById(mist.getId())); } } 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..5c3db0dd --- /dev/null +++ b/src/main/java/mate/academy/dao/BookDao.java @@ -0,0 +1,17 @@ +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); +} 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..4c59ef45 --- /dev/null +++ b/src/main/java/mate/academy/dao/impl/BookDaoImpl.java @@ -0,0 +1,132 @@ +package mate.academy.dao.impl; + +import mate.academy.dao.BookDao; +import mate.academy.exception.DataProcessingException; +import mate.academy.lib.Dao; +import mate.academy.model.Book; +import mate.academy.util.ConnectionUtil; +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; + +@Dao +public class BookDaoImpl implements BookDao { + @Override + public Book create(Book book) { + String insertBookQuery = "INSERT INTO books(title, price) values(?, ?);"; + try (Connection connection = ConnectionUtil.getConnection(); + PreparedStatement createBookStatement = + connection.prepareStatement( + insertBookQuery, Statement.RETURN_GENERATED_KEYS)) { + + createBookStatement.setString(1, book.getTitle()); + createBookStatement.setObject( + 2, book.getPrice()); + createBookStatement.executeUpdate(); + ResultSet generatedKeys = createBookStatement.getGeneratedKeys(); + if (generatedKeys.next()) { + Long id = generatedKeys.getObject(1, Long.class); + book.setId(id); + } + } catch (SQLException e) { + throw new DataProcessingException("Can`t insert book to DB" + book, e); + } + return book; + } + + @Override + public Optional findById(Long id) { + String findByIdQuery = "SELECT * FROM books " + + "WHERE is_deleted = 'FALSE' AND id = ?;"; + Book book = null; + try (Connection connection = ConnectionUtil.getConnection(); + PreparedStatement findByIdStatement = + connection.prepareStatement(findByIdQuery)) { + + findByIdStatement.setLong(1, id); + ResultSet resultSet = findByIdStatement.executeQuery(); + while (resultSet.next()) { + if (resultSet.getObject("id", Long.class).equals(id)) { + book = getBookFromResultSet(resultSet); + } + } + } catch (SQLException e) { + throw new DataProcessingException( + "Can`t find book by id from DB. id = " + id, e); + } + return Optional.ofNullable(book); + } + + @Override + public List findAll() { + String getAllQuery = "SELECT * FROM books " + + "WHERE is_deleted = 'FALSE';"; + List books = new ArrayList<>(); + try (Connection connection = ConnectionUtil.getConnection(); + PreparedStatement findAllBooksStatement = + connection.prepareStatement(getAllQuery)) { + ResultSet resultSet = findAllBooksStatement.executeQuery(); + while (resultSet.next()) { + Book bookFromResultSet = + getBookFromResultSet(resultSet); + books.add(bookFromResultSet); + } + } catch (SQLException e) { + throw new DataProcessingException( + "Can`t find all books from DB" + books, e); + } + return books; + } + + @Override + public Book update(Book book) { + String updateQuery = + "UPDATE books SET title = ?, price = ? " + + "WHERE is_deleted = FALSE AND id = ?;"; + try (Connection connection = ConnectionUtil.getConnection(); + PreparedStatement updateBookStatement = + connection.prepareStatement(updateQuery)) { + + updateBookStatement.setString(1, book.getTitle()); + updateBookStatement.setObject( + 2, book.getPrice()); + updateBookStatement.setLong(3, book.getId()); + updateBookStatement.executeUpdate(); + } catch (SQLException e) { + throw new DataProcessingException("Can`t update book: " + book, e); + } + return book; + } + + @Override + public boolean deleteById(Long id) { + String deleteQuery = "UPDATE books SET is_deleted = TRUE " + + "WHERE id = ?;"; + try (Connection connection = ConnectionUtil.getConnection(); + PreparedStatement deleteBookStatement = + connection.prepareStatement(deleteQuery)) { + deleteBookStatement.setLong(1, id); + return deleteBookStatement.executeUpdate() > 0; + } catch (SQLException e) { + throw new DataProcessingException( + "Can`t delete book by id from DB. 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.getObject("price", BigDecimal.class); + Book book = new Book(); + book.setId(id); + book.setTitle(title); + book.setPrice(price); + return book; + } +} 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..ea206058 --- /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 ex) { + super(message, ex); + } +} 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..f6e4b030 --- /dev/null +++ b/src/main/java/mate/academy/model/Book.java @@ -0,0 +1,46 @@ +package mate.academy.model; + +import java.math.BigDecimal; + +public class Book { + private Long id; + private String title; + private BigDecimal 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/util/ConnectionUtil.java b/src/main/java/mate/academy/util/ConnectionUtil.java new file mode 100644 index 00000000..2d546fa7 --- /dev/null +++ b/src/main/java/mate/academy/util/ConnectionUtil.java @@ -0,0 +1,33 @@ +package mate.academy.util; + +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/books"; + private static final String USERNAME = "root"; + private static final String PASSWORD = "2121105"; + private static final String JDBC_DRIVER = "com.mysql.cj.jdbc.Driver"; + + static { + try { + Class.forName(JDBC_DRIVER); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } + + public static Connection getConnection() { + try { + Properties dbProperties = new Properties(); + dbProperties.put("user", USERNAME); + dbProperties.put("password", PASSWORD); + return DriverManager.getConnection( + URL, dbProperties); + } catch (SQLException e) { + throw new RuntimeException("Can`t create connection to DB", e); + } + } +} diff --git a/src/main/resources/init_db.sql b/src/main/resources/init_db.sql new file mode 100644 index 00000000..7c6b4a79 --- /dev/null +++ b/src/main/resources/init_db.sql @@ -0,0 +1,9 @@ +CREATE DATABASE `books` + +CREATE TABLE `books`( + `id` bigint NOT NULL AUTO_INCREMENT, + `title` varchar(45) DEFAULT NULL, + `price` bigint DEFAULT NULL, + `is_deleted` tinyint(1) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8mb3;