-
Notifications
You must be signed in to change notification settings - Fork 438
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
Home work #405
base: main
Are you sure you want to change the base?
Home work #405
Changes from 9 commits
90fe925
d0ce442
34cc07b
01f7098
4d5d0d6
e35be33
fd00413
8e1b5dd
b3962ce
11ef307
c07dc82
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,48 @@ | ||
package mate.academy; | ||
|
||
import java.math.BigDecimal; | ||
import java.util.List; | ||
import java.util.Objects; | ||
import mate.academy.dao.BookDao; | ||
import mate.academy.lib.Injector; | ||
import mate.academy.model.Book; | ||
|
||
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); | ||
|
||
// Initialize data | ||
List<Book> books = initializeBooks(); | ||
books.forEach(book -> System.out.println("Created record in DB: " + bookDao.create(book))); | ||
|
||
// Fetch all books once and reuse the list | ||
List<Book> allBooks = bookDao.findAll(); | ||
System.out.println(System.lineSeparator() + "Records in DB:"); | ||
allBooks.forEach(System.out::println); | ||
|
||
// Update a specific book | ||
allBooks.stream() | ||
.filter(b -> Objects.equals(b.getTitle(), "Effective Java")) | ||
.findFirst() | ||
.ifPresent(updatedBook -> { | ||
updatedBook.setTitle("SQL in 10 Minutes"); | ||
updatedBook.setPrice(BigDecimal.valueOf(24.99)); | ||
System.out.println(System.lineSeparator() | ||
+ "Updated in db: " + bookDao.update(updatedBook)); | ||
}); | ||
|
||
// Delete all books | ||
allBooks.forEach(book -> System.out.println("Deleted record from DB: " | ||
+ bookDao.deleteById(book.getId()))); | ||
} | ||
|
||
private static List<Book> initializeBooks() { | ||
return List.of( | ||
new Book("Core Java Volume I – Fundamentals", BigDecimal.valueOf(29.99)), | ||
new Book("Effective Java", BigDecimal.valueOf(19.99)), | ||
new Book("Java - The Complete Reference", BigDecimal.valueOf(35.45)) | ||
); | ||
} | ||
} |
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); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
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 { | ||
@Override | ||
public Book create(Book book) { | ||
String query = "INSERT INTO books (title, price) " | ||
+ "VALUES (?, ?)"; | ||
try (Connection connection = ConnectionUtil.getConnection(); | ||
PreparedStatement statement = connection | ||
.prepareStatement(query, Statement.RETURN_GENERATED_KEYS)) { | ||
statement.setString(1, book.getTitle()); | ||
statement.setBigDecimal(2, book.getPrice()); | ||
statement.executeUpdate(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should we check if rows were updated? |
||
ResultSet resultSet = statement.getGeneratedKeys(); | ||
if (resultSet.next()) { | ||
book.setId(resultSet.getObject(1, Long.class)); | ||
} | ||
return book; | ||
} catch (SQLException e) { | ||
throw new DataProcessingException("Couldn't create book: " + book, e); | ||
} | ||
} | ||
|
||
@Override | ||
public Optional<Book> findById(Long id) { | ||
String query = "SELECT id, title, price FROM books WHERE id = ?;"; | ||
try (Connection connection = ConnectionUtil.getConnection(); | ||
PreparedStatement statement = connection.prepareStatement(query)) { | ||
statement.setLong(1, id); | ||
ResultSet resultSet = statement.executeQuery(); | ||
Book book = null; | ||
if (resultSet.next()) { | ||
book = getBook(resultSet); | ||
return Optional.of(book); | ||
} | ||
} catch (SQLException e) { | ||
throw new DataProcessingException("Couldn't get book by id: " + id, e); | ||
} | ||
return Optional.empty(); | ||
} | ||
|
||
@Override | ||
public List<Book> findAll() { | ||
String query = "SELECT id, title, price FROM books"; | ||
try (Connection connection = ConnectionUtil.getConnection(); | ||
PreparedStatement statement = connection.prepareStatement(query)) { | ||
List<Book> books = new ArrayList<>(); | ||
ResultSet resultSet = statement.executeQuery(); | ||
while (resultSet.next()) { | ||
books.add(getBook(resultSet)); | ||
} | ||
return books; | ||
} catch (SQLException e) { | ||
throw new DataProcessingException("Couldn't get a list of books from books table.", e); | ||
} | ||
} | ||
|
||
@Override | ||
public Book update(Book book) { | ||
String query = "UPDATE books SET title = ?, price = ? WHERE id= ?;"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remember to use uppercase for SQL keywords in your queries for consistency and readability. The |
||
try (Connection connection = ConnectionUtil.getConnection(); | ||
PreparedStatement statement = connection.prepareStatement(query)) { | ||
statement.setString(1, book.getTitle()); | ||
statement.setBigDecimal(2, book.getPrice()); | ||
statement.setLong(3, book.getId()); | ||
statement.executeUpdate(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should we check if rows were updated? |
||
return book; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You should execute There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You are not closing the |
||
} catch (SQLException e) { | ||
throw new DataProcessingException("Couldn't update a book: " | ||
+ book, e); | ||
} | ||
} | ||
|
||
@Override | ||
public boolean deleteById(Long id) { | ||
String query = "DELETE FROM books WHERE id = ?"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Remember to use uppercase for SQL keywords in your queries for consistency and readability. The |
||
try (Connection connection = ConnectionUtil.getConnection(); | ||
PreparedStatement statement = connection.prepareStatement(query)) { | ||
statement.setLong(1, id); | ||
return statement.executeUpdate() > 0; | ||
} catch (SQLException e) { | ||
throw new DataProcessingException("Couldn't delete a book by id " + id, e); | ||
} | ||
} | ||
|
||
private Book getBook(ResultSet resultSet) throws SQLException { | ||
Long id = resultSet.getObject("id", Long.class); | ||
String title = resultSet.getString("title"); | ||
BigDecimal price = resultSet.getBigDecimal("price"); | ||
return new Book(id, title, price); | ||
Comment on lines
+107
to
+111
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To avoid code duplication when converting |
||
} | ||
} |
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 cause) { | ||
super(message, cause); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
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() { | ||
} | ||
|
||
public Book(String title, BigDecimal price) { | ||
this.title = title; | ||
this.price = price; | ||
} | ||
|
||
public Book(Long id, String title, BigDecimal price) { | ||
this.id = id; | ||
this.title = title; | ||
this.price = 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 boolean equals(Object o) { | ||
if (this == o) { | ||
return true; | ||
} | ||
if (o == null || getClass() != o.getClass()) { | ||
return false; | ||
} | ||
Book book = (Book) o; | ||
return Objects.equals(id, book.id) | ||
&& Objects.equals(title, book.title) | ||
&& Objects.equals(price, book.price); | ||
} | ||
|
||
@Override | ||
public int hashCode() { | ||
return Objects.hash(id, title, price); | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "Book{" | ||
+ "id=" + id | ||
+ ", title='" + title + '\'' | ||
+ ", price=" + price | ||
+ '}'; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
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/library_service"; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The URL for the JDBC connection is incomplete. It should specify the database you're connecting to, for example, 'jdbc:mysql://localhost:3306/myDatabase'. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Avoid using hard-coded database credentials in your code. Consider using environment variables or configuration files to manage sensitive information securely. |
||
private static final String USERNAME = "root"; | ||
private static final String PASSWORD = "root"; | ||
private static final String JDBC_DRIVER = "com.mysql.cj.jdbc.Driver"; | ||
|
||
static { | ||
try { | ||
Class.forName(JDBC_DRIVER); | ||
} catch (ClassNotFoundException e) { | ||
throw new RuntimeException("Can't find SQL Driver", e); | ||
} | ||
} | ||
|
||
public static Connection getConnection() throws SQLException { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's a good practice to handle |
||
Properties dbProperties = new Properties(); | ||
dbProperties.setProperty("user", USERNAME); | ||
dbProperties.setProperty("password", PASSWORD); | ||
return DriverManager.getConnection(URL, dbProperties); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
remove comments please