【Hibernate】getHibernateTemplate.find()和session.createQuery()方法总结
Spring中常用的hql查詢方法(getHibernateTemplate().find())
一、find(String queryString);
示例:this.getHibernateTemplate().find("from bean.User"); 返回所有User對象二、find(String queryString , Object value);
示例:this.getHibernateTemplate().find("from bean.User u where u.name=?", "test"); 或模糊查詢:this.getHibernateTemplate().find("from bean.User u where u.name like ?", "%test%"); 返回name屬性值為test的對象(模糊查詢,返回name屬性值包含test的對象)三、find(String queryString, Object[] values);
示例:String hql= "from bean.User u where u.name=? and u.password=?" this.getHibernateTemplate().find(hql, new String[]{"test", "123"}); 返回用戶名為test并且密碼為123的所有User對象 u.setName("bb"); list=this.getHibernateTemplate().findByExample(u,start,max); 返回:用戶名為bb密碼為123的對象---------------------------------
四、findByExample(Object exampleEntity)
示例: User u=new User(); u.setPassword("123");//必須 符合的條件但是這兩個條件時并列的(象當于sql中的and) u.setName("bb"); list=this.getHibernateTemplate().findByExample(u,start,max); 返回:用戶名為bb密碼為123的對象五、findByExample(Object exampleEntity, int firstResult, int maxResults)
示例: User u=new User(); u.setPassword("123");//必須 符合的條件但是這兩個條件時并列的(象當于sql中的and) u.setName("bb"); list=this.getHibernateTemplate().findByExample(u,start,max); 返回:滿足用戶名為bb密碼為123,自start起共max個User對象。(對象從0開始計數)六、findByNamedParam(String queryString , String paramName , Object value)
使用以下語句查詢:
String queryString = "select count(*) from bean.User u where u.name=:myName"; String paramName= "myName"; String value= "xiyue"; this.getHibernateTemplate().findByNamedParam(queryString, paramName, value); System.out.println(list.get(0)); 返回name為xiyue的User對象的條數七、findByNamedParam(String queryString , String[] paramName , Object[] value)
示例: String queryString = "select count(*) from bean.User u where u.name=:myName and u.password=:myPassword"; String[] paramName= new String[]{"myName", "myPassword"}; String[] value= new String[]{"xiyue", "123"}; this.getHibernateTemplate().findByNamedParam(queryString, paramName, value); 返回用戶名為xiyue密碼為123的User對象八、findByNamedQuery(String queryName)
示例: 1、首先需要在User.hbm.xml中定義命名查詢 <hibernate-mapping> <class>......</class> <query name="queryAllUser"><!--此查詢被調用的名字--> <![CDATA[ from bean.User ]]> </query> </hibernate-mapping> 2、如下使用查詢: this.getHibernateTemplate().findByNamedQuery("queryAllUser");九、findByNamedQuery(String queryName, Object value)
示例: 1、首先需要在User.hbm.xml中定義命名查詢 <hibernate-mapping> <class>......</class> <query name="queryByName"><!--此查詢被調用的名字--> <![CDATA[ from bean.User u where u.name = ? ]]> </query> </hibernate-mapping> 2、如下使用查詢: this.getHibernateTemplate().findByNamedQuery("queryByName", "test");十、findByNamedQuery(String queryName, Object[] value)
示例: 1、首先需要在User.hbm.xml中定義命名查詢 <hibernate-mapping> <class>......</class> <query name="queryByNameAndPassword"><!--此查詢被調用的名字--> <![CDATA[ from bean.User u where u.name =? and u.password =? ]]> </query> </hibernate-mapping> 2、如下使用查詢: String[] values= new String[]{"test", "123"}; this.getHibernateTemplate().findByNamedQuery("queryByNameAndPassword" , values);十一、findByNamedQueryAndNamedParam(String queryName, String paramName, Object value)
示例:
1、首先需要在User.hbm.xml中定義命名查詢 <hibernate-mapping> <class>......</class> <query name="queryByName"><!--此查詢被調用的名字--> <![CDATA[ from bean.User u where u.name =:myName ]]> </query> </hibernate-mapping> 2、如下使用查詢: this.getHibernateTemplate().findByNamedQuery("queryByName" , "myName", "test");十二、findByNamedQueryAndNamedParam(String queryName, String[] paramName, Object[] value)
示例:
1、首先需要在User.hbm.xml中定義命名查詢 <hibernate-mapping> <class>......</class> <query name="queryByNameAndPassword"><!--此查詢被調用的名字--> <![CDATA[ from bean.User u where u.name =:myName and u.password=:myPassword ]]> </query> </hibernate-mapping> 2、如下使用查詢: String[] names= new String[]{"myName", "myPassword"}; String[] values= new String[]{"test", "123"}; this.getHibernateTemplate().findByNamedQuery("queryByNameAndPassword" , names, values);十三、findByValueBean(String queryString , Object value);
示例:
1、定義一個ValueBean,屬性名必須和HSQL語句中的:后面的變量名同名,此處必須至少有兩個屬性,分別為myName和myPassword,使用setter方法設置屬性值后 ValueBean valueBean= new ValueBean(); valueBean.setMyName("test"); valueBean.setMyPasswrod("123"); 2、 String queryString= "from bean.User u where u.name=:myName and u.password=:myPassword"; this.getHibernateTemplate().findByValueBean(queryString , valueBean);十四、findByNamedQueryAndValueBean(String queryName , Object value);
示例:
1、首先需要在User.hbm.xml中定義命名查詢 <hibernate-mapping> <class>......</class> <query name="queryByNameAndPassword"><!--此查詢被調用的名字--> <![CDATA[ from bean.User u where u.name =:myName and u.password=:myPassword ]]> </query> </hibernate-mapping> 2、定義一個ValueBean,屬性名必須和User.hbm.xml命名查詢語句中的:后面的變量名同名,此處必須至少有兩個屬性,分別為myName和myPassword,使用setter方法設置屬性值后 ValueBean valueBean= new ValueBean(); valueBean.setMyName("test"); valueBean.setMyPasswrod("123"); 3、 String queryString= "from bean.User u where u.name=:myName and u.password=:myPassword"; this.getHibernateTemplate().findByNamedQueryAndValueBean("queryByNameAndPassword", valueBean);session的createQuery()方法總結
使用SQLQuery對原生SQL查詢執行的控制是通過SQLQuery接口進行的,通過執行Session.createSQLQuery()獲取這個接口。最簡單的情況下,我們可以采用以下形式:
List cats = sess.createSQLQuery( " select * from cats " ).addEntity(Cat. class ).list();這個查詢指定了:SQL查詢字符串 和查詢返回的實體
這里,結果集字段名被假設為與映射文件中指明的字段名相同。對于連接了多個表的查詢,這就可能造成問題,因為可能在多個表中出現同樣名字的字段。下面的方法就可以避免字段名重復的問題:
List cats = sess.createSQLQuery( " select {cat.*} from cats cat " ).addEntity( " cat " , Cat. class ).list();這個查詢指定了:
SQL查詢語句,它帶一個占位符,可以讓Hibernate使用字段的別名.
查詢返回的實體,和它的SQL表的別名.
addEntity()方法將SQL表的別名和實體類聯系起來,并且確定查詢結果集的形態。
addJoin()方法可以被用于載入其他的實體和集合的關聯.
List cats = sess.createSQLQuery(" select {cat.*}, {kitten.*} from cats cat, cats kitten where kitten.mother = cat.id " ) .addEntity( " cat " , Cat. class ).addJoin( " kitten " , " cat.kittens " ) .list();原生的SQL查詢可能返回一個簡單的標量值或者一個標量和實體的結合體。
Double max = (Double) sess.createSQLQuery( " select max(cat.weight) as maxWeight from cats cat " ) .addScalar( " maxWeight " , Hibernate.DOUBLE).uniqueResult();除此之外,你還可以在你的hbm文件中描述結果集映射信息,在查詢中使用。
List cats = sess.createSQLQuery(" select {cat.*}, {kitten.*} from cats cat, cats kitten where kitten.mother = cat.id " ) .setResultSetMapping( " catAndKitten " ).list();命名SQL查詢可以在映射文檔中定義查詢的名字,然后就可以象調用一個命名的HQL查詢一樣直接調用命名SQL查詢.在這種情況下,我們不 需要調用addEntity()方法.
< sql - query name = " persons " > < return alias = " person " class = " eg.Person " /> Select person.NAME AS {person.name},person.AGE AS {person.age},person.SEX AS {person.sex} FROM PERSON person Where person.NAME LIKE :namePattern </ sql - query >List people = sess.getNamedQuery( " persons " ).setString( " namePattern " , namePattern).setMaxResults( 50 ).list();原來的查詢語句:
String sql = "select a.* from tb_doc_catalog a where a.cat_code like '"+catCode+"%'"; Session session = this.getSession(); try {List catNameList = session.createSQLQuery(sql).list();return catNameList ; } finally {releaseSession(session); //釋放session }分析:原來是查詢出來的字段并不能自動轉換為bean對象。
解決思路一(采用hql查詢):
String sql = "select a from DocCatalogInfo a where a.catCode like '"+catCode+"%'"; List catNameList =getHibernateTemplate().find(sql); return catNameList ;測試一下發現沒問題,看來還是因為用原生sql查詢的原因,網上搜一下:createsqlQuery返回對象,看到一篇文章才覺悟到:
解決思路二(采用原生sql查詢):
String sql = "select a.* from tb_doc_catalog a where a.cat_code like '"+catCode+"%'"; Session session = this.getSession(); try {List catNameList = session.createSQLQuery(sql).addEntity(DocCatalogInfo.class).list();return catNameList ; } finally {releaseSession(session); //釋放session }下面我們來總結一下hibernate 中createQuery與createSQLQuery兩者區別:
1、前者用的hql語句進行查詢,后者可以用sql語句查詢。
2、前者以hibernate生成的Bean為對象裝入list返回,后者則是以對象數組進行存儲。
所以使用createSQLQuery有時候也想以hibernate生成的Bean為對象裝入list返回,就不是很方便。
突然發現createSQLQuery有這樣一個方法可以直接轉換對象:
XXXXXXX 代表以hibernate生成的Bean的對象,也就是數據表映射出的Bean。
以后多注意,還是時不時的要看看hibernate各個對象方法的使用。
還有另外一個相關的小細節應注意:
比如有這樣一個po
PO: User.class
properties: userId,userName
DDL: create table tuser (userid varchar(10),username varchar(20));
當執行:session.createQuery(“from User u”).list()時生成的SQL:select userid,username from tuser;
當執行:session.createQuery(“from User u”).iterator()時生成的SQL:select userid from tuser;
可以看出list()一次將數據從數據庫中讀出直接填充到List中,iterator()將數據的主鍵從數據庫中讀出,當循環這個Iterator時才添加執行:
select userid,username from user where userid=?;把數據讀出。
在不同的應用范圍使用不同的方法,具體在hibernate應用中應當注意。
用法一(返回數值):
ISQLQuery query = session.CreateSQLQuery("SELECT COUNT(Id) AS C FROM Cake").AddScalar("C", NHibernateUtil.Int32); int c = Convert.ToInt32(query.UniqueResult()); 或int c = query.UniqueResult<int>;//使用此方法發現sql執行了兩次,故不推薦使用。用法二(返回對象實體):
ISQLQuery query = session.CreateSQLQuery("select * from cake c").AddEntity("CAKE.DataTransfer.Entities.Cake"); 或ISQLQuery query = session.CreateSQLQuery("select * from cake c").AddEntity("c", "CAKE.DataTransfer.Entities.Cake"); 或ISQLQuery query = session.CreateSQLQuery("select * from cake c").AddEntity(typeof(Cake)); 或ISQLQuery query = session.CreateSQLQuery("select * from cake c").AddEntity("c", typeof(Cake)); 或ISQLQuery query = session.CreateSQLQuery("select * from cake c").AddEntity("c", typeof(Cake), LockMode.Write);IList<Cake> c = query.List<Cake>();用法三(連表查詢):
ISQLQuery query = session.CreateSQLQuery("select cs.* from cake c join CakeSize cs on cs.CakeId=c.Id").AddEntity("cs", typeof(CakeSize)); IList<CakeSize> cs = query.List<CakeSize>();以上是一種常見的用法,通過該例子,相信大家心里也已經有個數了,也應該知道怎么操作這個sql了:
但是過程中難免會遇到些問題,比如:
實例二(問題說明):
我需要執行例如這條sql語句:
select CreateTime,Address,Password, (case when EmailType = 0 then 'Gmail' when EmailType = 1 then 'Yahoo' when EmailType = 2 then 'Hotmail' else 'Other' end) as EmailType from MailInfo錯誤:undefined alias or unknown mapping
ISession session = DAORepository.Instrance.DbSession; string queryString = "select CreateTime,Address,Password, (case when EmailType = 0 then 'Gmail' when EmailType = 1 then 'Yahoo' when EmailType = 2 then 'Hotmail' else 'Other' end) as EmailType from MailInfo where status=0 Order by CreateTime desc"; IQuery query = session.CreateQuery(queryString; IList lst = query.List();錯誤:Return types of SQL query were not specified…
ISession session = DAORepository.Instrance.DbSession; string queryString = "select CreateTime,Address,Password, (case when EmailType = 0 then 'Gmail' when EmailType = 1 then 'Yahoo' when EmailType = 2 then 'Hotmail' else 'Other' end) as EmailType from MailInfo where status=0 Order by CreateTime desc"; ISQLQuery query = session.CreateSQLQuery(queryString); IList lst = query.List();錯誤:could not execute query…
ISession session = DAORepository.Instrance.DbSession; string queryString = "select CreateTime,Address,Password, (case when EmailType = 0 then 'Gmail' when EmailType = 1 then 'Yahoo' when EmailType = 2 then 'Hotmail' else 'Other' end) as EmailType from MailInfo where status=0 Order by CreateTime desc"; ISQLQuery query = session.CreateSQLQuery(queryString).AddScalar("CreateTime",NHibernateUtil.String) .AddScalar("Address",NHibernateUtil.String) .AddScalar("Password",NHibernateUtil.String) .AddScalar("EmailType",NHibernateUtil.Int32); IList lst = query.List(); ISession session = DAORepository.Instrance.DbSession; string queryString = "select CreateTime,Address,Password, (case when EmailType = 0 then 'Gmail' when EmailType = 1 then 'Yahoo' when EmailType = 2 then 'Hotmail' else 'Other' end) as EmailType from MailInfo where status=0 Order by CreateTime desc"; ISQLQuery query = session.CreateSQLQuery(queryString) .AddScalar("CreateTime",NHibernateUtil.String) .AddScalar("Address",NHibernateUtil.String) .AddScalar("Password",NHibernateUtil.String) .AddScalar("EmailType",NHibernateUtil.Int32); IList lst = query.List();注意:EmailType字段對應數據庫的類型是int,這里我就誤解為也應該映射為NHibernateUtil.Int32;
把AddScalar方法的參數里一個屬性改了一下:
ISession session = DAORepository.Instrance.DbSession; string queryString = "select CreateTime,Address,Password, (case when EmailType = 0 then 'Gmail' when EmailType = 1 then 'Yahoo' when EmailType = 2 then 'Hotmail' else 'Other' end) as EmailType from MailInfo where status=0 Order by CreateTime desc"; ISQLQuery query = session.CreateSQLQuery(queryString).AddScalar("CreateTime",NHibernateUtil.String) .AddScalar("Address",NHibernateUtil.String) .AddScalar("Password",NHibernateUtil.String) .AddScalar("EmailType",NHibernateUtil.String); IList lst = query.List(); ISession session = DAORepository.Instrance.DbSession; string queryString = "select CreateTime,Address,Password, (case when EmailType = 0 then 'Gmail' when EmailType = 1 then 'Yahoo' when EmailType = 2 then 'Hotmail' else 'Other' end) as EmailType from MailInfo where status=0 Order by CreateTime desc"; ISQLQuery query = session.CreateSQLQuery(queryString) .AddScalar("CreateTime",NHibernateUtil.String) .AddScalar("Address",NHibernateUtil.String) .AddScalar("Password",NHibernateUtil.String) .AddScalar("EmailType",NHibernateUtil.String); IList lst = query.List();推薦一個hibernate源碼在線查看網站:
http://www.boyunjian.com/javasrc/org.hibernate/hibernate-core/
總結
以上是生活随笔為你收集整理的【Hibernate】getHibernateTemplate.find()和session.createQuery()方法总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Hibernate】Hibernate
- 下一篇: 【大话Hibernate】Hiberna