新增书籍表、列表/搜索、管理员/馆员维护入口
This commit is contained in:
@@ -0,0 +1,224 @@
|
||||
package com.mzh.library.dao.impl;
|
||||
|
||||
import com.mzh.library.dao.BookDao;
|
||||
import com.mzh.library.entity.Book;
|
||||
import com.mzh.library.entity.BookCategory;
|
||||
import com.mzh.library.entity.BookSearchCriteria;
|
||||
import com.mzh.library.entity.BookStatus;
|
||||
import com.mzh.library.exception.DaoException;
|
||||
import com.mzh.library.util.JdbcUtil;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.sql.Timestamp;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
public class JdbcBookDao implements BookDao {
|
||||
private static final String BOOK_COLUMNS = ""
|
||||
+ "b.id, b.book_identifier, b.title, b.author, b.category_id, c.name AS category_name, "
|
||||
+ "b.total_copies, b.available_copies, b.status, b.created_at, b.updated_at ";
|
||||
|
||||
private static final String BOOK_FROM = ""
|
||||
+ "FROM books b "
|
||||
+ "JOIN book_categories c ON c.id = b.category_id ";
|
||||
|
||||
private static final String FIND_ALL_CATEGORIES = ""
|
||||
+ "SELECT id, name, description "
|
||||
+ "FROM book_categories "
|
||||
+ "ORDER BY name";
|
||||
|
||||
private static final String FIND_BY_ID = "SELECT " + BOOK_COLUMNS + BOOK_FROM + "WHERE b.id = ?";
|
||||
|
||||
private static final String FIND_BY_IDENTIFIER = "SELECT " + BOOK_COLUMNS + BOOK_FROM
|
||||
+ "WHERE b.book_identifier = ?";
|
||||
|
||||
private static final String CREATE = ""
|
||||
+ "INSERT INTO books "
|
||||
+ "(book_identifier, title, author, category_id, total_copies, available_copies, status) "
|
||||
+ "VALUES (?, ?, ?, ?, ?, ?, ?)";
|
||||
|
||||
private static final String UPDATE = ""
|
||||
+ "UPDATE books "
|
||||
+ "SET book_identifier = ?, title = ?, author = ?, category_id = ?, total_copies = ?, "
|
||||
+ "available_copies = ?, status = ? "
|
||||
+ "WHERE id = ?";
|
||||
|
||||
private static final String DELETE = "DELETE FROM books WHERE id = ?";
|
||||
|
||||
@Override
|
||||
public List<BookCategory> findAllCategories() {
|
||||
try (Connection connection = JdbcUtil.getConnection();
|
||||
PreparedStatement statement = connection.prepareStatement(FIND_ALL_CATEGORIES);
|
||||
ResultSet resultSet = statement.executeQuery()) {
|
||||
List<BookCategory> categories = new ArrayList<>();
|
||||
while (resultSet.next()) {
|
||||
categories.add(mapCategory(resultSet));
|
||||
}
|
||||
return categories;
|
||||
} catch (SQLException ex) {
|
||||
throw new DaoException("Unable to load book categories", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Book> search(BookSearchCriteria criteria) {
|
||||
List<Object> parameters = new ArrayList<>();
|
||||
StringBuilder sql = new StringBuilder("SELECT ")
|
||||
.append(BOOK_COLUMNS)
|
||||
.append(BOOK_FROM)
|
||||
.append("WHERE 1 = 1 ");
|
||||
|
||||
appendLike(sql, parameters, "b.book_identifier", criteria.getIdentifier());
|
||||
appendLike(sql, parameters, "b.title", criteria.getTitle());
|
||||
appendLike(sql, parameters, "b.author", criteria.getAuthor());
|
||||
if (criteria.getCategoryId() != null) {
|
||||
sql.append("AND b.category_id = ? ");
|
||||
parameters.add(criteria.getCategoryId());
|
||||
}
|
||||
sql.append("ORDER BY b.title, b.author, b.book_identifier");
|
||||
|
||||
try (Connection connection = JdbcUtil.getConnection();
|
||||
PreparedStatement statement = connection.prepareStatement(sql.toString())) {
|
||||
bind(statement, parameters);
|
||||
try (ResultSet resultSet = statement.executeQuery()) {
|
||||
List<Book> books = new ArrayList<>();
|
||||
while (resultSet.next()) {
|
||||
books.add(mapBook(resultSet));
|
||||
}
|
||||
return books;
|
||||
}
|
||||
} catch (SQLException | IllegalArgumentException ex) {
|
||||
throw new DaoException("Unable to search books", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Book> findById(long id) {
|
||||
try (Connection connection = JdbcUtil.getConnection();
|
||||
PreparedStatement statement = connection.prepareStatement(FIND_BY_ID)) {
|
||||
statement.setLong(1, id);
|
||||
try (ResultSet resultSet = statement.executeQuery()) {
|
||||
return resultSet.next() ? Optional.of(mapBook(resultSet)) : Optional.empty();
|
||||
}
|
||||
} catch (SQLException | IllegalArgumentException ex) {
|
||||
throw new DaoException("Unable to load book by id", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Book> findByIdentifier(String identifier) {
|
||||
try (Connection connection = JdbcUtil.getConnection();
|
||||
PreparedStatement statement = connection.prepareStatement(FIND_BY_IDENTIFIER)) {
|
||||
statement.setString(1, identifier);
|
||||
try (ResultSet resultSet = statement.executeQuery()) {
|
||||
return resultSet.next() ? Optional.of(mapBook(resultSet)) : Optional.empty();
|
||||
}
|
||||
} catch (SQLException | IllegalArgumentException ex) {
|
||||
throw new DaoException("Unable to load book by identifier", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public long create(Book book) {
|
||||
try (Connection connection = JdbcUtil.getConnection();
|
||||
PreparedStatement statement = connection.prepareStatement(CREATE, Statement.RETURN_GENERATED_KEYS)) {
|
||||
bindBook(statement, book);
|
||||
statement.executeUpdate();
|
||||
|
||||
try (ResultSet generatedKeys = statement.getGeneratedKeys()) {
|
||||
if (generatedKeys.next()) {
|
||||
return generatedKeys.getLong(1);
|
||||
}
|
||||
}
|
||||
throw new DaoException("Unable to read generated book id", null);
|
||||
} catch (SQLException ex) {
|
||||
throw new DaoException("Unable to create book", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean update(Book book) {
|
||||
try (Connection connection = JdbcUtil.getConnection();
|
||||
PreparedStatement statement = connection.prepareStatement(UPDATE)) {
|
||||
bindBook(statement, book);
|
||||
statement.setLong(8, book.getId());
|
||||
return statement.executeUpdate() == 1;
|
||||
} catch (SQLException ex) {
|
||||
throw new DaoException("Unable to update book", ex);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean delete(long id) {
|
||||
try (Connection connection = JdbcUtil.getConnection();
|
||||
PreparedStatement statement = connection.prepareStatement(DELETE)) {
|
||||
statement.setLong(1, id);
|
||||
return statement.executeUpdate() == 1;
|
||||
} catch (SQLException ex) {
|
||||
throw new DaoException("Unable to delete book", ex);
|
||||
}
|
||||
}
|
||||
|
||||
private void appendLike(StringBuilder sql, List<Object> parameters, String column, String value) {
|
||||
if (value == null || value.trim().isEmpty()) {
|
||||
return;
|
||||
}
|
||||
sql.append("AND ").append(column).append(" LIKE ? ");
|
||||
parameters.add("%" + value.trim() + "%");
|
||||
}
|
||||
|
||||
private void bind(PreparedStatement statement, List<Object> parameters) throws SQLException {
|
||||
for (int i = 0; i < parameters.size(); i++) {
|
||||
Object value = parameters.get(i);
|
||||
if (value instanceof Long) {
|
||||
statement.setLong(i + 1, (Long) value);
|
||||
} else {
|
||||
statement.setString(i + 1, value.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void bindBook(PreparedStatement statement, Book book) throws SQLException {
|
||||
statement.setString(1, book.getIdentifier());
|
||||
statement.setString(2, book.getTitle());
|
||||
statement.setString(3, book.getAuthor());
|
||||
statement.setLong(4, book.getCategoryId());
|
||||
statement.setInt(5, book.getTotalCopies());
|
||||
statement.setInt(6, book.getAvailableCopies());
|
||||
statement.setString(7, book.getStatus().getCode());
|
||||
}
|
||||
|
||||
private Book mapBook(ResultSet resultSet) throws SQLException {
|
||||
Book book = new Book();
|
||||
book.setId(resultSet.getLong("id"));
|
||||
book.setIdentifier(resultSet.getString("book_identifier"));
|
||||
book.setTitle(resultSet.getString("title"));
|
||||
book.setAuthor(resultSet.getString("author"));
|
||||
book.setCategoryId(resultSet.getLong("category_id"));
|
||||
book.setCategoryName(resultSet.getString("category_name"));
|
||||
book.setTotalCopies(resultSet.getInt("total_copies"));
|
||||
book.setAvailableCopies(resultSet.getInt("available_copies"));
|
||||
book.setStatus(BookStatus.fromCode(resultSet.getString("status")));
|
||||
book.setCreatedAt(toLocalDateTime(resultSet.getTimestamp("created_at")));
|
||||
book.setUpdatedAt(toLocalDateTime(resultSet.getTimestamp("updated_at")));
|
||||
return book;
|
||||
}
|
||||
|
||||
private BookCategory mapCategory(ResultSet resultSet) throws SQLException {
|
||||
BookCategory category = new BookCategory();
|
||||
category.setId(resultSet.getLong("id"));
|
||||
category.setName(resultSet.getString("name"));
|
||||
category.setDescription(resultSet.getString("description"));
|
||||
return category;
|
||||
}
|
||||
|
||||
private LocalDateTime toLocalDateTime(Timestamp timestamp) {
|
||||
return timestamp == null ? null : timestamp.toLocalDateTime();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user