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

Jv jdbc intro solution #378

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 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 @@ -55,4 +55,11 @@
</plugins>
</pluginManagement>
</build>
<dependencies>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>9.0.0</version>
</dependency>
</dependencies>
</project>
43 changes: 43 additions & 0 deletions src/main/java/mate/academy/Main.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,50 @@
package mate.academy;

import java.math.BigDecimal;
import java.util.List;
import mate.academy.dao.BookDao;
import mate.academy.lib.Injector;
import mate.academy.models.Book;

public class Main {
private static final Injector injector = Injector.getInstance("mate.academy.dao");

public static void main(String[] args) {
BookDao bookDao = (BookDao) injector.getInstance(BookDao.class);

bookDao.create(new Book(1L, "Java Programming", new BigDecimal("1000.00")));
bookDao.create(new Book(2L, "Effective Java", new BigDecimal("1500.00")));
bookDao.create(new Book(3L, "Clean Code", new BigDecimal("2000.00")));
bookDao.create(new Book(4L, "Head First Java", new BigDecimal("2500.00")));
bookDao.create(new Book(5L, "Java Concurrency in Practice", new BigDecimal("3000.00")));

System.out.println("FULL list of books");
List<Book> list = bookDao.findAll();
for (Book book : list) {
System.out.println(book.getId() + " " + book.getTitle() + " " + book.getPrice());
}

System.out.println("\n" + "Finding book by index:" + list.get(0).getId());
Book book1 = bookDao.findById(list.get(0).getId())
.orElseThrow(() ->
new RuntimeException("Objects with the specified ID do not exist"));
System.out.println(book1.getId() + " " + book1.getTitle() + " " + book1.getPrice());

System.out.println("\n" + "Updating book by index:" + list.get(0).getId());
bookDao.update(new Book(list.get(0).getId(), "Nikilen", new BigDecimal(100)));

Book book2 = bookDao.findById(list.get(0).getId())
.orElseThrow(() ->
new RuntimeException("Objects with the specified ID do not exist"));

System.out.println(book2.getId() + " " + book2.getTitle() + " " + book2.getPrice());

System.out.println("\n" + "Deleting an object by index:" + list.get(0).getId());

if (bookDao.deleteById(list.get(0).getId())) {
System.out.println("The object is deleted");
} else {
System.out.println("The object does not exist");
}
}
}
18 changes: 18 additions & 0 deletions src/main/java/mate/academy/dao/BookDao.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package mate.academy.dao;

import java.util.List;
import java.util.Optional;
import mate.academy.models.Book;

public interface BookDao {
Book create(Book book);

Optional<Book> findById(Long id);

List<Book> findAll();

Book update(Book book);

boolean deleteById(Long id);

Choose a reason for hiding this comment

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

Suggested change

}
137 changes: 137 additions & 0 deletions src/main/java/mate/academy/dao/BookDaoImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
package mate.academy.dao;

import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.DriverManager;
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.lib.Dao;
import mate.academy.models.Book;

@Dao
public class BookDaoImpl implements BookDao {
private static final String 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.

It's better to create ConnectionUtil class to establish connection to DB

private static final String USER = "root";
private static final String PASSWORD = "henghfdf";

@Override
public Book create(Book book) {
String sqlCommand = "INSERT INTO books (title,price) VALUE (?,?)";

try (Connection connection = DriverManager.getConnection(URL, USER, PASSWORD);
PreparedStatement preparedStatement =
connection.prepareStatement(sqlCommand, Statement.RETURN_GENERATED_KEYS)) {

preparedStatement.setString(1, book.getTitle());
preparedStatement.setBigDecimal(2, book.getPrice());

int affectedRows = preparedStatement.executeUpdate();
if (affectedRows < 1) {
throw new RuntimeException("None of the rows have been added");
}

try (ResultSet generatedKeys = preparedStatement.getGeneratedKeys()) {
if (generatedKeys.next()) {
long id = generatedKeys.getLong(1);

Choose a reason for hiding this comment

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

Suggested change
long id = generatedKeys.getLong(1);
long id = generatedKeys.getObject(1, Long.class);
book.setId(id);
return book;

return new Book(id, book.getTitle(), book.getPrice());
} else {
throw new RuntimeException("Failed to retrieve the generated key");

Choose a reason for hiding this comment

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

Suggested change
throw new RuntimeException("Failed to retrieve the generated key");
throw new DataProcessingException("Failed to retrieve the generated key");

}
}
} catch (SQLException e) {
throw new RuntimeException("Cannot create a connection to the DB", e);

Choose a reason for hiding this comment

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

Suggested change
throw new RuntimeException("Cannot create a connection to the DB", e);
throw new DataProcessingException("Can't add a new book, " + book, e);

Check all places where you are using RuntimeEx

}
}

@Override
public Optional<Book> findById(Long id) {
String sqlCommand = "SELECT * FROM books WHERE id = ?";

try (Connection connection = DriverManager.getConnection(URL, USER, PASSWORD);
PreparedStatement preparedStatement = connection.prepareStatement(sqlCommand)) {
preparedStatement.setLong(1, id);

try (ResultSet resultSet = preparedStatement.executeQuery()) {
if (resultSet.next()) {
String title = resultSet.getObject("title", String.class);

Choose a reason for hiding this comment

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

Create separate method to map ResultSet to book to avoid duplication in findById and findAll methods

BigDecimal price = resultSet.getObject("price", BigDecimal.class);

return Optional.of(new Book(id, title, price));
}
}
} catch (SQLException e) {
throw new RuntimeException("Cannot create a connection to the DB", e);

Choose a reason for hiding this comment

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

Change message according to the logic of method (see example above)
Check everywhere

}

return Optional.empty();
}

@Override
public List<Book> findAll() {
String sqlCommand = "SELECT * FROM books";
List<Book> result = new ArrayList<>();

try (Connection connection = DriverManager.getConnection(URL, USER, PASSWORD);
PreparedStatement preparedStatement = connection.prepareStatement(sqlCommand);
ResultSet resultSet = preparedStatement.executeQuery()) {

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

result.add(new Book(id, title, price));
}

} catch (SQLException e) {
throw new RuntimeException("Cannot create a connection to the DB", e);
}

return result;
}

@Override
public Book update(Book book) {
String sqlCommand = "UPDATE books SET title=?, price=? WHERE id = ?";

try (Connection connection = DriverManager.getConnection(URL, USER, PASSWORD);
PreparedStatement preparedStatement = connection.prepareStatement(sqlCommand)) {

preparedStatement.setString(1, book.getTitle());
preparedStatement.setBigDecimal(2, book.getPrice());
preparedStatement.setLong(3, book.getId());

int affectedRows = preparedStatement.executeUpdate();
if (affectedRows < 1) {
throw new RuntimeException("None of the rows have been updated");
}

return book;

} catch (SQLException e) {
throw new RuntimeException("Cannot create a connection to the DB", e);
}
}

@Override
public boolean deleteById(Long id) {
String sqlCommand = "DELETE FROM books WHERE id = ?";

try (Connection connection = DriverManager.getConnection(URL, USER, PASSWORD);
PreparedStatement preparedStatement = connection.prepareStatement(sqlCommand)) {

preparedStatement.setLong(1, id);

int affectedRows = preparedStatement.executeUpdate();
return affectedRows > 0;

} catch (SQLException e) {
throw new RuntimeException("Cannot create a connection to the DB", e);
}
}
}
27 changes: 27 additions & 0 deletions src/main/java/mate/academy/models/Book.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package mate.academy.models;

import java.math.BigDecimal;

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 Long getId() {
return id;
}

public String getTitle() {
return title;
}

public BigDecimal getPrice() {
return price;
}
}
6 changes: 6 additions & 0 deletions src/main/resources/init_db.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
CREATE TABLE `books`(
`id` INT NOT NULL AUTO_INCREMENT,

Choose a reason for hiding this comment

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

Suggested change
`id` INT NOT NULL AUTO_INCREMENT,
`id` BIGINT AUTO_INCREMENT,

`title` VARCHAR(255),
`price` DECIMAL,
PRIMARY KEY (`id`)
);
Loading