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());}}

        


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