如何编写Java方法实现SQL查询:存在15分钟内预约返回true无结果返回false
问题描述
我目前需要通过查询User_ID来获取未来15分钟内的appointments列表,我正在使用的查询语句如下:
SELECT * FROM appointments WHERE User_ID = ? and Start BETWEEN NOW() AND ADDDATE(NOW(), INTERVAL 15 MINUTE);
我想要实现如下逻辑:如果查询返回任意预约记录就返回true,如果返回0行结果就返回false,请问应该如何实现?
我目前已经编写的代码如下:
public static boolean checkUpcomingAppointments(int userID) { try { String sqlCheck = "SELECT * FROM appointments WHERE User_ID = ? and Start BETWEEN NOW() AND ADDDATE(NOW(), INTERVAL 15 MINUTE);"; PreparedStatement ps = JDBC.getConnection().prepareStatement(sqlCheck); ps.setInt(1, userID); ps.execute(); } catch (SQLException throwables) { throwables.printStackTrace(); } return true; }
解决方案
优化思路
可以从SQL查询效率、Java逻辑正确性两个维度做调整:
1. SQL语句优化(推荐)
不需要查询全字段数据,仅判断是否存在匹配记录即可,使用EXISTS语法查询性能更高,不会返回多余行数据:
SELECT EXISTS(SELECT 1 FROM appointments WHERE User_ID = ? AND Start BETWEEN NOW() AND ADDDATE(NOW(), INTERVAL 15 MINUTE)) AS has_appointment;
该查询仅返回1行结果,值为1代表存在匹配记录,0代表无匹配记录。
2. Java代码修正
原有代码没有处理查询结果,无论是否有匹配记录都会返回true,且未做资源关闭处理容易引发连接泄漏,修正后代码如下:
public static boolean checkUpcomingAppointments(int userID) { boolean hasAppointment = false; String sqlCheck = "SELECT EXISTS(SELECT 1 FROM appointments WHERE User_ID = ? AND Start BETWEEN NOW() AND ADDDATE(NOW(), INTERVAL 15 MINUTE)) AS has_appointment"; // try-with-resources自动关闭连接资源,无需手动释放 try (PreparedStatement ps = JDBC.getConnection().prepareStatement(sqlCheck)) { ps.setInt(1, userID); try (ResultSet rs = ps.executeQuery()) { if (rs.next()) { hasAppointment = rs.getBoolean("has_appointment"); } } } catch (SQLException throwables) { throwables.printStackTrace(); } return hasAppointment; }
兼容原有SQL的快速修改方案
如果你不想调整SQL语句,也可以直接判断结果集是否存在下一行来得到结果:
public static boolean checkUpcomingAppointments(int userID) { boolean hasAppointment = false; String sqlCheck = "SELECT * FROM appointments WHERE User_ID = ? and Start BETWEEN NOW() AND ADDDATE(NOW(), INTERVAL 15 MINUTE);"; try (PreparedStatement ps = JDBC.getConnection().prepareStatement(sqlCheck)) { ps.setInt(1, userID); try (ResultSet rs = ps.executeQuery()) { // rs.next()返回true代表存在至少一行匹配记录 hasAppointment = rs.next(); } } catch (SQLException throwables) { throwables.printStackTrace(); } return hasAppointment; }
该方案逻辑可行,但如果匹配的预约记录较多会返回大量无用数据,性能低于EXISTS查询方案。
内容的提问来源于stack exchange,提问作者dkeys
相关产品推荐
相关产品推荐

