2024年5月11日发(作者:)
hibernate随机排序有关问题
hibernate随机排序问题
大家都知道不少数据库都支持随机排序,例如MySQL 用order by rand(),oracle用order by
newid()等等,在hibernate中,用什么来实现随机排序啊,比如是对用户库进行随机抽奖的
应用
------解决方案--------------------------------------------------------
这个是数据库支持的。HQL应该没有这个功能,没有那么完善。
既然MySQL,Oracle都支持了你就在SQL里用呗。
如果有数据库不支持,可以在查询的时候给每一条数据生成一个随机数列,然后order by 这
个随机数列就可以了。
例如sqlserver里有rand()函数(各个数据库应该都这种生成随机数的函数) 就可以达到这
种效果,
当然sqlserver有 newid()可以直接完成此功能,此处举个例子。
------解决方案--------------------------------------------------------
Java code
List datas = Query("from ClassName c where ... order by ... ").list()
//让List里面的元素随机排列
e(datas);
------解决方案--------------------------------------------------------
hibernate中实现随机排序的功能很简单,比如hql,可以这么写
rentSession().createQuery("from User u order by newid()").list();
------解决方案--------------------------------------------------------
你要在Hibernate实现这种功能的话,还可以这样搞
Java code
List datas = SQLQuery("select * from tb where ... order by rand()").list()
关于随机抽取order By Rand()的效率问题,和改进写法!
最近由于需要大概研究了一下MYSQL的随机抽取实现方法。
举个例子,要从tablename表中随机提取一条记录,大家一般的写法就是
SELECT * FROM tablename ORDER BY RAND() LIMIT 1
但是,后来我查了一下MYSQL的官方手册,里面针对RAND()有如下提示:
You can't use a column with RAND() values in an ORDER BY clause, because
ORDER BY would evaluate the column multiple times. In MySQL Version 3.23,
you can, however, do: SELECT * FROM table_name ORDER BY RAND()
大概意思就是,在ORDER BY从句里面不能使用RAND()函数,因为这样会导致数据列
被多次扫描。但是在MYSQL 3.23版本中,仍然可以通过ORDER BY RAND()来实现
随机。
然后我试了一下可行性,ORDER BY RAND()在我自己的4.0版本上可以执行,但是在
公司的3.x(具体忘了)上不能执行,看来好像和官方手册上有点不同。
后来在网上找了一些资料了解到,
SELECT * FROM tablename ORDER BY RAND() LIMIT 1
会扫描整个表,然后再随机返回一个记录。对于比较小的表,通常不大于30万行记录的表,
这种写法很实用。但是如果一旦记录大于了30万行,这个处理过程就会变得非常缓慢!!!
所以,结论是,我建议,能够不用ORDER BY RAND() 就不用!因为一来可以避免今后
表数据量增大后引起的效率低下;二来可以避免某些版本的MYSQL不支持这种写法。
最后给出一种比较实用的替代方法的主要思想:
假设id是主键
首先:SELECT MIN(id), MAX(id) FROM tablename
然后:$id=rand($min,$max); //通过rand返回刚才取到的最大id和最小id之间的一
个id号。
最后:SELECT * FROM tablename WHERE id='$id' LIMIT 1
如果是用auto increment产生的id号,也许会出现某个id列曾经删除过,造成了最大和
最小id之间的不连续,在这里可以先判断一下随机生成的这个id号是否存在。
有人肯定会问:如果不是随机检索一条,而是要随机检索多条,比如10条该怎么办???
最简单的就是随便取个连续的范围,比如
SELECT * FROM tablename WHERE id > '$id' LIMIT 10
但这种方法的随机是连续的.
然后还有比如生成一个WHERE id = '{$id['1']}' OR id = '{$id['2']}' OR .....的从句,
写起来会稍微多几句,$id的值随机生成数。
但这种方法如果从句多了话,比如上百条?那样SQL语句会比较大,也会影响效率。
还有,先按照第一种随机选择一个范围,比如
SELECT id FROM tablename WHERE id > '$id' LIMIT 50
然后再在在结果中随机选择10个
还有,每次随机取一个,取10次。
发布评论