我們在用到hibernate框架的時候經常和Hql語言打交道,這是把面向對象貫徹到骨髓的設計。我們通過實例來展示它的強大用處。
下圖是數據庫中的數據:
新建了一個實體類UserEntity.java:
@Entity
@Table(name = "user_tbl")
public class UserEntity {
private int id;
private String name;
private String password;
private int age;
private int sex;
public UserEntity(){
}
public UserEntity(String name, int age) {
this.name = name;
this.age = age;
}
@Id
@Column(name = "id")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Column(name = "name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Column(name = "password")
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Column(name = "age")
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Column(name = "sex",columnDefinition = "tinyint")
public int getSex() {
return sex;
}
public void setSex(int sex) {
this.sex = sex;
}
}
1.查詢單個對象,比如我們可以根據ID來查,用ID來確保唯一的數據,但是這裏我們使用getFirstResult(index).setMaxResult(1).uniqueResult()來查,下面是相關代碼:
StringBuffer infoHql = new StringBuffer("from UserEntity");
//只能查唯一的數據集,如果數據庫中有兩條數據,可以通過setFirstResult(0)[從0開始]查唯一的那條數據
UserEntity user = (UserEntity)sessionFactory.getCurrentSession().createQuery(infoHql.toString())
.setFirstResult(0).setMaxResults(1).uniqueResult();
我們可以發現getFirstResult(index)裏面的index就是一個索引值,它是從0開始的。返回的結果我們用JSON格式化後可以看到:
{"age":12,"id":1,"name":"yang","password":"123","sex":0}
2.比如我們想查表中特定的字段,比如user_tbl,我只想查name,age,sex的話,我們可以通過下面的查到
StringBuffer infoHql = new StringBuffer("select name,age,sex from UserEntity");
List<Object> objs = sessionFactory.getCurrentSession().createQuery(infoHql.toString()).list();
Iterator<Object> iter = objs.iterator();
while(iter.hasNext()){
Object[] o = (Object[])iter.next();
logger.info("name:"+o[0]);
logger.info("age:"+o[1]);
logger.info("sex:"+o[2]);
}
我們可以看到返回的結果是一個Object數組組成的鏈表。這種往往不是我們想要的結果,我們想封裝結果怎麼辦? 我們新建一個對象UserModel,然後以這種格式返回
StringBuffer infoHql = new StringBuffer("select new com.rey.entities.UserModel(u.name,u.age) from UserEntity as u");
List<UserEntity> users = sessionFactory.getCurrentSession().createQuery(infoHql.toString()).list();
返回的結果我們可以看到:
[{"age":12,"name":"yang"},{"age":18,"name":"eng"},{"age":20,"name":"oo"}]
3.如果我們查數據庫中單個列的話,我們通過createQuery(hql).list() 是可以返回相應的數據的,比如我們可以看到下面的例子:
StringBuffer idsHql = new StringBuffer("select id from UserEntity");
List<Integer> ids = sessionFactory.getCurrentSession().createQuery(idsHql.toString()).list();
上面的ids將返回id組成的List,這時候HQL查詢就可以識別出查詢出來的結果是什麼類型的數據了。這點我們需要注意。
當然我們也可以使用Criteria查詢來做上面的業務邏輯,代碼如下:
Criteria criteria= sessionFactory.getCurrentSession().createCriteria(UserEntity.class);
criteria.setProjection(Projections.projectionList().add(Projections.id().as("id"))
.add(Projections.property("name").as("name")))
.setResultTransformer(new AliasToBeanResultTransformer(UserEntity.class));
List<UserEntity> list = criteria.list();
可以將結果轉換爲UserEntity對象來做處理,用JSON做返回的結果集,輸出結果爲:
[{"age":0,"id":1,"name":"yang","sex":0},
{"age":0,"id":2,"name":"deng","sex":0},
{"age":0,"id":3,"name":"li","sex":0},
{"age":0,"id":4,"name":"wei","sex":0}]
4.有時候我們在用HQL進行查詢的時候經常會用ID來查相關聯的兩個實體類,這樣就可以用cross 查詢來連接。
from ViewPointEntity as v,UserEntity as u where v.id= 21 and v.userId = u.id
然後通過對象數組的形式拿取相應的實體類
Object[] o = (Object[]) sessionFactory.getCurrentSession().createQuery(viewHql.toString()).uniqueResult();
ViewPointEntity viewPoint = (ViewPointEntity) o[0];
UserEntity friendUserEntity = (UserEntity) o[1];
拿到實體類我們就可以返回前端想要的數據了。網上說根據ID來一個個查詢的速率比這個快,這個有待測試~~
5.在hql中我們經常遇到in關鍵字在數據庫中不能排序的問題,解決方案是連接查詢就可以根據條件表來關聯數據。
這裏我們查用戶id爲52的用戶收藏的觀點,但是我們收藏的觀點是無序的,所以我們連接觀點表根據觀點表中的發佈時間降序排列
select * from viewpoint_tbl as v left join
collect_tbl as c on v.id = c.src_id where c.src_type=1 and c.user_id = 52
order by c.reg_time desc
上面我們用到了原生的SQL查詢,在session查詢的時候要用到createSQLQuery()方法來查詢6.有時候我們使用原生的SQL語句對三種不同情況的數據進行統計,比如下面的例子SQL,
select condition1,condition2,condition3 from (xxx) as condition1,(xxx) as condition2,(xxx) as condition3
然後我們使用createSQLQuery方法進行查詢,我們想分別得到condition1,condition2,condition3的值,我們可以將查詢的結果轉換爲Map<String,Object>結構
Map<String,Object> map = (Map<String,Object>)createSQLQuery(hql).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).uniqueResult()
然後根據map.get(condition1) 就可以拿到相應的結果了。
上面的例子是轉成Map來提取的,其實也可以不用轉成Map,直接用Object[]對象就可以
List<Object[]> newsestList = session.createSQLQuery(newsestHql.toString()).setFirstResult((page - 1) * maxNum).setMaxResults(maxNum).list();
然後遍歷上面的newsestList對象就可以了。
if(newsestList!= null && newsestList.size()>0){
for(Object[] obj : newsestList){
int condition1= Integer.parseInt(obj[1].toString());}}