java - 如何检查 Java 日期类型的有效性?
问题描述
我写了两个简单的函数来获取我在 MySQL 表中的日期值。开始日期和结束日期列都是Date
数据类型。所以,在我的这两个函数中是这样的:
public Date get_startdate(long nodeid,String ts) {
try {
String sql="Select STARTDT FROM urllink WHERE URL='f0="+nodeid+"&ts="+ts + "'";
if (em == null) {
throw new Exception("could not found URL object.");
}
return (Date) em.createNativeQuery(sql).getSingleResult();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public Date get_enddate(long nodeid,String ts) {
try {
String sql="Select ENDDT FROM urllink WHERE URL='f0="+nodeid+"&ts="+ts + "'";
if (em == null) {
throw new Exception("could not found URL object.");
}
return (Date) em.createNativeQuery(sql).getSingleResult();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
现在我像这样在我的主页中调用这些函数,我想检查日期条件,如果 URL 在这两个日期之间,那么它应该是有效的并做一些事情。我在下面强调我的意思:
Date file_getstartdate=fileFacade1.get_startdate(fileID,hash);
Date file_getenddate=fileFacade1.get_enddate(fileID,hash);
String currentDate = CoreUtil.parseDate(new Date());
if( file_getstartdate<= currentDate<= file_getendDate){
//URL is valid, do something
}else {
//do nothing
}
我存储在表格中的日期是格式YYYY-MM-DD
,我面临的问题是在if
上面的语句中进行比较。我不能使用这些运算符进行检查。有没有办法实现我的愿望?
解决方案
不要使用字符串连接来构造 SQL 查询
这很容易受到 SQL 注入的影响,而且非常危险:
String sql="Select STARTDT FROM urllink WHERE URL='f0="+nodeid+"&ts="+ts + "'";
...
return (Date) em.createNativeQuery(sql).getSingleResult();
假设em
引用一个EntityManager对象,那么您可以构建一个Criteria
基于查询,或者如果您确实需要坚持使用本机 SQL,那么您应该使用PreparedStatement代替。
对于您的比较问题,您有三个问题:
- 您正在尝试比较两种不同的类型(
String
和Date
)。 - 您正在尝试使用只能用于比较原语但不能用于比较对象 (
<=
) 的运算符。 - 您将条件写成数学语句而不是编程条件语句(
a <= b <= c
不是有效的 Java 语句。它必须是a <= b && b <= c
)。
这是使用Date
该类进行比较的一种方法(请注意,LocalDate
如果您有选择,Java 8 是一个更好的类)。
Date fileStartDate = fileFacade1.get_startdate(fileID, hash);
Date fileEndDate = fileFacade1.get_enddate(fileID, hash);
Date currentDate = new Date();
if (fileStartDate.before(currentDate) && fileEndDate.after(currentDate) {
...
回应您的评论
好的,但是使用preparedStatement 是否有助于此SQL 注入。实体管理器是否阻止注入?有人告诉我不要使用preparedstatement,还有其他选择吗?
如果有人告诉您使用字符串连接(代码的+nodeid+
和+ts +
部分)而不是使用 PreparedStatement 进行本机查询,那么他们是错误的。EntityManager 不会保护您免受上述代码中的注入,但 PreparedStatement 以及更改查询的构造方式会。
PreparedStatement 看起来像
String url = "f0=" + nodeid + "&ts=" + ts;
PreparedStatement preparedStatement = connection.prepareStatement("Select STARTDT FROM urllink WHERE URL= ?");
preparedStatement.setString(1, url);
ResultSet resultSet = preparedStatement.executeQuery();
如果您被告知使用 anEntityManager
而不是编写本机 SQL,那么这实际上是个好建议。您需要使用Criteria
抽象构造查询。如何做到这一点可能是一个单独的问题。
推荐阅读
- php - 数组内爆导致 RabbitMQ 接收到空的 msg 正文,但其他发布者显示正文
- forms - WTForm modelform 不显示数据库记录中的复选框值
- python - 如何将值传递给 Django 自定义模板标签的函数
- c++ - 如何在 macOS 上导入 openssl/sha.h 或 openssl/md5.h
- string - while循环如何与字符串拼接一起找出字符串的长度?
- javascript - 在 JS 脚本中推送 PHP 数组
- javascript - 按月过滤一系列产品
- mysql - SequelizeDatabaseError:无法读取未定义的属性“解析”
- sql - 在 Postgresql 插入查询中获取“错误:在或附近出现语法错误”
- reactjs - 在自定义钩子中设置多个状态