-
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
Jv jdbc intro hw solution #319
base: main
Are you sure you want to change the base?
Changes from 2 commits
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,29 @@ | ||
package mate.academy; | ||
|
||
import java.math.BigDecimal; | ||
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); | ||
|
||
Book mainCamp = new Book(); | ||
mainCamp.setTitle("Main Camp"); | ||
mainCamp.setPrice(BigDecimal.valueOf(19.99)); | ||
bookDao.create(mainCamp); | ||
|
||
Book lordOfTheRing = new Book(); | ||
lordOfTheRing.setTitle("Lord of the ring"); | ||
lordOfTheRing.setPrice(BigDecimal.valueOf(20.50)); | ||
bookDao.create(lordOfTheRing); | ||
|
||
bookDao.findAll(); | ||
bookDao.findById(1L); | ||
bookDao.update(lordOfTheRing).setPrice(BigDecimal.valueOf(40)); | ||
bookDao.deleteById(1L); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package mate.academy.connection; | ||
|
||
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/test"; | ||
private static final Properties DB_PROPERTIES; | ||
|
||
static { | ||
DB_PROPERTIES = new Properties(); | ||
DB_PROPERTIES.put("user", "root"); | ||
DB_PROPERTIES.put("password", "Z170191erg"); | ||
try { | ||
Class.forName("com.mysql.cj.jdbc.Driver"); | ||
} catch (ClassNotFoundException e) { | ||
throw new RuntimeException("Can`t load JDBC driver", e); | ||
} | ||
} | ||
|
||
public static Connection getConnection(String sql) throws SQLException { | ||
return DriverManager.getConnection(DB_URL,DB_PROPERTIES); | ||
} | ||
} |
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,118 @@ | ||||||
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.connection.ConnectionUtil; | ||||||
import mate.academy.exception.DataProcessingException; | ||||||
import mate.academy.model.Book; | ||||||
|
||||||
public class BookDaoImpl implements BookDao { | ||||||
@Override | ||||||
public Book create(Book book) { | ||||||
String sql = "INSERT INTO books(title, price) VALUES (?, ?)"; | ||||||
try (Connection connection = ConnectionUtil.getConnection(sql); | ||||||
PreparedStatement statement = connection.prepareStatement( | ||||||
sql, Statement.RETURN_GENERATED_KEYS)) { | ||||||
statement.setString(1, book.getTitle()); | ||||||
statement.setBigDecimal(2, book.getPrice()); | ||||||
|
||||||
int affectedRows = statement.executeUpdate(); | ||||||
if (affectedRows < 1) { | ||||||
throw new RuntimeException("Expected to insert at least one row"); | ||||||
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. why raw |
||||||
} | ||||||
ResultSet generatedKeys = statement.getGeneratedKeys(); | ||||||
if (generatedKeys.next()) { | ||||||
Long id = generatedKeys.getLong(1); | ||||||
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. check common mistakes for that |
||||||
book.setId(id); | ||||||
} | ||||||
} catch (SQLException e) { | ||||||
throw new RuntimeException("Cannot save data", e); | ||||||
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. same here and in other places |
||||||
} | ||||||
return book; | ||||||
} | ||||||
|
||||||
@Override | ||||||
public Optional<Book> findById(Long id) { | ||||||
String sql = "SELECT * FROM books WHERE id = ?"; | ||||||
try (Connection connection = ConnectionUtil.getConnection(sql); | ||||||
PreparedStatement statement = connection.prepareStatement(sql)) { | ||||||
statement.setLong(1, id); | ||||||
ResultSet resultSet = statement.executeQuery(); | ||||||
if (resultSet.next()) { | ||||||
Long bookId = resultSet.getLong("id"); | ||||||
String title = resultSet.getString("title"); | ||||||
BigDecimal price = resultSet.getBigDecimal("price"); | ||||||
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. make those literals constants |
||||||
Book book = new Book(); | ||||||
book.setId(bookId); | ||||||
book.setTitle(title); | ||||||
book.setPrice(price); | ||||||
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. code duplication, extract a private method |
||||||
return Optional.of(book); | ||||||
} else { | ||||||
return Optional.empty(); | ||||||
} | ||||||
} catch (SQLException e) { | ||||||
throw new DataProcessingException("Failed to find book with id: " + id); | ||||||
} | ||||||
} | ||||||
|
||||||
@Override | ||||||
public List<Book> findAll() { | ||||||
String sql = "SELECT * FROM books"; | ||||||
List<Book> bookList = new ArrayList<>(); | ||||||
try (Connection connection = ConnectionUtil.getConnection(sql); | ||||||
PreparedStatement statement = connection.prepareStatement(sql)) { | ||||||
ResultSet resultSet = statement.executeQuery(); | ||||||
while (resultSet.next()) { | ||||||
long id = resultSet.getLong("id"); | ||||||
String title = resultSet.getString("title"); | ||||||
BigDecimal price = resultSet.getBigDecimal("price"); | ||||||
Book book = new Book(); | ||||||
book.setId(id); | ||||||
book.setTitle(title); | ||||||
book.setPrice(price); | ||||||
bookList.add(book); | ||||||
} | ||||||
} catch (SQLException e) { | ||||||
throw new DataProcessingException("can`t get book from DataBase ", e); | ||||||
} | ||||||
return bookList; | ||||||
} | ||||||
|
||||||
@Override | ||||||
public Book update(Book book) { | ||||||
String sql = "UPDATE books SET title = ?, price = ? WHERE id = ?"; | ||||||
try (Connection connection = ConnectionUtil.getConnection(sql); | ||||||
PreparedStatement statement = connection.prepareStatement(sql)) { | ||||||
statement.setString(1, book.getTitle()); | ||||||
statement.setBigDecimal(2, book.getPrice()); | ||||||
statement.setLong(3, book.getId()); | ||||||
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. magic numbers, check other methods as well |
||||||
int rowsUpdated = statement.executeUpdate(); | ||||||
if (rowsUpdated == 0) { | ||||||
throw new DataProcessingException("Failed to update book with id: " + book.getId()); | ||||||
} | ||||||
return book; | ||||||
} catch (SQLException e) { | ||||||
throw new DataProcessingException("Failed to update book with id: " + book.getId() + e); | ||||||
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. same here, we should pass it as a separate parameter, because we need the whole original exception info, like stack trace and it's message to be saved, and passed ll the way to the user or dev |
||||||
} | ||||||
} | ||||||
|
||||||
@Override | ||||||
public boolean deleteById(Long id) { | ||||||
String sql = "DELETE FROM books WHERE id = ?"; | ||||||
try (Connection connection = ConnectionUtil.getConnection(sql); | ||||||
PreparedStatement statement = connection.prepareStatement(sql)) { | ||||||
statement.setLong(1, id); | ||||||
int rowsDeleted = statement.executeUpdate(); | ||||||
return rowsDeleted > 0; | ||||||
} catch (SQLException e) { | ||||||
throw new DataProcessingException("Failed to delete book with id: " + id + e); | ||||||
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.
Suggested change
|
||||||
} | ||||||
} | ||||||
} |
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, Throwable cause) { | ||
super(message, cause); | ||
} | ||
|
||
public DataProcessingException(String message) { | ||
super(message); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change | ||
---|---|---|---|---|
@@ -0,0 +1,47 @@ | ||||
package mate.academy.model; | ||||
|
||||
import java.math.BigDecimal; | ||||
|
||||
public class Book { | ||||
private Long 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.
Suggested change
|
||||
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 | ||||
+ '}'; | ||||
} | ||||
} |
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,6 @@ | ||||||
CREATE TABLE `books` ( | ||||||
`id` INT NOT NULL AUTO_INCREMENT, | ||||||
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.
Suggested change
|
||||||
`bookTitle` VARCHAR(50), | ||||||
`price` BIGINT, | ||||||
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. price can be like |
||||||
PRIMARY KEY (`id`) | ||||||
); |
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.
this var could use a better naming, same in other places