You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaFX中Scene1插入数据库后Scene2自动弹窗通知问题求助

解决车辆预订系统实时通知问题

你的核心问题是getNotification()方法仅在user2登录时执行一次,无法持续监听数据库的新增预订请求,导致运行期间的新请求无法触发通知。以下是几种可行的解决思路和代码实现:

一、快速实现:定时轮询数据库(最易落地)

通过定时任务定期查询数据库,检测新增的待处理请求,同时避免重复通知。

1. 核心修改步骤

  • 记录最后处理的预订ID,过滤已通知过的请求
  • 使用定时任务框架定期执行查询
  • 优化数据库连接和SQL安全性

2. 修改后的代码示例

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import javafx.util.Duration;
import tray.notification.NotificationType;
import tray.notification.TrayNotification;

public class User2Controller {
    private String getDepartment;
    private long lastProcessedBookingId = 0; // 记录最后处理的预订ID(假设表中有自增的booking_id字段)
    private ScheduledExecutorService scheduler;
    private HikariDataSource dataSource;

    // 控制器初始化方法(JavaFX中自动调用)
    public void initialize() {
        // 初始化数据库连接池
        initDataSource();
        
        // 登录时先执行一次,处理历史待处理请求
        try {
            getNotification();
        } catch (SQLException e) {
            e.printStackTrace();
        }

        // 启动定时任务:每隔5秒查询一次(可根据业务调整间隔)
        scheduler = Executors.newSingleThreadScheduledExecutor();
        scheduler.scheduleAtFixedRate(() -> {
            try {
                getNotification();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }, 5, 5, TimeUnit.SECONDS);

        // 窗口关闭时清理资源
        // 假设primaryStage是你的窗口对象,需根据实际场景获取
        // primaryStage.setOnCloseRequest(event -> {
        //     scheduler.shutdown();
        //     dataSource.close();
        // });
    }

    // 初始化HikariCP连接池(替代每次创建新连接)
    private void initDataSource() {
        HikariConfig config = new HikariConfig();
        config.setJdbcUrl("jdbc:mysql://localhost/vbms_db");
        config.setUsername("root");
        config.setPassword("");
        config.setDriverClassName("com.mysql.cj.jdbc.Driver"); // 替换为新版驱动
        config.setMaximumPoolSize(5); // 连接池大小按需调整
        dataSource = new HikariDataSource(config);
    }

    // 修改后的通知查询方法
    public void getNotification() throws SQLException {
        // 用try-with-resources自动释放数据库资源
        try (Connection conn = dataSource.getConnection()) {
            getDepartment = lbl_holdUserDepartment.getText();
            // 仅查询未处理过的新请求,避免重复通知
            String sql = "SELECT * FROM bookings WHERE driver_department = ? AND vehicle_AvailStatus = 'Pending...' AND booking_id > ? ORDER BY booking_id ASC";
            
            try (PreparedStatement pst = conn.prepareStatement(sql)) {
                pst.setString(1, getDepartment);
                pst.setLong(2, lastProcessedBookingId);
                
                try (ResultSet rs = pst.executeQuery()) {
                    while (rs.next()) {
                        // 更新最后处理的ID,避免重复通知
                        lastProcessedBookingId = rs.getLong("booking_id");
                        
                        // 触发托盘通知
                        NotificationType nt = NotificationType.WARNING;
                        TrayNotification tray = new TrayNotification();
                        tray.setTitle("新预订通知");
                        tray.setMessage("有新的车辆预订请求,请及时处理!");
                        tray.setNotificationType(nt);
                        tray.showAndDismiss(Duration.millis(3000));
                    }
                }
            }
        }
    }
}

3. 关键优化点

  • SQL注入防护:替换字符串拼接为PreparedStatement参数绑定,避免安全风险
  • 资源自动释放:使用try-with-resources确保数据库连接、语句、结果集自动关闭,防止资源泄漏
  • 连接池优化:用HikariCP连接池替代每次创建新连接,提升性能
  • 避免重复通知:通过lastProcessedBookingId过滤已处理的请求,同一请求不会重复弹窗

二、更高效方案:主动推送(适合客户端-服务器架构)

如果你的系统是客户端-服务器模式,可以在user1提交请求时,由服务器主动向对应部门的user2客户端推送通知(比如用WebSocket),比定时轮询更高效,实时性更强。

核心思路:

  1. user2客户端登录后与服务器建立WebSocket连接
  2. user1提交预订请求时,服务器根据driver_department找到对应的在线user2客户端
  3. 服务器主动向目标客户端发送通知消息,客户端收到后触发TrayNotification

三、注意事项

  • 定时轮询的间隔需根据业务平衡:间隔太短会增加数据库压力,太长会降低实时性
  • 需确保bookings表有唯一自增的ID字段(比如booking_id),用于跟踪已处理的请求
  • 新版MySQL驱动需替换为com.mysql.cj.jdbc.Driver,旧驱动已废弃

内容的提问来源于stack exchange,提问作者T_Miles

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 19:40:15