常用HQL(Hibernate Query Language)查询

2019-03-02 20:10|来源: 领悟书生

查询一个对象(实体类必须有一个不带参数的构造方法)

@Test
public void test01() {
    Session session = null;
    try {
        session = HibernateUtil.openSession();
        /**
         * 对于HQL而言,都是基于对象进行查询的
         */
        Query query = session.createQuery("from Special");
        List<Special> spes = query.list();
        for(Special spe:spes) {
            System.out.println(spe.getName());
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        HibernateUtil.close(session);
    }
}

使用select查询

//不能使用select *进行查询
//Query query = session.createQuery("select * from Special");
/**
 * 可以使用链式查询的方式
 */
List<Special> spes = session.createQuery("select spe from Special spe").list();
for(Special spe:spes) {
    System.out.println(spe.getName());
}

条件查询

List<Student> stus = session
    .createQuery("from Student where name like '%张%'")
    .list();
for(Student stu:stus) {
    System.out.println(stu.getName());
}
-------------------------------------------------
/**
 * 基于?的条件的查询
 * 特别注意:jdbc设置参数的最小下标是1,hibernate是0
 */
List<Student> stus = session
    .createQuery("from Student where name like ?")
    .setParameter(0, "%李%")
    .list();
for(Student stu:stus) {
    System.out.println(stu.getName());
}
------------------------------------------------
/**
 * 还可以基于别名进行查询,使用:xxx来说明别名的名称
 */
List<Student> stus = session
    .createQuery("from Student where name like :name and sex=:sex")
    .setParameter("name", "%刘%")
    .setParameter("sex", "男")
    .list();
for(Student stu:stus) {
    System.out.println(stu.getName());
}

使用uniqueResult可以返回唯一的一个值/对象

Long stus = (Long)session
        .createQuery("select count(*) from Student " +
                 "where name like :name and sex=:sex")
        .setParameter("name", "%刘%")
        .setParameter("sex", "男")
        .uniqueResult();
System.out.println(stus);
------------------------------------------------------
Student stu = (Student)session
        .createQuery("select stu from Student stu where id=:id")
        .setParameter("id", 1)
        .uniqueResult();
System.out.println(stu.getName());

基于投影的查询,通过在列表中存储一个对象的数组

List<Object[]> stus = session
        .createQuery("select stu.sex,count(*) from Student stu " +
                "group by stu.sex")
        .list();
for(Object[] obj:stus) {
    System.out.println(obj[0]+":"+obj[1]);
}

如果对象中相应的导航对象,可以直接导航完成查询

List<Student> stus = session
    .createQuery("select stu from Student stu " +
        "where stu.classroom.name=? and stu.name like ?")
    .setParameter(0, "计算机教育班").setParameter(1, "%张%")
    .list();
for(Student stu:stus) {
    System.out.println(stu.getName());
}

可以使用in来设置基于列表的查询,此处的查询需要使用别名进行查询

特别注意,使用in的查询必须在其他的查询之后

List<Student> stus = session
    .createQuery("select stu from Student stu " +
        "where stu.name like ? and stu.classroom.id in (:clas)")
    .setParameter(0, "%张%")
    .setParameterList("clas", new Integer[]{1,2})
    .list();
for(Student stu:stus) {
    System.out.println(stu.getName());
}

使用setFirstResult和setMaxResult可以完成分页的offset和pageSize的设置

List<Student> stus = session
    .createQuery("select stu from Student stu " +
        "where stu.classroom.id in (:clas)")
    .setParameterList("clas", new Integer[]{1,2})
    .setFirstResult(0).setMaxResults(15)
    .list();
for(Student stu:stus) {
    System.out.println(stu.getName());
}

可以通过is null来查询为空的对象,和sql一样不能使用=来查询null的对象

List<Student> stus = session
    .createQuery("select stu from Student stu " +
        "where stu.classroom is null")
    .setFirstResult(0).setMaxResults(15)
    .list();
for(Student stu:stus) {
    System.out.println(stu.getName());
}


连接查询

/**
 * 使用对象的导航可以完成连接,但是是基于Cross JOIN,效率不高,
 * 可以直接使用JOIN来完成连接
 */
List<Student> stus = session
    .createQuery("select stu from Student stu " +
        "left join " +
        "stu.classroom cla where cla.id=2")
    .setFirstResult(0).setMaxResults(15)
    .list();
for(Student stu:stus) {
    System.out.println(stu.getName());
}

统计班级学生的人数

List<Object[]> stus = session
    .createQuery("select cla.name,count(stu.classroom.id) from Student stu " +
        "right join stu.classroom cla group by cla.id")
    .list();
for(Object[] stu:stus) {
    System.out.println(stu[0]+","+stu[1]);
}


把查询出来的数据封装成一个对象。

定义一个学生对象DTO

package org.zttc.itat.model;
/**
 * DTO对象没有存储的意义,仅仅是用来进行数据的传输的
 *
 */
public class StudentDto {
    private int sid;
    private String sname;
    private String sex;
    private String cname;
    private String spename;
    //省去set get方法
    public StudentDto(int sid, String sname, 
            String sex, String cname,String spename) {
        super();
        this.sid = sid;
        this.sname = sname;
        this.sex = sex;
        this.cname = cname;
        this.spename = spename;
    }
     
    public StudentDto() {
    }
     
}

查询

/**
 * 直接可以使用new XXObject完成查询,
 * 注意,一定要加上Object的完整包名
 * 这里使用的new XX,必须在对象中加入相应的构造函数
 */
List<StudentDto> stus = session
    .createQuery("select new org.zttc.itat.model.StudentDto" +
    "(stu.id as sid,stu.name as sname,stu.sex as sex," +
    "cla.name as cname,spe.name as spename) " +
    "from Student stu left join stu.classroom cla " +
    "left join cla.special spe")
    .list();
for(StudentDto stu:stus) {
    System.out.println(stu.getSid()+","+stu.getSname()+","+
    stu.getSex()+","+stu.getCname()+","+stu.getSpename());
}


having是为group来设置条件的

List<Object[]> stus = session.createQuery("select spe.name," +
        "(count(stu.classroom.special.id)) from Student stu right join " +
        "stu.classroom.special spe group by spe " +
        "having count(stu.classroom.special.id)>150")
    .list();
for(Object[] obj:stus) {
    System.out.println(obj[0]+":"+obj[1]);
}


本文链接:常用HQL(Hibernate Query Language)查询,领悟书生学习笔记,转载请注明出处http://www.656463.com/article/417

相关问答

更多

使用HQL / Hibernate嵌套查询(Nested query with HQL / Hibernate)

我不愿意这样做,但经过一些研究,我只能考虑使用SQL查询。 就像是 : String sQuery = "SELECT SUM(case when max_amount is null then price ... final org.hibernate.SQLQuery query = session.createSQLQuery(sQuery); List results = query.list(); 我无法想到Hibernate使用HQL处理嵌套查询。 I was reluctant t ...

用HQL查询Hibernate(Query in Hibernate with HQL)

我认为你没有正确建立实体之间的关系。 @ForeignKey表示约束,但不表示java实体之间的关系本身。 在Hibernate 5.1版本之前,如果您之前没有使用@OneToOne, @OneToMany, @ManyToOne等注释建立它们之间的关系,则不能在JPQL中使用实体之间的连接... ...有关此主题以及如何加入无关的更多信息实体。 要执行查询,您必须在实体中定义类似的内容 @Entity @Table(name="TB_Person") public class TB_Per ...

Hibernate(HQL) - 如何查询“many in()”中的多对多(Hibernate(HQL) - how to query “where many in()” many to many)

未定义用户别名。 试试吧 String hql = "from User user inner join user.cars car where car.id in (:carIds)"; Query query = session.createQuery(hql) query.setParameterList("cars", carIds); 其中carIds是一个集合(而不是第三次尝试中的字符串),其中包含汽车的ID。 The user alias is not defined. Try w ...

SQL到Hibernate查询语言(HQL) - 缺少IN(SQL to Hibernate Query Language (HQL) - missing IN)

HQL不允许使用UNION ALL sql构造。 您必须执行两个不同的查询,然后您可以合并它们的结果。 所以你会有: 第一个查询: From TableA a where a.columnA is not null order by cast(a.columnA as int), a.columnB 第二个查询: TableA b where b.columnA is not null order by b.columnB HQL doesn't allow use UNION ALL sq ...

查询Hibernate或HQL不返回结果(Query Hibernate or HQL not return result)

我设法解决使用与以前一样的搜索方法的同一会话,使用Session类。 正确的代码如下所示: public Laudo buscarLaudoPorCodigo(Long idLaudo) { Session sessao = HibernateUtil.getSessionFactory().openSession(); try { Criteria consulta = sessao.createCriteria(Laudo.class); con ...

Hibernate HQL与接口(Hibernate HQL with interfaces)

事实上,根据Hibernate关于Polymorphic查询的文档: Hibernate查询可以在from子句中命名任何Java类或接口。 该查询将返回扩展该类或实现该接口的所有持久化类的实例。 以下查询将返回所有持久对象: from java.lang.Object o Named接口可以通过各种持久化类来实现: from Named n, Named m where n.name = m.name 但是因为接口没有被映射(因此未知),所以你需要在你的HQL查询中使用完全限定的名字: fro ...

hibernate hql getMaxVersion(hibernate hql getMaxVersion)

试试这个查询: from Report where reportId = :reportId order by version desc with setMaxResults = 1 Try this query: from Report where reportId = :reportId order by version desc with setMaxResults=1

EJB查询语言与HQL(EJB Query Language vs HQL)

EJB查询语言是一种标准查询语言,构建为供JPA实现(也称为JPQL)使用,如果您使用的ORM符合JPA,则支持该查询语言,因此它背后的想法是你应该能够更改您的JPA实现,而无需更改您的查询。 另一方面,HQL是特定于hibernate的,如果你不使用hibernate作为JPA实现,那么你的查询可能不会工作。 EJB Query Language is a standard query language built to be used by JPA implementations (also ...

iReport,使用SQL代替HQL查询与Hibernate连接(iReport, use SQL instead HQL query with an hibernate connection)

使用视图。 请参阅: Hibernate Union替代方案 Use a View. See this: Hibernate Union alternatives

Hibernate查询语言(HQL)更新列表(Hibernate Query Language (HQL) Update list)

Status是MySQL保留字。 将列重命名为其他内容 Status is a MySQL reserved word. Rename your column to something else