標籤:finally 設定 程式 public user source 函數 dmi 1.0
感謝網友!
轉自:http://blog.sina.com.cn/s/blog_7ffb8dd501014a6o.html
Hibernate總的來說共有三種查詢方式:HQL、QBC和SQL三種。但是細分可以有如下幾種:
一、HQL查詢方式
這一種我最常用,也是最喜歡用的,因為它寫起來靈活直觀,而且與所熟悉的SQL的文法差不太多。條件查詢、分頁查詢、串連查詢、巢狀查詢,寫起來與SQL文法基本一致,唯一不同的就是把表名換成了類或者對象。其它的,包括一些查詢函數(count(),sum()等)、查詢條件的設定等,全都跟SQL文法一樣。
###注意:
在hql中關鍵字不區分大小寫,但是屬性和類名區分大小寫
樣本1:
static void query(String name){
Session s=null;
try{
s=HibernateUtil.getSession();
//from後面是對象,不是表名
String hql="from Admin as admin where admin.aname=:name";//使用具名引數,推薦使用,易讀。
Query query=s.createQuery(hql);
query.setString("name", name);
List<Admin> list=query.list();
for(Admin admin:list){
System.out.println(admin.getAname());
}
}finally{
if(s!=null)
s.close();
}
}
######!!!!!!!!!!!!!對於多對一關聯性查詢:
String hql = "from Student where Class.className = ‘二班‘";
(Student實體類中含有Class對象的引用。這樣相當於兩張表的聯集查詢)
樣本2(分頁查詢):
Query query = session.createQuery("from Customer c
order by c.name asc");
query.setFirstResult(0);
query.setMaxResults(10);
List result = query.list();
說明:
–setFirstResult(int firstResult):設定從哪一個對 象開始檢索,參數firstResult表示這個對象在查詢結果中的索引位置,索引位置的起始值為0。預設情況下,Query和Criteria介面從查 詢結果中的第一個對象,也就是索引位置為0的對象開始檢索。
–setMaxResult(int maxResults):設定一次最多檢索出的對象數目。預設情況下,Query和Criteria介面檢索出查詢結果中所有的對象。
適用情況:常用方法,比較傳統,類似jdbc。缺點:新的查詢語言,適用面有限,僅適用於Hibernate架構。
二、QBC(Query By Criteria) 查詢方式
這種方式比較物件導向方式,重點是有三個描述條件的對象:Restrictions,Order,Projections。使用QBC查詢,一般需要以下三個步驟:
1、 使用Session執行個體 的createCriteria()方法建立Criteria對象
2、使用工具類Restrictions的方法為Criteria對象設定查詢條件,Order工具類的方法設定排序方式,Projections工具類的方法進行統計和分組。
3、 使用Criteria對象的list()方法進行查詢並返回結果
Restrictions類的常用方法:
Restrictions類的常用方法:
| 方法名稱 |
描述 |
| Restrictions.eq |
等於 |
| Restrictions.allEq |
使用Map,Key/Valu進行多個等於的比對 |
| Restrictions.gt |
大於 |
| Restrictions.ge |
大於等於 |
| Restrictions.lt |
小於 |
| Restrictions.le |
小於等於 |
| Restrictions.between |
對應SQL的between |
| Restrictions.like |
對應SQL的like |
| Restrictions.in |
對應SQL的in |
| Restrictions.and |
and關係 |
| Restrictions.or |
or關係 |
| Restrictions.sqlRestriction |
SQL限定查詢 |
Order類的常用方法:
| 方法名稱 |
描述 |
| Order.asc |
升序 |
| Order.desc |
降序 |
Projections類的常用方法
| 方法名稱 |
描述 |
| Projections.avg |
求平均值 |
| Projections.count |
統計某屬性的數量 |
| Projections.countDistinct |
統計某屬性不同值的數量 |
| Projections.groupProperty |
指定某個屬性為分組屬性 |
| Projections.max |
求最大值 |
| Projections.min |
求最小值 |
| Projections.projectionList |
建立一個ProjectionList對象 |
| Projections.rowCount |
查詢結果集中的記錄條數 |
| Projections.sum |
求某屬性的合計 |
樣本:static void cri(String name,String password){
Session s=null;
try{
s=HibernateUtil.getSession();
Criteria c=s.createCriteria(Admin.class);
c.add(Restrictions.eq("aname",name));//eq是等於,gt是大於,lt是小於,or是或
c.add(Restrictions.eq("apassword", password));
List<Admin> list=c.list();
for(Admin admin:list){
System.out.println(admin.getAname());
}
}finally{
if(s!=null)
s.close();
}
}
樣本2(分頁查詢):
Criteria criteria = session.createCriteria(Customer.class);
criteria.addOrder( Order.asc("name") ); //排序方式
criteria.setFirstResult(0);
criteria.setMaxResults(10);
List result = criteria.list()
適用情況:物件導向操作,革新了以前的資料庫操作方式,易讀。缺點:適用面較HQL有限。
三、QBE(Query By Example)例子查詢方式
將一個對象的非空屬性作為查詢條件進行查詢。
樣本:Session session = SessionFactory.getCurrentSession();
User user = new User();
user.setName("ijse");
Transaction ts = session.beginTransaction();
try {
Criteria criteria = session.createCriteria(User.class);
criteria.add(Example.create(user));
user= (User) criteria.list().get(0);
session.commit();
} catch (HibernateException ex) {
ts.rollBack();
ex.printStackTrace();
}
System.out.println(user.getName());
適用情況:物件導向操作。 缺點:適用面較HQL有限,不推薦。
四、DetachedCriteria:離線條件查詢
離線查詢就是建立一個DetachedCriteria對象,將查詢的條件等指定好,然後在session.beginTransaction()後將這個對象傳入。通常這個對象可以在展示層建立,然後傳入業務層進行查詢。
1、建立DetachedCriteria對象
DetachedCriteria dc = DetachedCriteria.forClass(User.class);
int id = 1;
if (id != 0)
dc.add(Restrictions.eq("id", id));
Date age = new Date();
if (age != null)
dc.add(Restrictions.le("birthday", age));
List users = dc(dc);//執行查詢
System.out.println("離線查詢返回結果:" + users);
2、執行查詢
static List dc(DetachedCriteria dc) {
Session s = HibernateUtil.getSession();
Criteria c = dc.getExecutableCriteria(s);
List rs = c.list();
s.close();
return rs;
}
適用情況:物件導向操作,分離業務與底層,不需要欄位屬性攝入到Dao實現層。 缺點:適用面較HQL有限。
五、命名查詢
1、在資料對應元檔案中進行配置如下:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="com.sy.vo.User" table="user" catalog="news">
....
</class>
<!-- 命名查詢:定義查詢條件 -->
<query name="getUserById">
<![CDATA[from User where id=:id]]>
</query>
<!-- 命名查詢中使用sql,不推薦使用,影響跨資料庫
<sql-query name="getUserById2">
<![CDATA[select * from User where ]]>
</sql-query> -->
</hibernate-mapping>
2、在java代碼中寫入:
static List namedQuery(int id) {
Session s = HibernateUtil.getSession();
Query q = s.getNamedQuery("getUserById");
q.setInteger("id", id);
return q.list();
}
適用情況:萬能方法,有點像ibatis輕量級架構的操作,方便維護。 缺點:不物件導向。基於hql和sql,有一定缺陷。
六、SQL查詢
樣本:
static List sql() {
Session s = HibernateUtil.getSession();
Query q = s.createSQLQuery("select * from user").addEntity(User.class);
List<User> rs = q.list();
s.close();
return rs;
}
適用情況:不熟悉HQL的朋友,又不打算轉資料庫平台的朋友,萬能方法 缺點:破壞跨平台,不易維護,不物件導向。
七、OID查詢方式
按照對象的OID來檢索對象。Session的get()和load()方法提供了這種功能。如果在應用程式中事Crowdsourced Security Testing道了OID,就可以使用這種檢索對象的方式。
八、Query.iterator的N+1查詢(基於一的HQL,多見於一對多、多對多的關聯映射)
N + 1問題,在預設情況下,使用query.iterate查詢,有可以能出現N+1問題
所謂的N+1是在查詢的時候發出了N+1條sql語句
1: 首先發出一條查詢對象id列表的sql
N: 根據id列表到緩衝中查詢,如果緩衝中不存在與之匹配的資料,那麼會根據id發出相應的sql語句
* list和iterate的區別?
* list每次都會發出sql語句,list會向緩衝中放入資料,而不利用緩衝中的資料
* iterate:在預設情況下iterate利用快取資料,但如果緩衝中不存在資料有可以能出現N+1問題
樣本:Query q=session.createQuery(“from UserInfo”);
Iterator<UserInfo> list=q.iterate();
While(list.hasNext()) {
UserInfo st = (UserInfo) it.next();
System.out.println(st.getName());
}
避免N+1查詢解決方案:
1、可以將fetch抓取資料的屬性改為“join”,來避免N+1次的查詢;
2、使用二級緩衝
九、複查查詢(基於二:QBC的深度查詢)
複合查詢就是在原有查詢的基礎上再進行查詢,可以調用Criteria對象的createCriteria()方法在這個Criteria對象的基礎上再進行查詢。
樣本:Session session = SessionFactory.getCurrentSession();
User user = new User();
Transaction ts = session.beginTransaction();
try {
Criteria criteria1 = session.createCriteria(Room.class);
Criteria criteria2 =criterial.createCriteria("User");
criteria2.add(Restrictions.eq("name",new String("ijse"));
user= (User) criteria.list().get(0);
session.commit();
} catch (HibernateException ex) {
ts.rollBack();
ex.printStackTrace();
}
System.out.println(user.getName());
Hibernate查詢方式