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

developed dao logic #427

Open
wants to merge 2 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
7 changes: 7 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@
https://raw.githubusercontent.com/mate-academy/style-guides/master/java/checkstyle.xml
</maven.checkstyle.plugin.configLocation>
</properties>
<dependencies>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>9.1.0</version>
</dependency>
</dependencies>

<build>
<plugins>
Expand Down
18 changes: 17 additions & 1 deletion src/main/java/mate/academy/Main.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,23 @@
package mate.academy;

import java.math.BigDecimal;
import mate.academy.book.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.lib");
private static final BookDao dao = (BookDao) injector.getInstance(BookDao.class);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The BookDao interface specifies that the findById method should return an Optional<Book>, but the current code calls dao.findById(1L) without handling the Optional. Consider using Optional methods like ifPresent, orElse, or orElseThrow to handle the result properly.

private static final BigDecimal BIG_DECIMAL = new BigDecimal(8855);
private static final Book BOOK_TO_CREATE = new Book("title", BIG_DECIMAL);
private static final Book BOOK_TO_UPDATE = new Book(2L,"name", BIG_DECIMAL);

public static void main(String[] args) {
dao.create(BOOK_TO_CREATE);
dao.deleteById(3L);
dao.update(BOOK_TO_UPDATE);
dao.findById(1L);
dao.findAll();
}
}
17 changes: 17 additions & 0 deletions src/main/java/mate/academy/book/BookDao.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package mate.academy.book;

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);
}
121 changes: 121 additions & 0 deletions src/main/java/mate/academy/book/BookDaoImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
package mate.academy.book;

import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import mate.academy.connection.ConnectionUtils;
import mate.academy.exception.DataProcessingException;
import mate.academy.lib.Dao;
import mate.academy.model.Book;

@Dao
public class BookDaoImpl implements BookDao {

@Override
public Book create(Book book) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the create method, ensure that the SQL statement uses the correct table name books as specified in the task description. The current statement uses book, which may lead to errors if the table name is incorrect.

int titlePlace = 1;
int pricePlace = 2;
String sqlInsertionStatement = "INSERT INTO book (title, price) VALUES (?, ?)";
try (Connection connection = ConnectionUtils.getConnection();
PreparedStatement statement = connection.prepareStatement(sqlInsertionStatement,
PreparedStatement.RETURN_GENERATED_KEYS)) {
statement.setString(titlePlace, book.getTitle());
statement.setBigDecimal(pricePlace, book.getPrice());
int affectedRows = statement.executeUpdate();
if (affectedRows > 0) {
try (ResultSet generatedKeys = statement.getGeneratedKeys()) {
if (generatedKeys.next()) {
book.setId(generatedKeys.getLong(1));
}
}
}
} catch (SQLException e) {
throw new DataProcessingException("Unable to insert book: " + book.toString(), e);
}
return book;
}

@Override
public Optional<Book> findById(Long id) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the findById method, ensure that the SQL statement uses the correct table name books as specified in the task description. The current statement uses book, which may lead to errors if the table name is incorrect.

int variablePlace = 1;
String sqlGetStatement = "SELECT * FROM book WHERE id = ?";
try (Connection connection = ConnectionUtils.getConnection();
PreparedStatement statement = connection.prepareStatement(sqlGetStatement)) {
statement.setLong(variablePlace,id);
ResultSet resultSet = statement.executeQuery();
if (resultSet.next()) {
Long idFromDB = resultSet.getObject("id", Long.class);
String title = resultSet.getString("title");
BigDecimal price = resultSet.getObject("price", BigDecimal.class);
Book book = new Book(idFromDB,title,price);
return Optional.of(book);
}
return Optional.empty();
} catch (SQLException e) {
throw new DataProcessingException("Cant get book with id:" + id, e);
}
}

@Override
public List<Book> findAll() {
String sqlFindAllStatement = "SELECT * FROM book";

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the findAll method, ensure that the SQL statement uses the correct table name books as specified in the task description. The current statement uses book, which may lead to errors if the table name is incorrect.

List<Book> books = new ArrayList<>();
try (Connection connection = ConnectionUtils.getConnection();
PreparedStatement statement = connection.prepareStatement(sqlFindAllStatement);
ResultSet resultSet = statement.executeQuery()) {

while (resultSet.next()) {
Long id = resultSet.getObject("id", Long.class);
String title = resultSet.getString("title");
BigDecimal price = resultSet.getObject("price", BigDecimal.class);

Book book = new Book(id, title, price);
books.add(book);
}
} catch (SQLException e) {
throw new DataProcessingException("Can't read data", e);
}
return books;
}

@Override
public Book update(Book book) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the update method, ensure that the SQL statement uses the correct table name books as specified in the task description. The current statement uses book, which may lead to errors if the table name is incorrect.

int idPlace = 3;
int titlePlace = 1;
int pricePlace = 2;
String sqlUpdateStatement = "UPDATE book SET title = ?, price = ? WHERE id = ?";
try (Connection connection = ConnectionUtils.getConnection();
PreparedStatement statement = connection.prepareStatement(sqlUpdateStatement)) {
statement.setLong(idPlace,book.getId());
statement.setString(titlePlace,book.getTitle());
statement.setBigDecimal(pricePlace,book.getPrice());
Comment on lines +94 to +96

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider setting the parameters in the order they appear in the SQL statement to improve readability. This means setting titlePlace and pricePlace before idPlace, as they appear first in the SQL statement.

int affectedRows = statement.executeUpdate();
if (affectedRows > 0) {
return book;
} else {
throw new RuntimeException("Failed to update book with id: " + book.getId());

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of throwing a generic RuntimeException, consider using a more specific exception type or the existing DataProcessingException to maintain consistency in error handling.

}
} catch (SQLException e) {
throw new DataProcessingException("Can't update " + book.toString(), e);
}
}

@Override
public boolean deleteById(Long id) {
int idPlace = 1;
String sqlDeleteStatement = "DELETE FROM book WHERE id = ? ";

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the deleteById method, ensure that the SQL statement uses the correct table name books as specified in the task description. The current statement uses book, which may lead to errors if the table name is incorrect.

try (Connection connection = ConnectionUtils.getConnection();
PreparedStatement statement = connection.prepareStatement(sqlDeleteStatement)) {
statement.setLong(idPlace,id);
int affectedRows = statement.executeUpdate();
return affectedRows > 0;
} catch (SQLException e) {
throw new DataProcessingException("Can't delete book with id: " + id, e);
}
}
}
30 changes: 30 additions & 0 deletions src/main/java/mate/academy/connection/ConnectionUtils.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package mate.academy.connection;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
import mate.academy.exception.DataProcessingException;

public class ConnectionUtils {
private static final String DB_URL = "jdbc:mysql://localhost:3306/test";

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure that the database URL in DB_URL is correct and matches the schema you have set up for this task. The current URL points to jdbc:mysql://localhost:3306/test, which may not be the intended schema for your application.

private static final Properties DB_PROPERTIES;
private static final String PASSWORD = "4321";
private static final String USER = "root";
Comment on lines +12 to +13

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Storing database credentials directly in the code is not secure. Consider using environment variables or a secure vault to manage sensitive information like database passwords.


static {
DB_PROPERTIES = new Properties();
DB_PROPERTIES.put("user", USER);
DB_PROPERTIES.put("password", PASSWORD);

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

public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(DB_URL,DB_PROPERTIES);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a good practice to log the connection attempts and any exceptions that occur during the connection process for better traceability and debugging.

}
}
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);
}
}
72 changes: 72 additions & 0 deletions src/main/java/mate/academy/model/Book.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package mate.academy.model;

import java.math.BigDecimal;
import java.util.Objects;

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 Book(String title, BigDecimal price) {
this.title = title;
this.price = price;
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Book book = (Book) o;
return id == book.id && Objects

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When comparing Long objects, it's safer to use Objects.equals(id, book.id) instead of id == book.id to avoid potential issues with object references and null values.

.equals(title, book.title) && Objects.equals(price, book.price);
}

@Override
public int hashCode() {
return Objects.hash(id, title, 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 + System.lineSeparator()
+ ", price=" + price
+ '}';
}
}
2 changes: 2 additions & 0 deletions src/main/resources/init_db.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
select *
from book
Loading