首页
学习
活动
专区
圈层
工具
发布

在javafx中编辑TableView数据库表

JavaFX中编辑TableView数据库表

基础概念

TableView是JavaFX中用于显示和编辑表格数据的控件,常用于展示数据库查询结果并提供编辑功能。它与数据库表的交互通常通过数据模型和控制器实现。

相关优势

  1. 可视化数据展示和编辑
  2. 内置排序、过滤功能
  3. 支持单元格级别编辑
  4. 与JavaFX其他组件良好集成
  5. 支持自定义单元格渲染

实现方式

1. 基本TableView与数据库集成

代码语言:txt
复制
// 数据库连接类
public class DBConnection {
    private static final String URL = "jdbc:mysql://localhost:3306/mydb";
    private static final String USER = "username";
    private static final String PASS = "password";
    
    public static Connection getConnection() throws SQLException {
        return DriverManager.getConnection(URL, USER, PASS);
    }
}

// 数据模型类
public class Person {
    private final IntegerProperty id;
    private final StringProperty name;
    private final IntegerProperty age;
    
    public Person(int id, String name, int age) {
        this.id = new SimpleIntegerProperty(id);
        this.name = new SimpleStringProperty(name);
        this.age = new SimpleIntegerProperty(age);
    }
    
    // Getter和Setter方法...
}

// 主控制器类
public class TableViewController implements Initializable {
    @FXML private TableView<Person> tableView;
    @FXML private TableColumn<Person, Integer> idColumn;
    @FXML private TableColumn<Person, String> nameColumn;
    @FXML private TableColumn<Person, Integer> ageColumn;
    
    private ObservableList<Person> personData = FXCollections.observableArrayList();
    
    @Override
    public void initialize(URL location, ResourceBundle resources) {
        // 设置列与属性的绑定
        idColumn.setCellValueFactory(cellData -> cellData.getValue().idProperty().asObject());
        nameColumn.setCellValueFactory(cellData -> cellData.getValue().nameProperty());
        ageColumn.setCellValueFactory(cellData -> cellData.getValue().ageProperty().asObject());
        
        // 启用表格编辑
        tableView.setEditable(true);
        
        // 设置可编辑列
        nameColumn.setCellFactory(TextFieldTableCell.forTableColumn());
        ageColumn.setCellFactory(TextFieldTableCell.forTableColumn(new IntegerStringConverter()));
        
        // 加载数据
        loadDataFromDB();
    }
    
    private void loadDataFromDB() {
        try (Connection conn = DBConnection.getConnection();
             Statement stmt = conn.createStatement();
             ResultSet rs = stmt.executeQuery("SELECT * FROM persons")) {
            
            while (rs.next()) {
                personData.add(new Person(
                    rs.getInt("id"),
                    rs.getString("name"),
                    rs.getInt("age")
                ));
            }
            tableView.setItems(personData);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    
    // 编辑提交处理
    @FXML
    private void handleNameEdit(TableColumn.CellEditEvent<Person, String> event) {
        Person person = event.getRowValue();
        person.setName(event.getNewValue());
        updatePersonInDB(person);
    }
    
    @FXML
    private void handleAgeEdit(TableColumn.CellEditEvent<Person, Integer> event) {
        Person person = event.getRowValue();
        person.setAge(event.getNewValue());
        updatePersonInDB(person);
    }
    
    private void updatePersonInDB(Person person) {
        String sql = "UPDATE persons SET name = ?, age = ? WHERE id = ?";
        
        try (Connection conn = DBConnection.getConnection();
             PreparedStatement pstmt = conn.prepareStatement(sql)) {
            
            pstmt.setString(1, person.getName());
            pstmt.setInt(2, person.getAge());
            pstmt.setInt(3, person.getId());
            pstmt.executeUpdate();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

2. 使用ORM框架(如Hibernate)

代码语言:txt
复制
@Entity
@Table(name = "persons")
public class Person {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    
    private String name;
    private int age;
    
    // Getter和Setter方法...
}

// 控制器中使用Hibernate
public class TableViewController implements Initializable {
    // ...其他代码同前...
    
    private void loadDataFromDB() {
        Session session = HibernateUtil.getSessionFactory().openSession();
        List<Person> persons = session.createQuery("FROM Person", Person.class).list();
        session.close();
        
        personData.addAll(persons);
        tableView.setItems(personData);
    }
    
    private void updatePersonInDB(Person person) {
        Session session = HibernateUtil.getSessionFactory().openSession();
        Transaction tx = null;
        
        try {
            tx = session.beginTransaction();
            session.update(person);
            tx.commit();
        } catch (Exception e) {
            if (tx != null) tx.rollback();
            e.printStackTrace();
        } finally {
            session.close();
        }
    }
}

常见问题及解决方案

1. 数据不更新问题

原因: 可能是未正确设置可编辑属性或未绑定事件处理器 解决:

代码语言:txt
复制
tableView.setEditable(true);
nameColumn.setCellFactory(TextFieldTableCell.forTableColumn());
nameColumn.setOnEditCommit(event -> handleNameEdit(event));

2. 数据库连接问题

原因: 连接未正确关闭或连接池耗尽 解决: 使用try-with-resources确保资源释放

代码语言:txt
复制
try (Connection conn = DBConnection.getConnection();
     Statement stmt = conn.createStatement()) {
    // 执行查询
}

3. 性能问题

原因: 大量数据加载导致界面卡顿 解决: 使用分页加载

代码语言:txt
复制
// 分页查询
String sql = "SELECT * FROM persons LIMIT ? OFFSET ?";
pstmt.setInt(1, pageSize);
pstmt.setInt(2, pageNumber * pageSize);

4. 数据同步问题

原因: 多用户同时编辑导致数据不一致 解决: 使用乐观锁或时间戳检查

代码语言:txt
复制
// 更新时检查版本
String sql = "UPDATE persons SET name=?, age=?, version=version+1 WHERE id=? AND version=?";
pstmt.setInt(4, originalVersion);

高级功能实现

1. 自定义单元格编辑器

代码语言:txt
复制
// 自定义年龄编辑器
ageColumn.setCellFactory(column -> new TableCell<Person, Integer>() {
    private final Spinner<Integer> spinner = new Spinner<>(0, 150, 0);
    
    {
        spinner.setEditable(true);
        spinner.valueProperty().addListener((obs, oldVal, newVal) -> {
            if (isEditing()) {
                commitEdit(newVal);
            }
        });
    }
    
    @Override
    protected void updateItem(Integer item, boolean empty) {
        super.updateItem(item, empty);
        if (empty) {
            setGraphic(null);
        } else {
            spinner.getValueFactory().setValue(item);
            setGraphic(spinner);
        }
    }
});

2. 添加删除行功能

代码语言:txt
复制
@FXML
private void handleDelete() {
    Person selected = tableView.getSelectionModel().getSelectedItem();
    if (selected != null) {
        deleteFromDB(selected.getId());
        personData.remove(selected);
    }
}

private void deleteFromDB(int id) {
    String sql = "DELETE FROM persons WHERE id = ?";
    try (Connection conn = DBConnection.getConnection();
         PreparedStatement pstmt = conn.prepareStatement(sql)) {
        pstmt.setInt(1, id);
        pstmt.executeUpdate();
    } catch (SQLException e) {
        e.printStackTrace();
    }
}

3. 添加新行功能

代码语言:txt
复制
@FXML
private void handleAdd() {
    String sql = "INSERT INTO persons (name, age) VALUES (?, ?)";
    try (Connection conn = DBConnection.getConnection();
         PreparedStatement pstmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
        
        pstmt.setString(1, "New Person");
        pstmt.setInt(2, 20);
        pstmt.executeUpdate();
        
        try (ResultSet rs = pstmt.getGeneratedKeys()) {
            if (rs.next()) {
                int newId = rs.getInt(1);
                Person newPerson = new Person(newId, "New Person", 20);
                personData.add(newPerson);
                tableView.getSelectionModel().select(newPerson);
            }
        }
    } catch (SQLException e) {
        e.printStackTrace();
    }
}

应用场景

  1. 企业管理系统(CRM, ERP等)
  2. 数据分析和报表工具
  3. 库存管理系统
  4. 用户管理系统
  5. 任何需要表格数据展示和编辑的场景

通过以上实现,可以在JavaFX中创建功能完善的TableView数据库表编辑器,支持增删改查等基本操作,并能根据需要进行扩展和定制。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

  • iOS学习——tableview中带编辑功能的cell键盘弹出遮挡和收起问题解决

    言归正传,下面就说回到我们要解决的问题,在UITableView的cell中,系统自带的UITableViewCell的格式没有自带UITextField或UITextView这种可以编辑的区域的,而这种类型的...,在这个过程中我们需要回传什么信息,才能保证我们的可以对我们控制器中的tableview进行控制。...下面的流程就是UITextField或UITextView在整个编辑过程中的详细流程步骤: 在成为第一响应者之前,文本框调用其代理的textFieldShouldBeginEditing:  方法来允许或阻止其第一响应者...2.2 自定义包含UITextField的UITableViewCell   首先,我们在点击编辑区域的时候,获取到当前编辑区域相对屏幕的位置,这样方便我们判断整个tableview是否需要上移以及需要上移多少比较合适...cell的应用,首先,我们再主控制器中定义几个属性来保存我们键盘弹出时tableview的contentOffset以及当前编辑cell的frame,然后在应用自定义cell时设定我们的两个回调block

    4.6K80

    酒店管理系统实操指南 整合 JavaFX Spring Boot 与 React 的经典

    以下是基于现代技术栈的酒店管理系统实操指南,结合JavaFX、Spring Boot和React重构经典项目:基于JavaFX + Spring Boot + React的酒店管理系统实战开发一、技术选型与架构设计...后端技术栈Spring Boot:简化后端开发,提供RESTful APISpring Security:实现用户认证与授权Spring Data JPA:数据库访问层MySQL:关系型数据库存储业务数据...@FXML private TableView roomTable; @FXML private TableColumn roomNumberCol;...数据库设计优化采用规范化设计,主要数据表包括:rooms:客房表(房间号、类型、价格、状态等)guests:客户表(姓名、联系方式、身份证号等)reservations:预订表(预订号、客房ID、客户ID...、入住/退房日期、状态等)employees:员工表(员工ID、姓名、职位、登录凭证等)payments:支付记录表(支付ID、预订ID、金额、支付方式、时间等)2.

    15600

    使用nano在Linux中编辑文件

    介绍 GNU nano,简称nano,是大多数Linux发行版的基本内置编辑器。GNU nano是一个小巧友好的文本编辑器....与基本的文本编辑相比,nano提供许多额外的特性,例如:交互式的查找和替换,定位到指定的行列,自动缩进,特性切换,国际化支持,以及文件名标记完成。本教程中,我们将介绍一些帮助您入门的基本知识。...在此示例中,我们将使用sudo权限打开系统的hosts文件: sudo nano /etc/hosts 使用上面的示例打开系统主机文件,结果类似于以下内容: 在默认视图中,nano将在顶部标题栏的中心显示正在编辑的文件...在底部,快捷方式列表显示常用命令,其中^代表CTRL键。要保存,按住CTRL并按O(对于Write * O * ut); 按CTRL + X退出。...nano快捷方式 ^ W:在打开的文件中搜索 ALT + W:找到下一个搜索实例 ^ O:保存文件 ^ K:删除整行 ^ U:粘贴整行 ^ T:查看文件浏览器 ^ X:退出 更多信息 有关此主题的其他信息

    8.5K40

    JavaFX 与 Java Swing 桌面应用开发实战指南

    :支持 CSS 样式、3D 效果和动画 丰富的控件库:包含 TableView、WebView 等高级组件 FXML 分离设计:界面与逻辑分离,提高开发效率 内置媒体支持:直接播放音频视频 响应式布局:...19+ 技术栈升级 1.1 模块化开发 Java 9+ 引入的模块系统解决了类路径混乱问题,在 module-info.java 中明确声明依赖: module com.techprimers.javafx...; } 三、高级UI组件实战 3.1 自定义表格渲染 创建可排序、可筛选的表格视图: // BookTableView.java public class BookTableView extends TableView...return books; } public StringProperty searchTextProperty() { return searchText; } } 4.2 FXML控制器集成 在控制器中注入视图模型...BookController.java // FXML控制器 │ │ │ └── util/ │ │ │ ├── DBUtil.java // 数据库工具

    68310

    在Navicat中如何新建数据库和表并做查询

    上一篇文章,小编给大家分享了在Navicat中如何远程连接数据库,没有来得及上车的小伙伴可以戳这篇文章:在Ubuntu14.04中配置mysql远程连接教程。...今天小编给大家分享一下如何在Navicat中新建数据库和表。 用过远程连接数据库工具的小伙伴都知道,在Navicat中新建数据库和表并不太难,具体的教程如下所示。...2、在IP地址为192.168.255.131数据库上右键,然后点击“新建数据库”,如下图所示。 3、之后弹出“新建数据库”对话框,在“常规”选项卡中需要设置数据库名、字符集和排序规则。...10、保存之后,可以看到表名由之前的“无标题”变成了现在的article,并且可以看到所设置的字段。 11、接下来在字段中输入内容。...13、在查询窗口中输入SQL语句进行搜索,如下图所示,试图查询article表中的数据。SQL语句写完之后,点击“运行”选项卡,之后查询到的结果将会在同一个窗口下进行显示,如下图所示。

    6.7K30

    在Navicat中如何新建数据库和表并做查询

    上一篇文章,小编给大家分享了在Navicat中如何远程连接数据库,没有来得及上车的小伙伴可以戳这篇文章:在Ubuntu14.04中配置mysql远程连接教程。...今天小编给大家分享一下如何在Navicat中新建数据库和表。 用过远程连接数据库工具的小伙伴都知道,在Navicat中新建数据库和表并不太难,具体的教程如下所示。...2、在IP地址为192.168.255.131数据库上右键,然后点击“新建数据库”,如下图所示。 ? 3、之后弹出“新建数据库”对话框,在“常规”选项卡中需要设置数据库名、字符集和排序规则。 ?...10、保存之后,可以看到表名由之前的“无标题”变成了现在的article,并且可以看到所设置的字段。 ? 11、接下来在字段中输入内容。...13、在查询窗口中输入SQL语句进行搜索,如下图所示,试图查询article表中的数据。SQL语句写完之后,点击“运行”选项卡,之后查询到的结果将会在同一个窗口下进行显示,如下图所示。 ?

    3.7K20

    Python | 数据库中的表

    与电子表格相似,数据在表中式按行和列的格式组织排列的。表中的每一列都设计为存储某种类型的信息(例如日期、名称、美元金额或数字)。...例如:表(账号,昵称,密码)中账号列就满足其特点可以充当表的主键。 (2) 外键:外键是将两个表连接在一起的键,一个表的主键可以在另一个表中当作这个表的外键,进而将两个表连接在一起。...其特点是:可以重复,可以为空,一个表可以有多个外键。 例如:表1(账号,昵称,密码)中的账号列(主键)就可以在表2(身份证id,名字,性别,生日,住址,账号)中的外键,从而将表1和表2关联起来。...结语 在数据库的建立中满足三大范式可以很大程度上的减小数据库的冗余,提升数据库的性能;主键的正确建立可以保证数据的唯一性,外键的正确建立可以保证数据的完整性和一致性,同时将不同的表关联在一起。...实习编辑:李欣容 稿件来源:深度学习与文旅应用实验室(DLETA)

    1.8K20

    数据库中的DUAL表

    在日常的数据库操作中,DUAL表是一个特殊的存在。它是一个伪表,用于在不需要实际数据表的情况下进行简单的查询。特别是在执行一些无关联的数据计算时,DUAL表经常派上用场。 什么是DUAL表?...这些查询不需要访问实际的业务数据,而DUAL表则提供了一个简便的占位符机制。 不同数据库中的DUAL表 各大数据库对DUAL表的实现略有不同。让我们来看看不同数据库系统中的用法和特点。 1....MySQL 中的 DUAL 表 在MySQL中,虽然也可以使用DUAL表,但它的使用并不像Oracle中那么严格。...MySQL数据库通常会直接使用: SELECT 1 在MySQL中,DUAL表不是必须的,因此直接查询常量也可以完成连接验证。...定期发送此查询来确保连接池中的连接仍然有效,可以避免数据库连接突然失效导致的服务中断。 小结 DUAL表作为一个伪表,虽然在不同数据库中的实现和依赖程度有所不同,但其核心用途是一致的:用于无表查询。

    92610

    在PowerBI中创建时间表(非日期表)

    在powerquery中创建日期表是使用powerbi过程中一个必不可少的内容(当然,你也可以使用DAX来创建): Power BI创建日期表的几种方式概览 但是很多时候我们进行数据分析时,只有日期表是不够的...,在某些行业中,我们不仅要对年、季度月、周、日等维度进行分析,我们可能还需要对分钟、小时、15分钟、5分钟等进行划分维度并分析。...有朋友会说,在日期表上添加一个时间列就完了,不过,如果你真的直接把时间添加在日期表上,你就会发现组合结果的庞大。假设日期表包括每天一条记录,其中包含 10 年的数据,也即是有3650行数据。...3亿行对于一个维度表来说,太过于huge。哪怕只保留到分钟,仍然会超过 500 万行,很显然是不合适的。 因此呢,不要合并日期和时间表。这两个表应该是两个不同的表,并且它们都可以与事实表建立关系。...添加办法也很简单,在powerquery中添加空白查询,然后打开高级查询编辑器,输入以下代码: ? 点击完成即可。

    5.4K10

    JavaFX-TableView详解

    先看看TableView中有些什么 在IDEA中,按住Ctrl然后点中TableView关键字会自动跟进到它定义的地方,我们可以先看看这里面到底都有些什么东西。.../ 官方的文档:http://docs.oracle.com/javafx/2/ui_controls/table-view.htm TableView列的两种数据形式: 一种是维护类的TableColumn...设置映射时需要这样: col.setCellValueFactory(new MapValueFactory(colName)); // colName对应字符类型列名``` 表格可编辑:...forTableColumn()); // 设置编辑响应的函数 col.setOnEditCommit(new EventHandler<TableColumn.CellEditEvent<Map...增加列,删除列 这就不仅仅要删除集合中的数据,还要从表格里面的Columns集合中删除相应的数据才可以,或许你还会在删除和增加中加入一定的判断来保证操作的正确性: table.getColumns().

    3.8K60

    在Excel公式中嵌入查找表

    标签:Excel公式 通常,我们会在工作表中放置查找表,然后使用公式在该表中查找相对应的值。然而,这也存在风险,就是用户可能会在删除行时无意识地将查找表中的内容也删除,从而导致查找错误。...如下图1所示,将查找表放置在列AA和列BB中。 图1 如下图2所示,在查找表中查找列A中的值并返回相应的结果。...图2 此时,如果我们删除行,而这些删除的行刚好在查找表数据所在的行,那么就破坏了查找表。那么,该怎么避免这种情况呢? 一种解决方法是在另一个工作表中放置查找表,然后隐藏该工作表。...然而,如果查找表的数据不多,正如上文示例中那样,那么可以将查找表嵌入到公式中。 如下图3所示,选择公式中代表查找表所在单元格区域的字符。...如果不好理解,你可以直接将其复制到工作表中。 按Ctrl+C键复制花括号内容后,在工作表中选择5行2列区域,输入=号,按Ctrl+V键,再按Ctrl+Shift+Enter组合键,结果如下图6所示。

    1.7K30
    领券