Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added BookDao and connected project to db #53

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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>
32 changes: 32 additions & 0 deletions src/main/java/mate/academy/Main.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,39 @@
package mate.academy;

import java.math.BigDecimal;
import mate.academy.dao.BookDao;
import mate.academy.dao.BookDaoImpl;
import mate.academy.lib.Injector;
import mate.academy.model.Book;

nacenik marked this conversation as resolved.
Show resolved Hide resolved
public class Main {
public static void main(String[] args) {
Injector injector = Injector.getInstance("mate.academy");
BookDao bookDao = (BookDaoImpl) injector.getInstance(BookDao.class);

Book cleanCodeBook = new Book();
cleanCodeBook.setTitle("Clean Code");
cleanCodeBook.setPrice(BigDecimal.valueOf(29.99));
bookDao.create(cleanCodeBook);

Book colorOfMagicBook = new Book();
colorOfMagicBook.setTitle("The color of magic");
colorOfMagicBook.setPrice(BigDecimal.valueOf(69.99));
bookDao.create(colorOfMagicBook);

System.out.println(bookDao.findById(1L));

colorOfMagicBook.setPrice(BigDecimal.valueOf(6.99));
bookDao.update(colorOfMagicBook);

System.out.println(bookDao.findAll());

bookDao.deleteById(colorOfMagicBook.getId());

bookDao.findAll().stream()
.peek(b -> {
b.setPrice(b.getPrice().multiply(BigDecimal.valueOf(0.9)));
bookDao.update(b);
}).forEach(System.out::println);
}
}
17 changes: 17 additions & 0 deletions src/main/java/mate/academy/dao/BookDao.java
Original file line number Diff line number Diff line change
@@ -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<Book> findById(Long id);

List<Book> findAll();

Book update(Book book);

boolean deleteById(Long id);
}
129 changes: 129 additions & 0 deletions src/main/java/mate/academy/dao/BookDaoImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
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.Dao;
import mate.academy.model.Book;
import mate.academy.util.ConnectionUtil;

@Dao
public class BookDaoImpl implements BookDao {
private static final int ZERO_UPDATES = 0;
private static final int ID_INDEX = 1;
private static final int TITLE_INDEX = 2;
private static final int PRICE_INDEX = 3;
private static final int TITLE_INDEX_FOR_UPDATE_OPERATION = 1;
private static final int PRICE_INDEX_FOR_UPDATE_OPERATION = 2;
private static final int ID_INDEX_FOR_UPDATE_OPERATION = 3;
private static final String ID_COLUMN = "books.id";
private static final String TITLE_COLUMN = "books.title";
private static final String PRICE_COLUMN = "books.price";
private static final String NO_UPDATES_EXCEPTION_TEXT = "Expected to update at least 1 value, but updated 0 values.";
private static final String CREATING_BOOK_EXCEPTION_TEXT = "Can't save a book ";
private static final String FINDING_BOOK_BY_ID_EXCEPTION_TEXT = "Can't get a book by id = ";
private static final String GETTING_LIST_OF_ALL_BOOKS_EXCEPTION_TEXT = "Can't get a book list from db";
private static final String UPDATING_BOOK_EXCEPTION_TEXT = "Can't update book ";
private static final String DELETING_BOOK_BY_ID_EXCEPTION_TEXT = "Can't delete a book by id = ";

@Override
public Book create(Book book) {
try (Connection connection = ConnectionUtil.getConnection();
PreparedStatement statement = connection.prepareStatement("INSERT INTO books (id, title, price) VALUES (?, ?, ?)", Statement.RETURN_GENERATED_KEYS)) {

statement.setLong(ID_INDEX, book.getId());
statement.setString(TITLE_INDEX, book.getTitle());
statement.setBigDecimal(PRICE_INDEX, book.getPrice());

if (statement.executeUpdate() == ZERO_UPDATES) {
throw new RuntimeException(NO_UPDATES_EXCEPTION_TEXT);
}
ResultSet generatedKeys = statement.getGeneratedKeys();
if (generatedKeys.next()) {
Integer id = generatedKeys.getObject(ID_INDEX, Integer.class);
book.setId(id);
}
} catch (SQLException e) {
throw new DataProcessingException(CREATING_BOOK_EXCEPTION_TEXT + book, e);
}
return book;
}

@Override
public Optional<Book> findById(Long id) {
try (Connection connection = ConnectionUtil.getConnection();
PreparedStatement statement = connection.prepareStatement("SELECT * FROM books WHERE id = ?")) {

statement.setLong(ID_INDEX, id);
ResultSet resultSet = statement.executeQuery();
if (resultSet.next()) {
return Optional.of(parseBookFromQuery(resultSet));
}
return Optional.empty();
} catch (SQLException e) {
throw new DataProcessingException(FINDING_BOOK_BY_ID_EXCEPTION_TEXT + id, e);
}
}

@Override
public List<Book> findAll() {
try (Connection connection = ConnectionUtil.getConnection();
PreparedStatement statement = connection.prepareStatement("SELECT * FROM books")) {

ResultSet resultSet = statement.executeQuery();
List<Book> books = new ArrayList<>();
while (resultSet.next()) {
books.add(parseBookFromQuery(resultSet));
}
return books;
} catch (SQLException e) {
throw new DataProcessingException(GETTING_LIST_OF_ALL_BOOKS_EXCEPTION_TEXT, e);
}
}

@Override
public Book update(Book book) {
try (Connection connection = ConnectionUtil.getConnection();
PreparedStatement statement = connection.prepareStatement("UPDATE books SET title = ?, price = ? WHERE id = ?")) {

statement.setString(TITLE_INDEX_FOR_UPDATE_OPERATION, book.getTitle());
statement.setBigDecimal(PRICE_INDEX_FOR_UPDATE_OPERATION, book.getPrice());
statement.setLong(ID_INDEX_FOR_UPDATE_OPERATION, book.getId());

if (statement.executeUpdate() == ZERO_UPDATES) {
throw new RuntimeException(NO_UPDATES_EXCEPTION_TEXT);
}
} catch (SQLException e) {
throw new DataProcessingException(UPDATING_BOOK_EXCEPTION_TEXT + book, e);
}
return null;
}

@Override
public boolean deleteById(Long id) {
try (Connection connection = ConnectionUtil.getConnection();
PreparedStatement statement = connection.prepareStatement("DELETE FROM books WHERE id = ?")) {

statement.setLong(ID_INDEX, id);

return statement.executeUpdate() > ZERO_UPDATES;
} catch (SQLException e) {
throw new DataProcessingException(DELETING_BOOK_BY_ID_EXCEPTION_TEXT + id, e);
}
}

private Book parseBookFromQuery(ResultSet resultSet) throws SQLException{
Book book = new Book();
book.setId(resultSet.getObject(ID_COLUMN, Long.class));
book.setTitle(resultSet.getObject(TITLE_COLUMN, String.class));
book.setPrice(resultSet.getObject(PRICE_COLUMN, BigDecimal.class));
return book;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package mate.academy.exception;

public class DataProcessingException extends RuntimeException{
public DataProcessingException(String message, Throwable ex) {
super(message, ex);
}
}
42 changes: 42 additions & 0 deletions src/main/java/mate/academy/model/Book.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
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 +
'}';
}
}
26 changes: 26 additions & 0 deletions src/main/java/mate/academy/util/ConnectionUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package mate.academy.util;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;

public class ConnectionUtil {
public static final String DB_URL = "jdbc:mysql://localhost:3306/book_schema";
public static final Properties DB_PROPERTIES;
static {
DB_PROPERTIES = new Properties();
DB_PROPERTIES.put("user", "root");
DB_PROPERTIES.put("password", "qwerty123");

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

public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(DB_URL, DB_PROPERTIES);
}
}
7 changes: 7 additions & 0 deletions src/main/resources/init_db.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
CREATE DATABASE book_schema;
USE book_schema;
CREATE TABLE books (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`title` VARCHAR(255),
`price` DECIMAL,
PRIMARY KEY (`id`));
Loading