Hql使用總結

        我們在用到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());}}

        


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章