这几天一直在做quartz调度的开发,在做数据查询时经常用到对date类型字段的过滤,SQL(HQL)的拼接一直是头疼的问题,这里做个总结,只有记录才有进步。
SQL(HQL)的拼接在日常的使用中无非就那么两种方式,一种是使用字符串拼接,还有一种是使用查询参数。在这里强烈建议使用参数的方式来拼接SQL语句,防止SQL注入的安全问题,虽然最安全的方式是“不把任何没有经过验证的数据传入服务端”但是在实际的开发中真正能做到的又有多少呢。好了,全是废话,开始正题。
对于date类型字段的过滤要保证一点:拼接完成的SQL中传入或拼接上的值在SQL执行时必须是sql.Date类型的。
方式一:使用字符串拼接。
字符串拼接最后生成的只能是字符串,所以可以使用TO_DATE函数,将函数名接入SQL语句中,让SQL在执行时把字符串转换成java.sql.Date。
java.sql.Date startDate = new java.sql.Date(1000000000);
java.sql.Date endDate = new java.sql.Date(1100000000);
StringBuffer sbuf = new StringBuffer();
sbuf.append("from XXEntity t where t.time >= TO_DATE('")
.append(startDate)
.append("' , 'yyyy-mm-dd') and t.time <= TO_DATE('")
.append(endDate)
.append("' , 'yyyy-mm-dd')");
String sql = sbuf.toString();
System.out.println(sql);
最终打印的语句是:
from XXEntity t where t.time >= TO_DATE('1970-01-12' , 'yyyy-mm-dd') and t.time <= TO_DATE('1970-01-14' , 'yyyy-mm-dd')
从这条打印结果也不难发现:java.sql.Date 的toString()方法得到的时间字符串只有yyyy-mm-dd这种形式。所以如果你要操作代有时分秒的数据请用 timestamp类型存储,这时你要用SimpleDateFormat这个类做时间 格式的转换。这里只讨论date类型的数据。
看下面一段代码:
java.util.Date startDate1 = new java.util.Date();
java.util.Date endDate1 = new java.util.Date();
StringBuffer sbuf1 = new StringBuffer();
sbuf1.append("from XXEntity t where t.time >= TO_DATE('")
.append(startDate1)
.append("' , 'yyyy-mm-dd') and t.time <= TO_DATE('")
.append(endDate1)
.append("' , 'yyyy-mm-dd')");
String sql1 = sbuf1.toString();
System.out.println(sql1);
打印的结果如下:
from XXEntity t where t.time >= TO_DATE('Fri Aug 03 20:16:56 CST 2012' , 'yyyy-mm-dd') and t.time <= TO_DATE('Fri Aug 03 20:16:56 CST 2012' , 'yyyy-mm-dd')
这sql是没法执行的。所以在做sql拼接的时候要么使用java.sql.Date,要么使用SimpleDateFormat类做格式化处理,不然拼接的语句是不能执行的。
方式二:使用参数。
使用参数的方式传入变量的值是博主力推的方式,安全,灵活。
1.直接传入java.sql.Date类型的值:
java.sql.Date startDate = new java.sql.Date(1000000000);
java.sql.Date endDate = new java.sql.Date(1100000000);
String sqlString = "from XXEntity t where t.time >= :startTime and t.time <= :endTime";
Query query = session.createQuery(sqlString);
query.setParameter("startTime", startDate).setParameter("endTime", endDate);
query.list();
注意这里面startDate和endDate是做为java.sql.Date类型处理的,因为t.time是一个date类型,所以只能和date类 型的数据进行>=等运算。
2.使用字符串做为参数:
java.sql.Date startDate = new java.sql.Date(1000000000);
java.sql.Date endDate = new java.sql.Date(1100000000);
String sqlString = "from XXEntity t where t.time >= to_date(:startTime,'yyyy-mm-dd') and t.time <= (:endTime , 'yyyy-mm-dd') ";
Query query = session.createQuery(sqlString.toString());
query.setParameter("startTime", startDate).setParameter("endTime", endDate.toString());
query.list();
这里startTime和endTime都必须是字符串类型的。所以做设置参数的时候要把startDate和endDate做类型转换。
这里还有一个值得注意的地方: to_date(:startTime,'yyyy-mm-dd')一定不能写成 to_date(':startTime' , 'yyyy- mm-dd')。不然会出现找不到name为startTime的参数的错误。这个问题的原因是在使用参数 的时候,jdbc会根据 你传入值 的类型拼接sql语句,startTime最后的值一定会是 'yyyy-mm-dd'的形式,不会是yyyy-dd-mm的。
另外:发现有些博客中提到如果使用between的方式查询,在startTime和endTime相等的情况下是无法查出数据 的,小弟没有测试,有兴趣的可以亲测一下。
第一次写技术博客,以后会不断记下自己学习过程的点点滴滴,这里有些需要完善的地方希望前辈们能够给我多 些提点。
分享到:
相关推荐
hql语句大全hql语句大全hql语句大全hql语句大全hql语句大全hql语句大全hql语句大全hql语句大全hql语句大全hql语句大全hql语句大全hql语句大全hql语句大全hql语句大全hql语句大全hql语句大全hql语句大全
HQL语句大全HQL语句大全HQL语句大全HQL语句大全HQL语句大全
HQL语句 HQL语句 HQL语句 HQL语句 HQL语句
之前写好SQL,再到代码里面来写,语句复杂的看的时不时细节会忘记,用sql转换hql工具,直接贴近了就可以了;
非常详细直接实用的HQL语句的功能介绍 看过的人保准都说好
HQL语句查询
hibernate-HQL语句大全
HQL语句大全
HQL语句的语法,很基础
hql语句大全
HQL语句的用法,关于HQL与SQL语句的比较及其用法。
hql语句常规 方法 使用 了解hql语句
常见HQL语句的示例包括输出结果,以及语句的分析总结
整理的hql语句 id生成策略 集合传参,传参方式等 应有尽有
解析内容清晰简单,让你对hql语句半天就可以掌握!!
下面介绍HQL语句的语法 1.from子句 2.select子句 3.聚集函数 4.多态查询 5.where子句 6.表达式 7.order by子句 8.group by子句 9.子查询语句 10.fetch关键字 11.命名查询
HQL语句(结合实例).doc HQL语句(结合实例).doc HQL语句(结合实例).doc
HQL语句(结合实例)HQL语句(结合实例)HQL语句(结合实例)HQL语句(结合实例)HQL语句(结合实例)
汇集了hql语句中大部分常用的函数 ABS(n) 取绝对值数学函数 数学函数 JPAQL HQL ABS(column_name[数字类型对象属性])
hibernate hql语句 经典教程 实用 全面