hibernate取得一條隨機記錄

項目中要求隨機取得user表的一條記錄。用到hibernate,底層數據庫是mysql.

1.首先會想到一種方式:取出數據庫中所有的記錄,你懂的。一個List,然後list.get(new Random().nextInt(list.size));但顯然查詢了所有的記錄,如果表特別大,效率可想而知。

2. 可行的方式,應該是得到一個隨機的主鍵,然後load.原生sql實現的方式是:select * from user order by rand() limit   1;插一句,很奇怪,有人說這種方式會慢慢的;還有朋友說這種方式rand()有可能返回null.我沒有深入瞭解數據庫的實現,但是我想:數據庫對於每 插入的一條記錄,生成一個index是多麼正常。就像這樣。


那麼數據庫感知到index有存在是多麼正常,既然index本身就像一個數組索引,那麼得到一條隨機記錄是多麼正常,數據庫對於暴露得到一條隨機記錄又是多麼正常。那麼對於mysql來說,提供rand()是多麼正常。那rand()爲什麼會返回null.這個API理應由數據庫來做,那麼效率低又何以見得。。。

 

3.hql居然不支持rand()。createCriteria不太會啊。

 

4.萬般無奈,我在dao.impl層寫了個方法,調用createSQLQuery。我愚笨,就像這樣

(User)getHibernateTemplate().execute(
                    new HibernateCallback() {

 居然會報cast Exception,到底返回什麼呢,我不知道。又試着強制轉換爲ResultSet,也是一樣的錯誤。

 

5.幸好的generator id方式比較有規律,是auto_increment的。解決方式是這樣的。如下

public User loadRandomUser() throws Exception {
		int count = countAll("User");
		User user = null;
		while (user == null) {
			int rand = new Random().nextInt(count);
			final String hql = "from User where privilege=1 and uid = " + rand;
			user = (User) getHibernateTemplate().execute(
					new HibernateCallback() {
						public Object doInHibernate(Session session)
								throws HibernateException {
							Query query = session.createQuery(hql);
							query.setMaxResults(1);
							return query.uniqueResult();
						}
					});
		}
		return user;
	}

  首先取得記錄的總數。隨機得一個uid,然後load。隨機取記錄,由java來做的,效率肯定比rand()低。

 

求解。。。

 

另外:我發現iteye的網站界面難看,編輯頁設計也太差了。坑爹的提問積分制度。分數低了,沒人願意回答你。

 

 

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章