Hibernate数据查询

Hibernate Query Language(HQL)
Criteria Query
Native SQL
下面对其分别进行解释
Hibernate Query Language:
HQL提供了是十分强大的功能,它是针对持久化对象,用取得对象,而不进行update,delete和insert等操作。而且HQL是面向对象的,具备继承,多态和关联等特性。
from子句
from子句是最简单的HQL,例如from Student,也可以写成 select s from Student s。它简单的返回Student类的所有实例。
值得注意的是除了JAVA类和属性的名称外,HQL语句对大小写不敏感。
select子句
有时并不需要取得对象的所有属性,这时可以使用select子句进行属性查询,如select s.name from Student s。
例:
None.gif public   void  HQLselectDEMO()
ExpandedBlockStart.gifContractedBlock.gif    
dot.gif {
InBlock.gif        TRegister user 
= new TRegister();
InBlock.gif        Session session 
= HibernateUtil.currentSession();
InBlock.gif        Query query 
= session.createQuery("select u.userName from TRegister u");
InBlock.gif        List list 
= query.list();
InBlock.gif        
for(int i = 0 ; i < list.size(); i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            String name 
= (String)list.get(i);
InBlock.gif            System.out.println(name);
ExpandedSubBlockEnd.gif        }

ExpandedBlockEnd.gif    }
如果要查询两个以上的属性桧以数组的方式返回,如下:
None.gif public   void  HQLselectDEMO()
ExpandedBlockStart.gifContractedBlock.gif    
dot.gif {
InBlock.gif        TRegister user 
= new TRegister();
InBlock.gif        Session session 
= HibernateUtil.currentSession();
InBlock.gif        Query query 
= session.createQuery("select u.userName ,u.sex from TRegister u");
InBlock.gif        List list 
= query.list();
InBlock.gif        
for(int i = 0 ; i < list.size(); i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            Object obj[] 
= (Object[])list.get(i);
InBlock.gif            
InBlock.gif            System.out.println(obj[
0]+"    的性别是:"+obj[1]);
ExpandedSubBlockEnd.gif        }

ExpandedBlockEnd.gif    }

在使用属性查询时,由于使用对象数组,操作和理解不太方便,如果将 一个object[]中所有成员封装成一个对象就方便多了。下面的程序做了示例:
None.gif public   void  HQLselectDEMO()
ExpandedBlockStart.gifContractedBlock.gif    
dot.gif {        
InBlock.gif        Session session 
= HibernateUtil.currentSession();
InBlock.gif        Query query 
= session.createQuery("select new TRegister(u.userName,u.sex) from TRegister u");
InBlock.gif        List list 
= query.list();
InBlock.gif        
for(int i = 0 ; i < list.size(); i++)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
//Object obj[] = (Object[])list.get(i);
InBlock.gif
            TRegister user = (TRegister)list.get(i);
InBlock.gif            System.out.println(user.getUserName()
+"    的性别是:"+user.getSex());
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockStart.gifContractedSubBlock.gif        
/** *//**要正确运行以上程序,需要在TRegister类中加入一个相应的构造函数
InBlock.gif         public TRegister(String userName,String sex) {
InBlock.gif                this.userName = userName;
InBlock.gif                this.sex = sex;
InBlock.gif            }
ExpandedSubBlockEnd.gif          
*/

ExpandedBlockEnd.gif    }


统计函数查询
可以在HQL中使用函数,经常使用的函数如下:
count():统计记录条数。
min():求最小值。
max():求最大值。
sum():求和。
avg():求平均值。
例如,要取得Student实例的数量,可以编写如下HQL语句:
select count(*) from Student
取得Student平均年龄的HQL语句:
select avg(s.age) from Student as s
可以使用distinct去除重复的数据:
select distinct s.age from Student as s

where子句
HQL也支持子查询,它通过where子句实现这一机制。where子句可以让用户缩小要返回的实例的列表范围。例如下面语句会返回所有名字为"Bill"的Student实例:
Query query = session.createQuery("from Student as s where s.name='Bill'");
where子句允许出现的表达式包括了SQL中可以使用的大多数情况。
数学操作:+,-,*,/
真假比较操作:=, >=, <=, <>, !=, like
逻辑操作:and ,or, not
字符串连接:||

SQL标题函数 :如upper()和lower()
如果查询返回多条记录,可以用以下关键字来量化
all:表示所有的记录。
any:表示所有记录中的任意一条。
some:与any相同。
in:与any等价。
exists:表示子查询至少要返回一条记录。
例如,下面语句返回所有学生年龄都大于18的班级对象
from Group g where 18<all  (select s.age from g.students s)
下列语句返回在所有学生中有一个学生的年龄等于22的班级:
from Group g where 22 = any (select s.age from g.students s)
或者
from Group g where 22= some(select s.age from g.students s)
或者
from Group g where 22 in (select s.age from g.students s)

order by子句
查询返回列表可以按照任何返回的类或者组件的属性排序
from Student s order by s.name asc

连接查询
与SQL一样,HQL也支持连接查询,如内连接,外连接和交叉连接:
inner join:内连接
left outer join:左外连接
rigth outer join:右外连接
full join:全连接,但不常用
下面我重点介绍下内连接查询,左外连接和或外连接和内连接大同小异,而全连接几乎没有使用得到的地方。
inner join可以简写为join,例如在查询得到的Group对象时,内连接取得对应的Student对象,实现的程序代码如下:

None.gif Student stu  =   null ;
None.gif        Group group 
=   null ;
None.gif        Query query 
=  session.createQuery( " from Group g join g.students " );
None.gif        List list 
=  query.list();
None.gif        Object obj[] 
=   null ;
None.gif        
for ( int  i  =   0  ; i  <  list.size(); i ++ )
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif            obj 
= (Object[])list.get(i);
InBlock.gif            group 
= (Group)obj[0];//group是数组是第一个对象
InBlock.gif
            stu = (Student)obj[1];//stu是数组的第二个对象
InBlock.gif
            System.out.println(stu.getName()+"属于"+group.getName());
ExpandedBlockEnd.gif        }

None.gif    

Criteria Query方式
 当查询数据时,往往需要设置查询条件。在SQL或HQL语句中,查询条件常常放在where子句中。此处Hibernate还支持Criteria查询,这种查询方式把查询条件封装为一个Criteria对象。在实际应用中,可以使用Session的createCriteria()方法构建一个org.hibernate.Criteria实例,然后把具体的查询条件通过Criteria的add方法加入到Criteria实例中。这样程序员可以在不使用SQL甚至HQL的情况下进行数据查询。如下:
None.gif      public   void  criteriaDEMO()
ExpandedBlockStart.gifContractedBlock.gif    
dot.gif {
InBlock.gif        Session session 
= HibernateUtil.currentSession();
InBlock.gif        Criteria criteria 
= session.createCriteria(TRegister.class);//生成一个Criteria实例
InBlock.gif
        criteria.add(Restrictions.eq("userName","fengyan"));//等价于where name = 'fengyan'
InBlock.gif
        List list = criteria.list();
InBlock.gif        TRegister user 
= (TRegister)list.get(0);
InBlock.gif        System.out.println(user.getUserName());
ExpandedBlockEnd.gif    }

常用的查询限制方法
 上面代码中 Restrictions.eq()方法表示equal,即等于的情况。Restrictions类提供了查询限制机制。它提供了许多方法,以实现查询限制
Restrictions.eq():equal,=
Restrictions.allEq(): 参数为Map对象,使用key/value进行多个等于的对比,相当于多个                                          Restrictions.eq()的效果
Restrictions.gt():greater-than,<
Restrictions.lt():less-than,<
Restrictions.le:less-equal,<=
Restrictions.between():对应SQL的between子句。
Restrictions.like():对应SQL的like子句。
Restrictions.in():对应SQL的in子句。
Restrictions.and():and 关系。
Restrictions.or():or 关系。
Restrictions.isNull():判断属性是否为空,为空返回true,否则返回false。
Restrictions.isNoyNull():与上面的相反。
Order.asc():根据传入的字段进行升序排序。
Order.desc():与上相反
MatchMode.EXACT:字符串中精确匹配,相当于like 'value'
MatchMode.ANYWHERE:字符串在中间位置,相当于like'%value%'
MatchMode.START:字符串在最前面,相当于like'value%'
MatchMode.END:字符串在最后,相当于like'%value'
下面是几个查询限制的例子:
查询学生名字以t开关的所有Student对象
Criteria criertia = session.createCriteria(Student.class);
  criteria.add(Restrictions.like("name", "t%"));
  List list = criteria.list();
  Student stu = (Student)list.get(0);
或者:
  Criteria criertia = session.createCriteria(Student.class);
  criteria.add(Restrictions.like("name", "t",MatchMode.START));
  List list = criteria.list();
  Student stu = (Student)list.get(0);
查询学生姓名在Bill,Jack和Tom之间所有的Student对象
 String[] names = {"Bill","Jack","Tom"};
  Criteria criertia = session.createCriteria(Student.class);
  criteria.add(Restrictions.in("name", names));
  List list = criteria.list();
  Student stu = (Student)list.get(0);
查询学生年龄(age)等于22或为空(null)的所有学生对象
Criteria criertia = session.createCriteria(Student.class);
  criteria.add(Restrictions.eq("age", new Integer(22)));
  criteria.add(Restrictions.isNull("age"));
  List list = criteria.list();
  Student stu = (Student)list.get(0);
查询学生姓名以字母F开头的所有Student对象,并按姓名升序排序
Criteria criertia = session.createCriteria(Student.class);
  criteria.add(Restrictions.like("name", "F%"));
  criteria.addOrder(Order.asc("name"));
  List list = criteria.list();
  Student stu = (Student)list.get(0);
注意调用Order.asc的方法应该是Criteria.addOrder()方法。

连接限制
Criteria查询中使用FetchMode来实现连接限制。在HQL语句中,可以通过fetch关键字来表示预先抓取(Eager fetching),如下:
from Group g
left join fetch g.students s
where g.name like '%2005'
可以使用Criteria的API完成同样的功能,如下:

None.gif Criteria criertia  =  session.createCriteria(Group. class );
None.gif        criteria.setFetchMode(
" students " , FetchMode.EAGER);
None.gif        criteria.add(Restrictions.like(
" name " " 2005 " ,MatchMode.END));
None.gif        List list 
=  criteria.list();

以上两种方式编写的代码都使用相同的SQL语句来完成它们的功能,如下:
select  g.*, s.* from Group g
left outer join Student s
on g.id = s.group_id
where g.name like '%2005'

Native SQL查询
本地SQL查询指的是直接使用本地数据库的SQL语言进行查询。这样做对于将 原来的SQL/JDBC程序迁移到Hibernate应用很有用
创建一个基于SQL的Query
Native SQL查询是通过SQLQuery接口来控制的,它通过调用Session.createSQLQuery()方法来获得。如:

None.gif String sql  =   " select {s.*} from t_student s where s.age>22 " ;
None.gif
// {}用来引用数据表的别名,{s.*}表示使用s来做为t_student表的别名
None.gif
SQLQuery sqlQuery  =  session.createSQLQuery(sql);
None.gifsqlQuery.addEntity(
" s " ,Student. class );
None.gifList list 
=  sqlQuery.list();
None.gif
for ( int  i  =   0  ; i  <  list.size(); i ++ )
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    Student stu 
= (Student)list.get(i);
ExpandedBlockEnd.gif}

None.gif
// createSQLQuery(String sql)利用传入的sql参数构造一个SQLQuery实例。使用该方法时,还需要传入查询的实体类,因此在配合使用SQLQuery的addEntity()方法一起使用。
None.gif
命名SQL查询
与HQL的命名查询相似,也可以将 本地的SQK查询语句定义在映射文件中,然后像调用一个命名HQL查询一样专题报道调用命名SQL查询。
如:
None.gif    </ class >
None.gif    
None.gif    
< sql-query  name ="QueryStudents" >
None.gif        
<![CDATA[
None.gif                    select {s.*} from t_student s where s.age > 22
None.gif        
]]>
None.gif            
< return  alias ="s"  class ="Student"   />
None.gif    
</ sql-query >
None.gif
</ hibernate-mapping >
配合以上配置我们可以如下编写代码来查询
None.gif Query query  =  session.getNamedQuery( " QueryStudents " );
None.gifList list 
=  query.list();
None.gif
for ( int  i  =   0  ; i  <  list.size();i ++ )
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    Student stu 
= (Student)list.get(i);
InBlock.gif
ExpandedBlockEnd.gif}
也可以在命名查询是设定参数,如下:
None.gif   < sql-query  name ="QueryStudents" >
None.gif        
<![CDATA[
None.gif                    select {s.*} from t_student s where s.age > :age
None.gif        
]]>
None.gif            
< return  alias ="s"  class ="Student"   />
None.gif    
</ sql-query >
None.gif
</ hibernate-mapping >
程序代码:
None.gif Query query  =  session.getNamedQuery( " QueryStudents " );
None.gifquery.setInteger(
" age " , 22 );
None.gifList list 
=  query.list();
None.gif
for ( int  i  =   0  ; i  <  list.size();i ++ )
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    Student stu 
= (Student)list.get(i);
InBlock.gif
ExpandedBlockEnd.gif}
自定义insert , update和delete语句
Hibernate 3.x的映射文件中新添加<sql_insert>,<sql_update>,<sql-delete>3个标记。可以使用这3个标记自定义自己的insert ,update,delete语句,如:
None.gif </ class >
None.gif    
< sql-insert >
None.gif        insert into t_student(name,age,id) values(?,?,?)
None.gif    
</ sql-insert >
None.gif    
< sql-update >
None.gif        update t_student set name=?,age=? where id=?
None.gif    
</ sql-update >
None.gif    
< sql-delete >
None.gif        delete from t_student where id = ?
None.gif    
</ sql-delete >
None.gif
</ hibernate-mapping >
对于以上自定义的SQL语句,要注意以下几点
1:insert 和update语句中定义的字段必须和映射文件声明的属性相应,一个都不能少。
2:在insert 和update语句中,属性出现的顺序必须和映射文件中的顺序一样。
3:在insert语句中,主键id总是放在最后。
在程序中实现以上自定义的insert语句如下:
None.gif Student stu  =   new  Student();
None.gifstu.setName(
" Bill " );
None.gifstu.setAge(
22 );
None.gifsession.save(stu);
如果不想在insert或update语句中包括所有属性,则可以在属性定义时 加上insert ="false"或update="false"如下:
None.gif < property  name  = "name"  type ="string"  insert  = "false"  update ="false" />
None.gif
< sql-insert >
None.gif    insert into t_student(age,id) values(?,?)
None.gif
</ sql-inert >
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值