Hibernate中有HQL查詢語法。但我們用得比較熟的還是數SQL語句,那麼應該怎麼來讓Hibernate支持SQL呢?這個不用我們去考慮了,Hibernate團隊已經早就做好了。
廢話不說,直接來例子啦。
select * from t_user usr
上面是一條SQL語句,又是廢話,是個人都知道。我們想讓Hibernate執行這條語句,怎麼辦呢?看代碼:
Query query = session.createSQLQuery("select * from t_user usr");就這樣,剩下來的,大家應該都知道了,平常的查詢。
那查詢完之後,返回的是什麼東西呢?
while(iter.hasNext()){ Object[] objs = (Object[])iter.next(); for (int i = 0; i < objs.length; i++) { System.out.print(objs[i]); } System.out.println(); }返回的每個結果都是Object[]數組,
這時又有人跑出來說面向對象啦。對,就是面向對象,唉,沒辦法。
我們繼續看:
select {usr.*} from t_user usr看到這裡,估計某些童鞋開始雞動啦,那個大括號什麼東西啦?
別急,慢慢來。我們先繼續看代碼。
複製代碼代碼如下:
Query query = session.createSQLQuery("select {usr.*} from t_user usr").addEntity(TUser.class);
addEntitySQLQuery addEntity(String tableAlias, Class entityType)Declare a "root" entityParameters:tableAlias - The SQL table aliasentityType - The java type of the entity to add as a root
有跟沒一個樣,杯具。只能自己動手用用。
第一個參數是指表的別名,就像上面的語句,我們表的別名是usr,所以第一個參數為usr,而第二個是指查詢到的結果需要映射到哪個類,這裡由於我們在映射文件中是通過TUser映射到t_user表,所以我們這里當然也就是TUser啦。然後一查,有SQL語句出來,而且查到的結果是TUser類型的。
我們查到的結果是:
org.hibernate.tutorial.domain6.TUser@198cb3d
當然,你們的肯定跟我不一樣的。不要雞動。
也許我們並不需要全部進行查出,這時,我們需要的只是設定別名即可:
select u.id as {usr.id},u.name as {usr.name},u.age as {usr.age} from t_user u我們看到我們用了as指定了字段的別名,程序中還是一樣:
複製代碼代碼如下:
Query query = session.createSQLQuery("select u.id as {usr.id},u.name as {usr.name},u.age as {usr.age} from t_user u").addEntity("usr",TUser.class);
<sql-query name="queryTUser"> <return alias="usr" entity-name="org.hibernate.tutorial.domain6.TUser" /> select {usr.*} from t_user usr where name=:name </sql-query>注意,這裡的entity-name需要寫完整的包名,不然會報錯的。這裡我們有子標籤return,它指定了表的別名和類名,這樣我們在運行時就不需要再addEntity了。
看代碼:
Query query = session.getNamedQuery("queryTUser"); query.setParameter("name","shun"); List list = query.list(); Iterator iter = list.iterator();
我們直接這樣就OK了,注意,我們並沒有加addEntity了,主要還是歸功於配置文件中的配置。
注意,如果在配置文件中配置,一定要有return子標籤指定表別名和類名。這個主要是避免了我們讀取語句時的重複判斷。
上面講了這麼久,我們一直在講有別名的表,那麼如果我們的表沒有別名,但又想返回的結果封裝在對象內,我們應該怎樣呢?
select * from t_user usr
很簡單,只要調用addEntity的重載方法addEntity(Class clazz)就行了,只需要提供一個類名,而不需要表別名。
當然,hibernate也支持存儲過程,只需要在配置文件中把sql-query的callable屬性設為true即表示當前調用的是存儲過程,由於存儲過程我接觸地不多,以後多研究一下再跟大家一起研究。
我們在調用session.save等相應的對數據操作的方法時,它會轉換成hibernate內置的SQL語句,但如果我們想自己控制SQL語句的格式呢,怎麼辦?
Hibernate實際上也想到了。
我們直接在映射文件中加入:
<sql-insert> INSERT INTO T_USER (NAME,AGE) values (?,?) </sql-insert> <sql-update> UPDATE USER SET USER_NAME=?,AGE=? WHERE uSER_ID=? </sql-update>
注意,這個需要添加在class標籤內,作為子標籤。我們這裡全部是大寫字母,是為了跟hibernate默認的語句分清,沒有其他意思。
我們先來看一下insert的調用:
User user = new User(); user.setName("shun123123"); user.setAge(23);當我們調用保存時,hibernate的語句是:
Hibernate:
INSERT INTO USER(USER_NAME,AGE) values(?,?)
它調用了我們配置的sql-insert標籤內的語句我們再來看一下update的調用:
User user = (User)session.get(User.class,new Long(29)); user.setName("shun123123"); user.setAge(23); session.save(user);我們調用保存,它會自動調用更新,此時的語句是:
Hibernate:
UPDATE USER SET USER_NAME=?,AGE=? WHERE uSER_ID=?我們看到輸出的語句是大寫的,也就是調用了我們配置的語句。