diff --git a/pom.xml b/pom.xml index 526fbcf3..8c843598 100644 --- a/pom.xml +++ b/pom.xml @@ -9,9 +9,51 @@ 1.0-SNAPSHOT + 17 17 17 UTF-8 + + https://raw.githubusercontent.com/mate-academy/style-guides/master/java/checkstyle.xml + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + 3.1.1 + + + compile + + check + + + + + ${maven.checkstyle.plugin.configLocation} + UTF-8 + true + true + false + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.0 + + ${jdk.version} + ${jdk.version} + ${project.build.sourceEncoding} + + + + + diff --git a/src/main/java/mate/academy/Main.java b/src/main/java/mate/academy/Main.java index 0058fbf9..415bbfad 100644 --- a/src/main/java/mate/academy/Main.java +++ b/src/main/java/mate/academy/Main.java @@ -1,7 +1,28 @@ package mate.academy; +import java.math.BigDecimal; +import java.util.List; +import java.util.Optional; +import mate.academy.dao.BookDao; +import mate.academy.lib.Injector; +import mate.academy.model.Book; + public class Main { - public static void main(String[] args) { + private static final Injector injector = Injector.getInstance("mate.academy"); + public static void main(String[] args) { + BookDao bookDao = (BookDao) injector.getInstance(BookDao.class); + Book book = new Book(); + book.setPrice(BigDecimal.valueOf(10)); + book.setTitle("Testing"); + Book savedBook = bookDao.create(book); + List all = bookDao.findAll(); + Optional bookOptional = bookDao.findById(savedBook.getId()); + System.out.println(bookOptional.get().getTitle()); + Book toUpdateBook = new Book(); + toUpdateBook.setPrice(BigDecimal.valueOf(15)); + toUpdateBook.setTitle("Testing2"); + bookDao.update(book); + bookDao.deleteById(savedBook.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..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..0852c1d4 --- /dev/null +++ b/src/main/java/mate/academy/dao/BookDaoImpl.java @@ -0,0 +1,127 @@ +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.sql.Statement; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import mate.academy.exception.DataProcessingException; +import mate.academy.lib.ConnectionUtil; +import mate.academy.lib.Dao; +import mate.academy.model.Book; + +@Dao +public class BookDaoImpl implements BookDao { + private static final int ID_INDEX = 1; + private static final int TITLE_INDEX = 1; + private static final int PRICE_INDEX = 2; + private static final int MINIMAL_OPERATION_AMOUNT = 1; + + @Override + public Book create(Book book) { + String insertQuery = "INSERT INTO book(title, price)" + + " values(?,?)"; + try (Connection connection = ConnectionUtil.getConnection(); + PreparedStatement creationStatement = connection.prepareStatement(insertQuery, + Statement.RETURN_GENERATED_KEYS)) { + creationStatement.setString(TITLE_INDEX, book.getTitle()); + creationStatement.setBigDecimal(PRICE_INDEX, book.getPrice()); + creationStatement.executeUpdate(); + ResultSet generatedKeys = creationStatement.getGeneratedKeys(); + if (generatedKeys.next()) { + Long id = generatedKeys.getObject(ID_INDEX, Long.class); + book.setId(id); + } + } catch (SQLException e) { + throw new DataProcessingException("can't get connection to db", e); + } + return book; + } + + @Override + public Optional findById(Long id) { + String selectRequest = "SELECT * FROM book WHERE id = ? AND is_deleted = FALSE"; + try (Connection connection = ConnectionUtil.getConnection(); + PreparedStatement selectStatement = + connection.prepareStatement(selectRequest)) { + selectStatement.setLong(ID_INDEX, id); + selectStatement.executeQuery(); + ResultSet generatedKeys = selectStatement.executeQuery(); + return Optional.of(parseResultSet(generatedKeys)); + } catch (SQLException e) { + throw new DataProcessingException("can't get book from DB " + id, e); + } + } + + @Override + public List findAll() { + List allBooks = new ArrayList<>(); + String selectRequest = "SELECT * FROM Book WHERE is_deleted = FALSE"; + try (Connection connection = ConnectionUtil.getConnection(); Statement getAllStatement = + connection.createStatement()) { + ResultSet resultSet = getAllStatement.executeQuery(selectRequest); + while (resultSet.next()) { + allBooks.add(parseResultSet(resultSet)); + } + } catch (SQLException e) { + throw new DataProcessingException("can't get all books from DB ", e); + } + return allBooks; + } + + @Override + public Book update(Book book) { + String updateRequest = "UPDATE Book SET title = ?, price = ?" + + " WHERE id = ? AND is_deleted = FALSE"; + int idPosition = 3; + try (Connection connection = ConnectionUtil.getConnection(); + PreparedStatement updateStatement = + connection.prepareStatement(updateRequest, Statement + .RETURN_GENERATED_KEYS)) { + updateStatement.setLong(idPosition, book.getId()); + updateStatement.setString(TITLE_INDEX, book.getTitle()); + updateStatement.setBigDecimal(PRICE_INDEX, book.getPrice()); + updateStatement.executeUpdate(); + } catch (SQLException e) { + throw new DataProcessingException("can't update book: " + + book + " in DB ", e); + } + return book; + } + + @Override + public boolean deleteById(Long id) { + String deleteRequest = "UPDATE Book SET is_deleted = TRUE WHERE id = ?"; + try (Connection connection = ConnectionUtil.getConnection(); + PreparedStatement deleteStatement = + connection.prepareStatement(deleteRequest, + Statement.RETURN_GENERATED_KEYS)) { + deleteStatement.setLong(ID_INDEX, id); + return deleteStatement.executeUpdate() >= MINIMAL_OPERATION_AMOUNT; + } catch (SQLException e) { + throw new DataProcessingException("can't delete book from DB with id: " + + id, e); + } + } + + private static Book parseResultSet(ResultSet set) { + Book book = new Book(); + try { + if (set.next()) { + Long id = set.getLong("id"); + String title = set.getString("title"); + BigDecimal price = set.getBigDecimal("price"); + book.setId(id); + book.setTitle(title); + book.setPrice(price); + } + return book; + } catch (SQLException e) { + throw new DataProcessingException("Can't get book from set " + set, e); + } + } +} 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/ConnectionUtil.java b/src/main/java/mate/academy/lib/ConnectionUtil.java new file mode 100644 index 00000000..2b238a89 --- /dev/null +++ b/src/main/java/mate/academy/lib/ConnectionUtil.java @@ -0,0 +1,29 @@ +package mate.academy.lib; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.util.Properties; +import mate.academy.exception.DataProcessingException; + +public class ConnectionUtil { + static { + try { + Class.forName("com.mysql.cj.jdbc.Driver"); + } catch (ClassNotFoundException e) { + throw new DataProcessingException("can't create a jdbc driver ", e); + } + } + + public static Connection getConnection() { + try { + Properties dbProperties = new Properties(); + dbProperties.put("user", "root"); + dbProperties.put("password", "12345678"); + return DriverManager + .getConnection("jdbc:mysql://localhost:3306/test", dbProperties); + } catch (SQLException e) { + throw new DataProcessingException("can't create connection to DB ", e); + } + } +} 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..c837ac48 --- /dev/null +++ b/src/main/java/mate/academy/model/Book.java @@ -0,0 +1,33 @@ +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; + } +} diff --git a/src/main/resources/init_db.sql b/src/main/resources/init_db.sql new file mode 100644 index 00000000..a4c559d1 --- /dev/null +++ b/src/main/resources/init_db.sql @@ -0,0 +1,7 @@ +CREATE TABLE `Book` ( + `id` int NOT NULL AUTO_INCREMENT, + `title` varchar(45) NOT NULL, + `price` DECIMAL DEFAULT NULL, + `is_deleted` tinyint NOT NULL DEFAULT '0', + PRIMARY KEY (`id`) +); \ No newline at end of file