您好: 当我使用hibernate进行一些查询时,我遇到了一个非常奇怪的问题:
这是核心代码:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
start = sdf.parse("2011-02-22 10:00:00");
end = sdf.parse("2011-02-22 16:00:00");
Query q = sess.createQuery("select log.uri,count(log.uri) as num from LogEntry log where log.time between ? and ? group by log.uri order by num desc")
.setDate(0, start).setDate(1, end);
System.out.println(q.list()); //here I got 0 result,
System.out.println("===== Make the start date smaller =========");
start=sdf.parse("2011-02-21 10:00:00");
q = sess.createQuery("select log.uri,count(log.uri) as num from LogEntry log where log.time between ? and ? group by log.uri order by num desc")
.setDate(0, start).setDate(1, end);
System.out.println(q.list()); //here I got 26 result
System.out.println("===== Make the end date bigger =========");
end=sdf.parse("2011-02-23 16:00:00");
q = sess.createQuery("select log.uri,count(log.uri) as num from LogEntry log where log.time between ? and ? group by log.uri order by num desc")
.setDate(0, start).setDate(1, end); //here I got 39 result
System.out.println(q.list());
从上面看,似乎在db中有
“2011-02-22 10:00:00”和“2011-02-22 16:00:00”之间00结果,但有
“2011-02-21 10:00:00”和“2011-02-23 16:00:00”之间23结果,
所以这意味着“2011-02-22 16:00:00”和“2011-02-23 16:00:00”之间肯定会有一些结果,但是当我做这个测试时,当前时间是“ 2011-02-22 14:45:00“!!!
另外,我也在数据库中做过测试,
select uri,count(uri) as num from xxx_log where time between 20110222100000 and 20110222160000 group by uri order by num desc
我设置了 23行。
所以我想知道为什么这么令人惊讶?
我的代码有什么问题吗?
BTW,我使用的是mysql 5.1。
更新
这是另一个测试代码,首先使用hibernate,然后使用本机sql:
@Test
public void testSQLAndHibernate() throws ParseException {
start = sdf.parse("2011-02-22 10:00:00");
end = sdf.parse("2011-02-22 16:00:00");
// use hibernate
Session sess = HibernateUtil.getSessionFactory().getCurrentSession();
sess.beginTransaction();
Query q = sess
.createQuery(
"select log.uri,count(log.uri) as num from LogEntry log where log.time between ? and ? group by log.uri order by num desc")
.setDate(0, start).setDate(1, end);
System.out.println("get "+q.list().size()+" results by hibernate");
System.out.println("++++++++++++++");
// use sql
SimpleDateFormat sdf_sql = new SimpleDateFormat("yyyyMMddHHmmss");
String sql = "select uri,count(uri) as num from t_log where time between "
+ sdf_sql.format(start) + " and " + sdf_sql.format(end)
+ " group by uri order by num desc";
try {
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db",
"root", "0000");
Statement state = conn.createStatement();
ResultSet rs = state.executeQuery(sql);
int i=0;
while (rs.next()) {
//System.out.println(rs.getString(1) + " " + rs.getLong(2));
i++;
}
System.out.println("get "+i+" results by sql query");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
输出:
get 0 results by hibernate
++++++++++++++
get 24 results by sql query
同样来自hibernat日志我得到了:
binding parameter [1] as [DATE] - Tue Feb 22 10:00:00 CST 2011
binding parameter [2] as [DATE] - Tue Feb 22 16:00:00 CST 2011
似乎开始和结束日期是正确的
答案 0 :(得分:1)
执行System.out.println(end)
和System.out.println(start)
时的结果是什么?它们是正确的格式吗?
如果时间格式偏离预期,Mysql会产生非常奇怪的结果。
答案 1 :(得分:1)
请注意,您通过setDate()
传递参数,因此它们被解释为SQL类型DATE
。在本机查询的情况下,您将日期作为日期文字传递,我想在这种情况下,它们被解释为TIMESTAMP
s。这是HQL和本机查询之间的唯一区别。
因此,请尝试通过setTimestamp()
传递参数。