(8)second(...)、minute(...)、hour(...)、day(...)、month(...) 和 year(...)
(9)EJB-QL 3.0 定義的任何功能或操做符:substring(), trim(), lower(), upper(), length(),locate(), abs(), sqrt(), bit_length(), mod()
(10)coalesce() 和 nullif()
(11)str() 把數字或者時間值轉換爲可讀的字符串
(12)cast(... as ...),其第二個參數是某 Hibernate 類型的名字,以及 extract(... from ...),只要 ANSI cast() 和 extract() 被底層數據庫支持
(13)HQL index() 函數,做用於 join 的有序集合的別名。
(14)HQL 函數,把集合做爲參數:size(), minelement(), maxelement(), minindex(), maxindex(),還有特別的 elements() 和 indices 函數,能夠與數量詞加以限定:some, all, exists, any, in。
(15)任何數據庫支持的 SQL 標量函數,好比 sign(), trunc(), rtrim(), sin()
(16)JDBC 風格的參數傳入 ?
(17)命名參數 :name,:start_date,:x1
(18)SQL 直接常量 'foo', 69, 6.66E+2, '1970-01-01 10:00:01.0'
(19)Java public static final 類型的常量 eg.Color.TABBY
group by 子句
1:對於返回彙集值的查詢,能夠按照任何屬性進行分組
2:可使用having子句
3:sql中的彙集函數,能夠出如今having子句中
4:group by 子句與 order by 子句中都不能包含算術表達式
5:不能group by 某個實體對象,必須明確的列出全部的彙集屬性
order by 子句
查詢返回的列表(list)能夠按照一個返回的類或組件(components)中的任何屬性進行排序,可選的 asc 或 desc 關鍵字指明瞭按照升序或降序進行排序。
子查詢
對於支持子查詢的數據庫,Hibernate 支持在查詢中使用子查詢。一個子查詢必須被圓括號包圍起來。
n鏈接(join)
1:Hibernate能夠在相關聯的實體間使用join,相似於sql,支持inner join、left outer join、right outer join、full join(全鏈接,並不經常使用)。
2:inner join能夠簡寫成join,left outer join 和right outer join在簡寫的時候能夠把outer去掉。
with
經過 HQL 的 with 關鍵字,你能夠提供額外的 join 條件。
如:from Cat as cat left join cat.kittens as kitten with kitten.bodyWeight > 10.0
fetch
能夠要求當即返回關聯的集合對象,如:
java代碼:
from Cat as cat
inner join fetch cat.mate
left join fetch cat.kittens
對於沒有關聯的實體,如何使用join呢?
對於沒有關聯的實體,想要使用join,能夠採用本地查詢的方式,使用sql來實現,好比:
s.createSQLQuery("select um.*,dm.* from tbl_user2 um left join tbl_dep dm on um.age=dm.uuid")
.addEntity("um",UserModel.class).addEntity("dm",DepModel.class);
1:新增
2:load、 get
3:修改
4:按條件查詢
(1)傳入條件值的方法:?或 :名稱,索引從0開始
(2)給參數賦值
(3)返回對象
(4)返回多個屬性,造成Object[]
(5)getByCondition的Hibernate版實現
5:刪除
6:分頁
Query q = sess.createQuery("from DomesticCat cat");
q.setFirstResult(20);
q.setMaxResults(10);
List cats = q.list();
也可使用你的數據庫的Native SQL語言來查詢數據。這對你在要使用數據庫的
某些特性的時候(好比說在查詢提示或者Oracle中的 CONNECT關鍵字),這是很是有
用的。這就可以掃清你把原來直接使用SQL/JDBC 的程序遷移到基於 Hibernate應用
的道路上的障礙。
使用SQLQuery
對原生SQL查詢執行的控制是經過SQLQuery接口進行的,經過執行
Session.createSQLQuery()獲取這個接口。下面來描述如何使用這個API進行查詢。
標量查詢(Scalar queries)
s.createSQLQuery(「select uuid,name from tbl_user」).list();
它將返回一個Object[]組成的List,Hibernate會使用ResultSetMetadata來斷定返回的標量值的實際順序和類型。你也可使用scalar來明確指明類型,如:
s.createSQLQuery("select * from tbl_user").addScalar("id", LongType.
INSTANCE)
id字段就明確是long型,固然你也能夠指定不少個字段的類型。
實體查詢(Entity queries)
上面的查詢都是返回標量值的,也就是從resultset中返回的「裸」數據。下面展現如何經過addEntity()讓原生查詢返回實體對象。
(1) s.createSQLQuery("select * from tbl_user").addEntity(UserModel.class);
(2) s.createSQLQuery(「select uuid,userId from tbl_user2」).addEntity (UserModel.class); //必定要把表的全部字段羅列出來
(3) s.createSQLQuery("select {um}.uuid as {um.uuid},{um}.name as {um.name} from tbl_user {um}").addEntity("um",UserModel.class);
功能跟第二個差很少,也要把表的全部字段都羅列出來
(4)簡單點的寫法:s.createSQLQuery("select * from tbl_user2 um")
.addEntity("um",UserModel.class);
(5)添加條件的示例:
s.createSQLQuery("select * from tbl_user where uuid=? and name like ?").addEntity(UserModel.class).setString(0, "3").setString(1,"%na%");
命名Sql查詢
能夠在映射文檔中定義查詢的名字,而後就能夠象調用一個命名的 HQL 查詢同樣直接調用命名 SQL查詢.在這種狀況下,咱們不 須要調用 addEntity() 方法。
在hbm.xml中配置,示例以下:
java代碼:
<sql-query name="users">
<return alias="um" class="cn.javass.h3.hello.UserModel"/>
select um.name as {um.name},
um.age as {um.age},
um.uuid as {um.uuid}
from tbl_user um
where um.name like :name
</sql-query>
注意:由於要返回一個對象,因此要把表的全部字段都羅列上,不然會報錯「列名無效」,實際上是在反射向對象賦值的時候,從sql的返回中得不到這個數據。
程序裏面調用示例:Query q = s.getNamedQuery(um.getClass().getName()
+".users").setString("name", "%n%");
命名Sql查詢--使用return-property
使用 <return-property> 你能夠明確的告訴 Hibernate 使用哪些字段別名,這取代了使用 {}-語法 來讓 Hibernate 注入它本身的別名。
在hbm.xml中配置,示例以下:
java代碼:
<sql-query name="users">
<return alias="um" class="cn.javass.h3.hello.UserModel">
<return-property name="name" column="umName"></return-property>
<return-property name="uuid" column="uuid"></return-property>
<return-property name="age" column="age"></return-property>
</return>
select um.name as umName,
um.age as age,
um.uuid as uuid
from tbl_user um
where um.name like :name
</sql-query>
具備一個直觀的、可擴展的條件查詢API是Hibernate的特點。
建立一個Criteria 實例
org.hibernate.Criteria接口表示特定持久類的一個查詢。Session是 Criteria實例的工廠。
java代碼:
Criteria crit = sess.createCriteria(Cat.class);
crit.setMaxResults(50);
List cats = crit.list();
限制結果集內容
一個單獨的查詢條件是org.hibernate.criterion.Criterion 接口的一個實例org.hibernate.criterion.Restrictions類 定義了得到某些內置Criterion類型的工廠方法。
java代碼:
List list = s.createCriteria(UserModel.class)
.add(Restrictions.eq("uuid", "3"))
.add(Restrictions.like("name", "%n%"))
.list();
約束能夠按照邏輯分組,示例以下:
List cats = sess.createCriteria(Cat.class)
.add( Restrictions.like("name", "Fritz%") )
.add( Restrictions.or(
Restrictions.eq( "age", new Integer(0) ),
Restrictions.isNull("age")
)
).list();
對結果集排序
可使用 org.hibernate.criterion.Order 來爲查詢結果排序。示例以下:
java代碼:
List cats = sess.createCriteria(Cat.class)
.add( Restrictions.like("name", "F%")
.addOrder( Order.asc("name") )
.addOrder( Order.desc("age") )
.setMaxResults(50)
.list();
1:假若有以下程序,須要向數據庫裏面加如100000條數據:
java代碼:
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
for ( int i=0; i<100000; i++ ) {
Customer customer = new Customer(.....);
session.save(customer);
}
tx.commit();
session.close();
這個程序很顯然不能正常運行,會拋出內存溢出的例外。按照前面講過的原理,Hibernate的save方法是先把數據放到內存裏面,數據太多,致使內存溢出。
那麼該如何解決呢?
解決方案:
1:首先將 hibernate.jdbc.batch_size的批量抓取數量參數設置到一個合適值(好比,10 - 50 之間),同時最好關閉二級緩存,若是有的話。
2:批量插入,一個可行的方案以下:
java代碼:
for ( int i=0; i<100000; i++ ) {
Customer customer = new Customer(.....);
session.save(customer);
if ( i % 20 == 0 ) {
//將本批數據插入數據庫,並釋放內存
session.flush();
session.clear();
}
}
批量更新的作法跟這個相似
1:默認的Hibernate是有緩存的,稱之爲一級緩存。
2:也可使用StatelessSession,來表示不實現一級緩存,也不和二級緩存和查詢緩存交互
3:StatelessSession是低層的抽象,和底層JDBC至關接近
java代碼:
StatelessSession session = sessionFactory.openStatelessSession();
Transaction tx = session.beginTransaction();
ScrollableResults customers = session.getNamedQuery("GetCustomers") .scroll(ScrollMode.FORWARD_ONLY);
while ( customers.next() ) {
Customer customer = (Customer) customers.get(0);
customer.updateStuff(...);
session.update(customer);
} tx.commit(); session.close();