图书信息管理模块实现

1.数据库t_book表,主键id为bigint类型,type_id为bigint类型(图书所属类别的id)


image.png

2.录入一些数据,注意type_id字段,一定要是t_type表存在的id


image.png

3.图书实体类Book.java

package com.soft1841.book.entity;

import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleLongProperty;
import javafx.beans.property.SimpleStringProperty;

/**
* 图书实体类
*/
public class Book {
   private final SimpleLongProperty id = new SimpleLongProperty();
   private final SimpleLongProperty typeId = new SimpleLongProperty();
   private final SimpleStringProperty name = new SimpleStringProperty("");
   private final SimpleStringProperty author = new SimpleStringProperty("");
   private final SimpleDoubleProperty price = new SimpleDoubleProperty();
   private final SimpleStringProperty cover = new SimpleStringProperty("");
   private final SimpleStringProperty summary = new SimpleStringProperty("");
   private final SimpleIntegerProperty stock = new SimpleIntegerProperty();
   public Book() {

   }

   public Book(Long id, Long typeId, String name, String author, Double price, String cover, String summary,Integer stock) {
       setId(id);
       setTypeId(typeId);
       setName(name);
       setAuthor(author);
       setPrice(price);
       setCover(cover);
       setSummary(summary);
       setStock(stock);
   }

   public long getId() {
       return id.get();
   }

   public SimpleLongProperty idProperty() {
       return id;
   }

   public void setId(long id) {
       this.id.set(id);
   }

   public long getTypeId() {
       return typeId.get();
   }

   public SimpleLongProperty typeIdProperty() {
       return typeId;
   }

   public void setTypeId(long typeId) {
       this.typeId.set(typeId);
   }

   public String getName() {
       return name.get();
   }

   public SimpleStringProperty nameProperty() {
       return name;
   }

   public void setName(String name) {
       this.name.set(name);
   }

   public String getAuthor() {
       return author.get();
   }

   public SimpleStringProperty authorProperty() {
       return author;
   }

   public void setAuthor(String author) {
       this.author.set(author);
   }

   public double getPrice() {
       return price.get();
   }

   public SimpleDoubleProperty priceProperty() {
       return price;
   }

   public void setPrice(double price) {
       this.price.set(price);
   }

   public String getCover() {
       return cover.get();
   }

   public SimpleStringProperty coverProperty() {
       return cover;
   }

   public void setCover(String cover) {
       this.cover.set(cover);
   }

   public String getSummary() {
       return summary.get();
   }

   public SimpleStringProperty summaryProperty() {
       return summary;
   }

   public void setSummary(String summary) {
       this.summary.set(summary);
   }

   public int getStock() {
       return stock.get();
   }

   public SimpleIntegerProperty stockProperty() {
       return stock;
   }

   public void setStock(int stock) {
       this.stock.set(stock);
   }
}

4.BookDAO接口

package com.soft1841.book.dao;

import cn.hutool.db.Entity;
import com.soft1841.book.entity.Book;

import java.sql.SQLException;
import java.util.List;

/**
* 图书DAO
*/
public interface BookDAO {

   /**
    * 新增图书,返回自增主键
    *
    * @param book
    * @return
    * @throws SQLException
    */
   Long insertBook(Book book) throws SQLException;

   /**
    * 根据id删除图书
    *
    * @param id
    * @return
    */
   int deleteBookById(long id) throws SQLException;

   /**
    * 更新图书信息
    *
    * @param book
    * @return
    */
   int updateBook(Book book) throws SQLException;


   /**
    * 查询所有图书
    *
    * @return
    */
   List<Entity> selectAllBooks() throws SQLException;


   /**
    * 根据id查询图书信息
    *
    * @param id
    * @return
    */
   Entity getBookById(long id) throws SQLException;

   /**
    * 根据书名关键词模糊查询图书
    * @param keywords
    * @return
    * @throws SQLException
    */
   List<Entity> selectBooksLike(String keywords) throws SQLException;

   /**
    * 根据图书类别查询图书
    * @param typeId
    * @return
    * @throws SQLException
    */
   List<Entity> selectBooksByTypeId(long typeId) throws SQLException;

   /**
    * 根据图书类别统计图书数量
    * @param typeId
    * @return
    * @throws SQLException
    */
   int countByType(long typeId) throws SQLException;
}

5.BookDAOImpl实现类

package com.soft1841.book.dao.impl;

import cn.hutool.db.Db;
import cn.hutool.db.Entity;
import cn.hutool.db.sql.Condition;
import com.soft1841.book.dao.BookDAO;
import com.soft1841.book.entity.Book;

import java.sql.SQLException;
import java.util.List;

public class BookDAOImpl implements BookDAO {
    @Override
    public Long insertBook(Book book) throws SQLException {
        return Db.use().insertForGeneratedKey(
                Entity.create("t_book")
                        .set("type_id", book.getTypeId())
                        .set("name", book.getName())
                        .set("author", book.getAuthor())
                        .set("price", book.getPrice())
                        .set("cover", book.getCover())
                        .set("summary", book.getSummary())
                        .set("stock",book.getStock())
        );
    }

    @Override
    public int deleteBookById(long id) throws SQLException {
        return Db.use().del(
                Entity.create("t_book").set("id", id)
        );
    }

    @Override
    public int updateBook(Book book) throws SQLException {
        //只修改了图书的价格和库存
        return Db.use().update(
                Entity.create().set("price", book.getPrice())
                                .set("stock",book.getStock()),
                Entity.create("t_book").set("id", book.getId())
        );
    }

    @Override
    public List<Entity> selectAllBooks() throws SQLException {
        return Db.use().query("SELECT * FROM t_book ");
    }

    @Override
    public Entity getBookById(long id) throws SQLException {
        return Db.use().queryOne("SELECT * FROM t_book WHERE id = ? ", id);
    }

    @Override
    public List<Entity> selectBooksLike(String keywords) throws SQLException {
        return Db.use().findLike("t_book", "name", keywords, Condition.LikeType.Contains);
    }

    @Override
    public List<Entity> selectBooksByTypeId(long typeId) throws SQLException {
        return Db.use().query("SELECT * FROM t_book WHERE type_id = ? ", typeId);
    }

    @Override
    public int countByType(long typeId) throws SQLException {
        return Db.use().queryNumber("SELECT COUNT(*) FROM t_book WHERE type_id = ? ", typeId).intValue();
    }
}

6.DAOFactory工厂类中增加方法,获得BookDAO的实现类对象

 public static BookDAO getBookDAOInstance() {
        return new BookDAOImpl();
    }

7.单元测试

package com.soft1841.book.dao;

import cn.hutool.db.Entity;
import com.soft1841.book.entity.Book;
import com.soft1841.book.utils.DAOFactory;
import org.junit.Test;

import java.sql.SQLException;
import java.util.List;

public class BookDAOTest {
    private BookDAO bookDAO = DAOFactory.getBookDAOInstance();

    @Test
    public void insertBook() throws SQLException {
        Book book = new Book();
        book.setTypeId(1);
        book.setName("测试书籍");
        book.setAuthor("匿名");
        System.out.println(bookDAO.insertBook(book));
    }

    @Test
    public void deleteBookById() throws SQLException {
        bookDAO.deleteBookById(40);
    }

    @Test
    public void updateBook() throws SQLException {
        Book book = new Book();
        book.setId(40);
        book.setPrice(11.1);
        book.setStock(99);
        bookDAO.updateBook(book);
    }

    @Test
    public void selectAllBooks() throws SQLException {
        List<Entity> bookList = bookDAO.selectAllBooks();
        bookList.forEach(entity -> System.out.println(entity.getStr("name")));
    }

    @Test
    public void getBookById() throws SQLException {
        Entity entity = bookDAO.getBookById(1);
        System.out.println(entity);
    }

    @Test
    public void selectBooksLike() throws SQLException {
        List<Entity> bookList = bookDAO.selectBooksLike("少");
        bookList.forEach(entity -> System.out.println(entity.getStr("name")));
    }

    @Test
    public void selectBooksByTypeId() throws SQLException {
        List<Entity> bookList = bookDAO.selectBooksByTypeId(1);
        bookList.forEach(entity -> System.out.println(entity.getStr("name")));
    }

    @Test
    public void countByType() throws SQLException {
        int n = bookDAO.countByType(1);
        System.out.println(n);
    }
}

8.book.fxml布局文件

<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.cell.PropertyValueFactory?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.ComboBox?>
<AnchorPane xmlns="http://javafx.com/javafx"
            xmlns:fx="http://javafx.com/fxml"
            fx:controller="com.soft1841.book.controller.BookController">
    <HBox alignment="BOTTOM_CENTER" AnchorPane.topAnchor="10" AnchorPane.leftAnchor="10" spacing="10">
        <Button styleClass="btn-basic,btn-radius-large,green-theme" text="添加图书" onAction="#newBookStage"/>
        <Button styleClass="btn-basic,btn-radius-large,blue-theme" text="导出数据"/>
    </HBox>
    <HBox alignment="CENTER" AnchorPane.topAnchor="60" AnchorPane.leftAnchor="10" spacing="10">
        <ComboBox promptText="选择图书类别" fx:id="typeComboBox" prefWidth="150"/>
        <TextField promptText="请输入关键词" fx:id="keywordsField"/>
        <Button styleClass="btn-basic,btn-radius-normal,green-theme" text="搜索" onAction="#search"/>
    </HBox>
    <TableView fx:id="bookTable" prefWidth="1000"
               AnchorPane.topAnchor="110" AnchorPane.leftAnchor="10">
        <columns>
            <TableColumn text="ID">
                <cellValueFactory>
                    <PropertyValueFactory property="id"/>
                </cellValueFactory>
            </TableColumn>
            <TableColumn text="书名">
                <cellValueFactory>
                    <PropertyValueFactory property="name"/>
                </cellValueFactory>
            </TableColumn>
            <TableColumn text="作者">
                <cellValueFactory>
                    <PropertyValueFactory property="author"/>
                </cellValueFactory>
            </TableColumn>
            <TableColumn text="价格">
                <cellValueFactory>
                    <PropertyValueFactory property="price"/>
                </cellValueFactory>
            </TableColumn>
            <TableColumn text="库存">
                <cellValueFactory>
                    <PropertyValueFactory property="stock"/>
                </cellValueFactory>
            </TableColumn>
        </columns>
    </TableView>
</AnchorPane>

9.add_book.fxml布局文件

<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.geometry.Insets?>
<AnchorPane xmlns="http://javafx.com/javafx"
            xmlns:fx="http://javafx.com/fxml"
            fx:controller="com.soft1841.book.controller.AddBookController"
            prefHeight="500.0" prefWidth="600.0">
    <HBox AnchorPane.topAnchor="0" AnchorPane.leftAnchor="0" AnchorPane.rightAnchor="0"
          minHeight="50" alignment="CENTER" styleClass="green-theme">
        <Label text="新增书籍信息" styleClass="font-title,green-theme,font-white"/>
    </HBox>
    <VBox styleClass="default-theme" spacing="20" minHeight="400"
          AnchorPane.topAnchor="55" AnchorPane.leftAnchor="0" AnchorPane.rightAnchor="0">
        <ComboBox promptText="选择类别" fx:id="bookType" prefWidth="120"/>
        <TextField promptText="书名" fx:id="bookName"/>
        <TextField promptText="作者" fx:id="bookAuthor"/>
        <HBox spacing="10">
            <TextField promptText="价格" fx:id="bookPrice" prefWidth="290"/>
            <TextField promptText="库存" fx:id="bookStock" prefWidth="290"/>
        </HBox>
        <TextField promptText="封面图" fx:id="bookCover"/>
        <TextArea promptText="图书摘要" fx:id="bookSummary" prefHeight="140"/>
        <padding>
            <Insets top="10" left="50" bottom="10" right="50"/>
        </padding>
    </VBox>
    <Button text="确认" onAction="#addBook" styleClass="btn-radius-large,green-theme"
            AnchorPane.bottomAnchor="10" AnchorPane.leftAnchor="180" AnchorPane.rightAnchor="180"/>
</AnchorPane>

10.BookController控制器

package com.soft1841.book.controller;

import cn.hutool.db.Entity;
import com.soft1841.book.dao.BookDAO;
import com.soft1841.book.dao.TypeDAO;
import com.soft1841.book.entity.Book;
import com.soft1841.book.entity.Type;
import com.soft1841.book.utils.ComponentUtil;
import com.soft1841.book.utils.DAOFactory;
import javafx.beans.property.ReadOnlyObjectWrapper;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

import java.net.URL;
import java.sql.SQLException;
import java.util.List;
import java.util.Optional;
import java.util.ResourceBundle;

public class BookController implements Initializable {
   //布局文件中的表格视图对象,用来显示数据库中读取的所有图书信息
   @FXML
   private TableView<Book> bookTable;

   //布局文件中的下拉框组件对象,用来显示数据库中读取的所有图书类别
   @FXML
   private ComboBox<Type> typeComboBox;

   //布局文件中的输入文本框对象,用来输入搜索关键词
   @FXML
   private TextField keywordsField;

   //图书模型数据集合,可以实时相应数据变化,无需刷新
   private ObservableList<Book> bookData = FXCollections.observableArrayList();

   //图书类型模型数据集合
   private ObservableList<Type> typeData = FXCollections.observableArrayList();

   //图书DAO对象,从DAO工厂通过静态方法获得
   private BookDAO bookDAO = DAOFactory.getBookDAOInstance();

   //图书类型DAO对象
   private TypeDAO typeDAO = DAOFactory.getTypeDAOInstance();

   //图书实体集合,存放数据库图书表各种查询的结果
   private List<Entity> bookList = null;

   //类别实体集合,存放数据库类别表查询结果
   private List<Entity> typeList = null;

   //表格中的编辑列
   private TableColumn<Book, Book> editCol = new TableColumn<>("操作");

   //表格中的删除列
   private TableColumn<Book, Book> delCol = new TableColumn<>("操作");

   //初始化方法,通过调用对图书表格和列表下拉框的两个封装方法,实现数据初始化
   @Override
   public void initialize(URL location, ResourceBundle resources) {
       initTable();
       initComBox();
   }

   //表格初始化方法
   private void initTable() {
       //水平方向不显示滚动条,表格的列宽会均匀分布
       bookTable.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);

       //1.调用底层查询所有图书的方法,
       try {
           bookList = bookDAO.selectAllBooks();
       } catch (SQLException e) {
           e.printStackTrace();
       }
       //将实体集合作为参数,调用显示数据的方法,可以在界面的表格中显示图书模型集合的值
       showBookData(bookList);

       //2.编辑列的相关设置
       editCol.setCellValueFactory(param -> new ReadOnlyObjectWrapper<>(param.getValue()));
       editCol.setCellFactory(param -> new TableCell<Book, Book>() {
           //通过ComponentUtil工具类的静态方法,传入按钮文字和样式,获得一个按钮对象
           private final Button editButton = ComponentUtil.getButton("编辑", "blue-theme");
           @Override
           protected void updateItem(Book book, boolean empty) {
               super.updateItem(book, empty);
               if (book == null) {
                   setGraphic(null);
                   return;
               }
               setGraphic(editButton);
               //点击编辑按钮,弹出窗口,输入需要修改的图书价格
               editButton.setOnAction(event -> {
                   TextInputDialog dialog = new TextInputDialog("请输入价格");
                   dialog.setTitle("图书修改界面");
                   dialog.setHeaderText("书名:" + book.getName());
                   dialog.setContentText("请输入新的价格:");
                   Optional<String> result = dialog.showAndWait();
                   //确认输入了内容,避免NPE
                   if (result.isPresent()) {
                       //获取输入的新价格并转化成Double数据
                       String priceString = result.get();
                       book.setPrice(Double.parseDouble(priceString));
                       try {
                           //更新图书信息
                           bookDAO.updateBook(book);
                       } catch (SQLException e) {
                           e.printStackTrace();
                       }
                   }
               });
           }
       });
       //将编辑列加入图书表格
       bookTable.getColumns().add(editCol);

       //3.删除列的相关设置
       delCol.setCellValueFactory(param -> new ReadOnlyObjectWrapper<>(param.getValue()));
       delCol.setCellFactory(param -> new TableCell<Book, Book>() {
           private final Button deleteButton = ComponentUtil.getButton("删除", "warning-theme");
           @Override
           protected void updateItem(Book book, boolean empty) {
               super.updateItem(book, empty);
               if (book == null) {
                   setGraphic(null);
                   return;
               }
               setGraphic(deleteButton);
               //点击删除按钮,需要将这一行从表格移除,同时从底层数据库真正删除
               deleteButton.setOnAction(event -> {
                   Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
                   alert.setTitle("确认对话框");
                   alert.setHeaderText("请确认");
                   alert.setContentText("确定要删除这行记录吗?");
                   Optional<ButtonType> result = alert.showAndWait();
                   //点击了确认按钮,执行删除操作,同时移除一行模型数据
                   if (result.get() == ButtonType.OK){
                       bookData.remove(book);
                       try {
                           bookDAO.deleteBookById(book.getId());
                       } catch (SQLException e) {
                           e.printStackTrace();
                       }
                   }
               });
           }
       });
       //将除列加入图书表格
       bookTable.getColumns().add(delCol);

       //4.图书表格双击事件,双击弹出显示图书详情的界面
       bookTable.setRowFactory(tv -> {
           TableRow<Book> row = new TableRow<>();
           row.setOnMouseClicked(event -> {
               //判断鼠标双击了一行
               if (event.getClickCount() == 2 && (!row.isEmpty())) {
                   //获得该行的图书ID属性
                   long id = row.getItem().getId();
                   Book book = new Book();
                   try {
                       //通过ID到数据库查询到该图书对象的完整信息,因为表格中没有显示全,如
                       //图书封面、摘要等,但是在详情界面需要这些数据,如果不查出完整信息,会有空值异常
                       Entity entity = bookDAO.getBookById(id);
                       book.setId(entity.getLong("id"));
                       book.setTypeId(entity.getLong("type_id"));
                       book.setName(entity.getStr("name"));
                       book.setAuthor(entity.getStr("author"));
                       book.setPrice(entity.getDouble("price"));
                       book.setCover(entity.getStr("cover"));
                       book.setSummary(entity.getStr("summary"));
                       book.setStock(entity.getInt("stock"));
                   } catch (SQLException e) {
                       e.printStackTrace();
                   }
                 //  System.out.println(book.getName() + book.getPrice() + book.getCover() + book.getSummary());
                   //创建一个新的图书详情界面窗口
                   Stage bookInfoStage = new Stage();
                   bookInfoStage.setTitle("图书详情界面");
                   //用VBox显示具体图书信息
                   VBox vBox = new VBox();
                   vBox.setSpacing(10);
                   vBox.setAlignment(Pos.CENTER);
                   vBox.setPrefSize(600, 400);
                   vBox.setPadding(new Insets(10, 10, 10, 10));
                   Label nameLabel = new Label("书名:" + book.getName());
                   nameLabel.getStyleClass().add("font-title");
                   Label authorLabel = new Label("作者:" + book.getAuthor());
                   Label priceLabel = new Label("价格:" + book.getPrice());
                  Label stockLabel = new Label("库存:"+book.getStock());
                   ImageView bookImgView = new ImageView(new Image(book.getCover()));
                   bookImgView.setFitHeight(150);
                   bookImgView.setFitWidth(120);
                   Label summaryLabel = new Label(book.getSummary());
                   summaryLabel.setPrefWidth(400);
                   summaryLabel.setWrapText(true);
                   summaryLabel.getStyleClass().add("box");
                   vBox.getChildren().addAll(nameLabel, authorLabel, priceLabel,stockLabel,bookImgView, summaryLabel);
                   Scene scene = new Scene(vBox, 640, 480);
                   //因为是一个新的窗口,需要重新读入一下样式表,这个界面就可以使用style.css样式表中的样式了
                   scene.getStylesheets().add("/css/style.css");
                   bookInfoStage.setScene(scene);
                   bookInfoStage.show();
               }
           });
           return row;
       });
   }

   //下拉框初始化方法
   private void initComBox() {
       //1.到数据库查询所有的类别
       try {
           typeList = typeDAO.selectAllTypes();
       } catch (SQLException e) {
           e.printStackTrace();
       }
       //2.遍历typeList集合,将其加入typeData模型数据集合
       for (Entity entity : typeList) {
           Type type = new Type();
           type.setId(entity.getLong("id"));
           type.setTypeName(entity.getStr("type_name"));
           typeData.add(type);
       }
       typeComboBox.setItems(typeData);

       //4.下拉框选择事件监听,根据选择不同的类别,图书表格中会过滤出该类别的图书
       typeComboBox.getSelectionModel().selectedItemProperty().addListener((options, oldValue, newValue) -> {
                  // System.out.println(newValue.getId() + "," + newValue.getTypeName());

                   //移除掉之前的数据
                   bookTable.getItems().removeAll(bookData);
                   try {
                       //根据选中的类别查询该类别所有图书
                       bookList = bookDAO.selectBooksByTypeId(newValue.getId());
                   } catch (SQLException e) {
                       e.printStackTrace();
                   }
                   //重新显示数据
                   showBookData(bookList);
               }
       );
   }

   //显示图书表格数据的方法
   private void showBookData(List<Entity> bookList) {
       for (Entity entity : bookList) {
           Book book = new Book();
           book.setId(entity.getInt("id"));
           book.setName(entity.getStr("name"));
           book.setAuthor(entity.getStr("author"));
           book.setPrice(entity.getDouble("price"));
           book.setStock(entity.getInt("stock"));
           bookData.add(book);
       }
       bookTable.setItems(bookData);
   }

   //弹出新增图书界面方法
   public void newBookStage() throws Exception {
       Stage addBookStage = new Stage();
       FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource("/fxml/add_book.fxml"));
       AnchorPane root = fxmlLoader.load();
       Scene scene = new Scene(root);
       scene.getStylesheets().add("/css/style.css");
       AddBookController addBookController = fxmlLoader.getController();
       addBookController.setBookData(bookData);
       addBookStage.setTitle("新增图书界面");
       //界面大小不可变
       addBookStage.setResizable(false);
       addBookStage.setScene(scene);
       addBookStage.show();
   }

   //根据关键词搜索方法
   public void search() {
       bookTable.getItems().removeAll(bookData);
       //获得输入的查询关键字
       String keywords = keywordsField.getText().trim();
       try {
           bookList = bookDAO.selectBooksLike(keywords);
       } catch (SQLException e) {
           e.printStackTrace();
       }
       showBookData(bookList);
   }
}

11.AddBookController控制器

package com.soft1841.book.controller;

import cn.hutool.db.Entity;
import com.soft1841.book.dao.BookDAO;
import com.soft1841.book.dao.TypeDAO;
import com.soft1841.book.entity.Book;
import com.soft1841.book.entity.Type;
import com.soft1841.book.utils.DAOFactory;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Alert;
import javafx.scene.control.ComboBox;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.stage.Stage;

import java.net.URL;
import java.sql.SQLException;
import java.util.List;
import java.util.ResourceBundle;

public class AddBookController implements Initializable {
    private ObservableList<Book> bookData = FXCollections.observableArrayList();

    public ObservableList<Book> getBookData() {
        return bookData;
    }

    public void setBookData(ObservableList<Book> bookData) {
        this.bookData = bookData;
    }

    @FXML
    private ComboBox<Type> bookType;

    @FXML
    private TextField bookName, bookAuthor, bookPrice, bookCover,bookStock;
    @FXML
    private TextArea bookSummary;

    private ObservableList<Type> typeData = FXCollections.observableArrayList();

    private BookDAO bookDAO = DAOFactory.getBookDAOInstance();

    private TypeDAO typeDAO = DAOFactory.getTypeDAOInstance();

    private List<Entity> entityList = null;

    private Long typeId;

    @Override
    public void initialize(URL location, ResourceBundle resources) {

        try {
            entityList = typeDAO.selectAllTypes();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        for (Entity entity : entityList) {
            Type type = new Type();
            type.setId(entity.getLong("id"));
            type.setTypeName(entity.getStr("type_name"));
            typeData.add(type);
        }
        bookType.setItems(typeData);
        bookType.getSelectionModel().selectedItemProperty().addListener((options, oldValue, newValue) -> {
                    typeId = newValue.getId();
                }
        );
    }

    public void addBook() throws Exception {
        String name = bookName.getText();
        String author = bookAuthor.getText();
        String price = bookPrice.getText();
        String stock = bookStock.getText();
        String cover = bookCover.getText();
        String summary = bookSummary.getText();
        System.out.println(stock);
        Book book = new Book();
        book.setTypeId(typeId);
        book.setName(name);
        book.setAuthor(author);
        book.setPrice(Double.parseDouble(price));
        book.setStock(Integer.parseInt(stock));
        book.setCover(cover);
        book.setSummary(summary);
        long id = bookDAO.insertBook(book);
        book.setId(id);
        this.getBookData().add(book);
        Alert alert = new Alert(Alert.AlertType.INFORMATION);
        alert.setTitle("提示信息");
        alert.setHeaderText("新增图书成功!");
        alert.showAndWait();
        Stage stage = (Stage) bookName.getScene().getWindow();
        stage.close();
    }
}

12.运行效果:
模型和视图绑定后,无需刷新界面,新增、修改、删除都可以无刷新实时显示。

  • 图书信息显示


    image.png
  • 根据类别过滤


    image.png
  • 根据关键词搜索


    image.png
  • 新增图书


    image.png
  • 编辑价格


    image.png
  • 删除


    image.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容