HQL与QBC检索:
HQL查询:
HQL(HibernateQuery Language)是面向对象的查询语言,它和SQL查询语言有些相似。在Hibernate提供的各种检索方式中,HQL是使用最广的一种检索方式。
1)
Query query = session.createQuery("select s.name, s.age from Student s");
List list = query.list();
for(int i = 0; i < list.size(); i++)
{
/**
* Return the queryresults as a List.
* If the querycontains multiple resultspre row,
* the results arereturned in an instance of Object[].
*/
Object[] obj = (Object[])list.get(i);
System.out.println(obj[0] +", " + obj[1]);
}
这样查询的结果是离散的值,返回的是一个数组。
2)
Query query = session.createQuery("select new Student(s.name, s.age) from Students");
List list = query.list();
for(int i = 0; i < list.size(); i++)
{
Student student = (Student)list.get(i);
System.out.println(student.getName() +", " + student.getAge());
//查出来的对象不包含cardId,打印为null
System.out.println(student.getCardId());
}
构造一个对象进行查询。
注意:需要为Student类提供带name、age两个参数(顺序也要一致)的构造函数,否则会出现下面异常:
org.hibernate.hql.ast.QuerySyntaxException : Unable to locate appropriate constructor on class[com.songjinghao.hibernate.Student] [select new Student(s.name, s.age) fromcom.songjinghao.hibernate.Student s]3)
Query query = session.createQuery("from Team t join t.students"); //抵消掉了延迟加载
命令行打印出的SQL语句,即该语句向数据库发出的SQL语句:
select
team0_.id as id0_0_,
students1_.id as id1_1_,
team0_.teamName as teamName0_0_,
students1_.name as name1_1_,
students1_.cardId as cardId1_1_,
students1_.age as age1_1_,
students1_.team_id as team5_1_1_
from
team team0_
inner join
student students1_
onteam0_.id=students1_.team_id
以上是内连接(inner join)查询。
对应的SQL语句如下:
select*from teamjoin student on team.id = student.team_id;
等价于:
select*from team, studentwhere team.id = student.team_id;
内连接查询出来的结果是满足team.id= student.team_id条件的所以记录。
顺便记录一下左外连接(leftouterjoin):
select*from teamleftouterjoin studenton team.id = student.team_id;
右外连接同样道理,不举例了。
左连接以左表为准,右连接以右表为准。
附图:
依次为:team表、student表、内连接结果、左连接结果、右连接结果
附程序说明内连接抵消延迟加载问题:
Session session = sessionFactory.openSession();
Transaction tx = null;
Query query = null;
List list = null;
try
{
tx = session.beginTransaction();
query = session.createQuery("from Team t join t.students"); //抵消掉了延迟加载
list = query.list();
tx.commit();
}
catch(Exception ex)
{
ex.printStackTrace();
if(tx !=null)
{
tx.rollback();
}
}
finally
{
session.close();
}
//返回的结果是team和student信息的拼合,可参考上图
for(int i = 0; i < list.size(); i++)
{
Object[] obj = (Object[])list.get(i);
Team team = (Team)obj[0];
Student student = (Student)obj[1];
System.out.println(team.getTeamName());
System.out.println(student.getName());
System.out.println("-------------------");
}
将映射文件中lazy属性值改为true,即延迟加载。以上程序中在session关闭之后,依然能够获得到查询的结果。说明:query = session.createQuery("from Team t join t.students"); //抵消掉了延迟加载
4) 命名查询
Team team = (Team)session.get(Team.class,"ff8080813b465b05013b465b069c0001");
//HQL命名查询:":自定义命名"
Query query = session.createQuery("from Student s where s.team = :team and s.age > 20");
//命名查询方式一:
// query.setParameter("team", team,Hibernate.entity(Team.class));
//命名查询方式二:
// query.setEntity("team", team);
//过滤方式查询
// Query query = session.createFilter(team.getStudents(),"where age > 20");
List<Student> list = query.list();
System.out.println(list.size());
QBC查询:
采用HQL检索方式时,在应用程序中需要定义基于字符串形式的HQL查询语句。
QBC API 提供了检索对象的另一种方式,它主要由Criteria接口、Criterion接口和Expression类组成,它支持在运行时动态生成查询语句。
// Criteria criteria =session.createCriteria(Student.class).add(Restrictions.between("age",new Integer(12), new Integer(30)));
// Criteria criteria =session.createCriteria(Student.class).add(Restrictions.like("name","t%"));
// Criteria criteria =session.createCriteria(Student.class).addOrder(Order.asc("age")).addOrder(Order.desc("cardId"));
String[] names = {"jerry","spark", "tom"};
Criteria criteria = session.createCriteria(Student.class).add(Restrictions.in("name", names));
List<Student> list = criteria.list();
for(Student s : list)
{
System.out.println(s.getName());
}