Skip to content

Commit

Permalink
Create bookDaoImpl
Browse files Browse the repository at this point in the history
  • Loading branch information
ConfusedSatlan committed Aug 11, 2023
1 parent 96f414d commit 080722d
Show file tree
Hide file tree
Showing 8 changed files with 287 additions and 1 deletion.
8 changes: 8 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,12 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>
</dependencies>

</project>
27 changes: 27 additions & 0 deletions src/main/java/mate/academy/ConnectionUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package mate.academy;

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/books";
private static final Properties DB_PROPERTIES;

static {
DB_PROPERTIES = new Properties();
DB_PROPERTIES.put("user", "root");
DB_PROPERTIES.put("password", "S13o28N24m23$");

try {
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
throw new RuntimeException("Can't load JDBC driver" , e);
}
}

public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(DB_URL, DB_PROPERTIES);
}
}
21 changes: 20 additions & 1 deletion src/main/java/mate/academy/Main.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,26 @@
package mate.academy;

import mate.academy.dao.BookDao;
import mate.academy.lib.Injector;
import mate.academy.model.Book;

import java.math.BigDecimal;
import java.util.List;
import java.util.Optional;

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);
Book book = new Book();
List<Book> all = bookDao.findAll();
book.setId(2L);
book.setTitle("MERS");
book.setPrice(BigDecimal.valueOf(245.32));
bookDao.update(book);
all.forEach(System.out::println);
bookDao.deleteById(2L);
all = bookDao.findAll();
all.forEach(System.out::println);
}
}
14 changes: 14 additions & 0 deletions src/main/java/mate/academy/dao/BookDao.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
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<Book> findById(Long id);
List<Book> findAll();
Book update(Book book);
boolean deleteById(Long id);
}
158 changes: 158 additions & 0 deletions src/main/java/mate/academy/dao/BookDaoImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
package mate.academy.dao;

import mate.academy.ConnectionUtil;
import mate.academy.exception.DataProcessingException;
import mate.academy.model.Book;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
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;

@mate.academy.lib.Dao
public class BookDaoImpl implements BookDao {
private static final String TABLE_NAME = "books";
private static final String TITLE_NAME = "title";
private static final String PRICE_NAME = "price";
private static final int FIRST_INDEX = 1;
private static final int SECOND_INDEX = 2;
private static final int THIRD_INDEX = 3;
private static final int ROW_EXIST_NUM = 1;

@Override
public Book create(Book book) {
String sql = "INSERT INTO " + TABLE_NAME + " (title, price) VALUES (?, ?)";
try (Connection connection = ConnectionUtil.getConnection();
PreparedStatement statement = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
validateTableConnection(connection, TABLE_NAME);
statement.setString(FIRST_INDEX, book.getTitle());
statement.setBigDecimal(SECOND_INDEX, book.getPrice());
int affectedRows = statement.executeUpdate();
if (affectedRows < ROW_EXIST_NUM) {
throw new DataProcessingException("Expected to insert at leas one row, but inserted 0 row.");
}
ResultSet generatedKeys = statement.getGeneratedKeys();
if (generatedKeys.next()) {
Long id = generatedKeys.getObject(FIRST_INDEX, Long.class);
book.setId(id);
}
} catch (SQLException e) {
throw new DataProcessingException("Can't add new book: " + book, e);
}
return book;
}

@Override
public Optional<Book> findById(Long id) {
String sql = "SELECT * FROM " + TABLE_NAME + " WHERE id = ?";
try (Connection connection = ConnectionUtil.getConnection();
PreparedStatement statement = connection.prepareStatement(sql)) {
validateTableConnection(connection, TABLE_NAME);
statement.setLong(FIRST_INDEX, id);
ResultSet resultSet = statement.executeQuery();
if (resultSet.next()) {
String title = resultSet.getString(TITLE_NAME);
BigDecimal price = resultSet.getObject(PRICE_NAME, BigDecimal.class);
Book book = new Book();
book.setId(id);
book.setTitle(title);
book.setPrice(price);
return Optional.of(book);
}
} catch (SQLException e) {
throw new RuntimeException("Can't create a connection to the DB" ,e);
}
return Optional.empty();
}

@Override
public List<Book> findAll() {
String sql = "SELECT * FROM " + TABLE_NAME;
try (Connection connection = ConnectionUtil.getConnection();
Statement statement = connection.createStatement()) {
ResultSet resultSet = statement.executeQuery(sql);
List<Book> allBooks = new ArrayList<>();
while (resultSet.next()) {
Long id = resultSet.getObject(FIRST_INDEX, Long.class);
String title = resultSet.getString(TITLE_NAME);
BigDecimal price = resultSet.getObject(PRICE_NAME, BigDecimal.class);
Book book = new Book();
book.setId(id);
book.setTitle(title);
book.setPrice(price);
allBooks.add(book);
}
return allBooks;
} catch (SQLException e) {
throw new RuntimeException("Can't create a connection to the DB" ,e);
}
}

@Override
public Book update(Book book) {
String sql = "UPDATE " + TABLE_NAME + " SET title = ?, price = ? WHERE id = ?";
try (Connection connection = ConnectionUtil.getConnection();
PreparedStatement statement = connection.prepareStatement(sql)) {
validateTableConnection(connection, TABLE_NAME);
statement.setString(FIRST_INDEX, book.getTitle());
statement.setBigDecimal(SECOND_INDEX, book.getPrice());
statement.setLong(THIRD_INDEX, book.getId());
int affectedRows = statement.executeUpdate();
if (affectedRows < ROW_EXIST_NUM) {
throw new DataProcessingException("Expected to insert at leas one row, but inserted 0 row.");
}
return book;
} catch (SQLException e) {
throw new DataProcessingException("Can't update new book: " + book, e);
}
}

@Override
public boolean deleteById(Long id) {
String sql = "DELETE FROM " + TABLE_NAME + " WHERE id = ?";
try (Connection connection = ConnectionUtil.getConnection();
PreparedStatement statement = connection.prepareStatement(sql)) {
validateTableConnection(connection, TABLE_NAME);
statement.setLong(FIRST_INDEX, id);
int affectedRows = statement.executeUpdate();
if (affectedRows < ROW_EXIST_NUM) {
throw new DataProcessingException("Expected to insert at leas one row, but inserted 0 row.");
}
return affectedRows >= 1;
} catch (SQLException e) {
throw new DataProcessingException("Can't delete book by id: " + id, e);
}
}

private static boolean tableExists(Connection connection ,String tableName) throws SQLException {
DatabaseMetaData metaData = connection.getMetaData();
try (var resultSet = metaData.getTables(null, null, tableName, null)) {
return resultSet.next();
}
}

private void validateTableConnection(Connection connection, String tableName) throws SQLException {
if (connection == null) {
throw new DataProcessingException("Connection can't be null");
}
if (tableName == null) {
throw new DataProcessingException("TableName can't be null");
}
if (tableName.isEmpty()) {
throw new DataProcessingException("TableName can't be empty");
}
if (!tableExists(connection, tableName)) {
throw new DataProcessingException("Table: " + tableName + " is not exist");
}
}
}
11 changes: 11 additions & 0 deletions src/main/java/mate/academy/exception/DataProcessingException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package mate.academy.exception;

public class DataProcessingException extends RuntimeException {
public DataProcessingException(String message) {
super(message);
}

public DataProcessingException(String message, Throwable ex) {
super(message, ex);
}
}
44 changes: 44 additions & 0 deletions src/main/java/mate/academy/model/Book.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package mate.academy.model;

import mate.academy.lib.Dao;

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 +
'}';
}
}
5 changes: 5 additions & 0 deletions src/main/resources/init_db.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
CREATE TABLE books (
id INT AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(50) NOT NULL,
price DECIMAL(10, 2) NOT NULL
);

0 comments on commit 080722d

Please sign in to comment.