session.createQuery("HQL语句")
HQL语句查询的是实体类的属性
//查询字段的数据类型与类中字段属性相同
List students=session.createQuery("select name from Student").list();
for(Iterator iter=students.iterator();iter.hasNext();)
{
String str=(String)iter.Next();
}
其中name代表属性,Student代表类名
//查询多个属性,其集合元素是对象数组,数组元素的类型和实体类的属性类型一致,数组的长度取决于查询的属性个数。
List students=session.createQuery("select id,name from Student").list();
for(Iterator iter=students.iterator();iter.hasNext();)
{
Object[] objs=(Objectp[])iter.next();
}
//在HQL中是用new那么返回的就是对象,不过需要在类中添加构造方法
List students=session.createQuery("select new Student(id,name) from Student").list();
for(Iterator iter=students.iterator();iter.hasNext();)
{
Student objs=(Student)iter.next();
}
//HQL中为表取别名
List students=session.createQuery("select new s.id,s.name from Student as s").list();
for(Iterator iter=students.iterator();iter.hasNext();)
{
Student objs=(Student)iter.next();
}
//查询实体对象
//表可以加别名
List students=session.createQuery("from Student").list();
for(Iterator iter=students.iterator();iter.hasNext())
{
Student stu=(Student)iter.next();
}
或者
List students=session.createQuery("select s from Student s").list();
那么在HQL中必须设置别名
//使用迭代器查询
Iterator iter=session.createQuery("from Student").iterate();
while(iter.hasNext())
{
Student student=(Student)iter.next();
}
迭代器查询时先查询id列表的sql语句,然后再根据id查询实体对象的sql,会发出n+1条sql语句。
如果首先使用list从数据库中把数据取出到缓存中,然后再使用iterator迭代器从缓存中查询数据,如果缓存中没有数据,才发出sql语句。这样就可以避免发出n+1条数据。
list在默认下只用数据库查询数据到缓存,iterator会使用缓存中的数据。
//外置命名查询
把HQL放置到配置文件中。
在配置文件中的class外,加入<query>标签
例如:
<query name="stu"><![CDATA[select s from Student where s.id<? ]]></query>
在所有的配置文件中query的name不能重名,因为是根据query设置的name属性来查找HQL语句的。
代码:
List students=session.getNamedQuery("stu").setParameter(0,10).list();
//查询过滤器
在class标签外加上标签<filter-def>标签
<class name="Student" table="t_student">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<!-- 在查询Student的时候会在HQL后自动加上该条件 -->
<filter name="filtertest" condition="id < :myid"/>
</class>
<filter-der name="filtertest">
<filter-param name="myid" type="integer"/>
</filter-def>
在程序中开启事务后需要启用过滤器:
session.beginTransaction();
session.endableFilter("filtertest").setParameter("myid",20);
List students=session.createQuery("from Student").list();
//hibernate也支持原生sql查询
//得到的是对象数组
List students=session.createSQLQuery("select * from t_student").list();
for(Iterator iter=student.iterator();iter.hasNext();)
{
Object[] objs=(Object[])iter.next();
}
//分页查询
List students=session.createQuery("from Student").setFirstResult(0).setMaxResult(2).list();
//对象导航查询
List students=session.createQuery("select s from Student s where s.class.id<5").list();
class是s类下的一个对象,id是class类的id字段
//连接查询
select c.name,s.name from Student s join s.classes
其中classes是Student中的对象
左连接查询
select c.name,s.name from Classes c left join c.students s
右连接
select c.name,s.name from Classes c right join c.students s
//hql函数
统计查询:
List student=session.createQuery("select count(*) from Student").list();
Long count=(Long)student.get(0);
或者写成:
Long count=(Long)session.createQuery("select count(*) from Student").uniqueResult();
List student=session.createQuery("select c.name,count(s) from Student s join s.classes c group by c.name order by c.id").list();
//HQL的DML
HQL中的DML直接操作数据库,容易造成数据库与缓存不一致
session.createQuery("update Student s set s.name=? where s.id in(:myids)").setParameter(0,"张三").setParameterList("myids",new Object[]{0,1,2}).execueUpdate();