Hibernate查询语句

来源:互联网 发布:汽车专业英语软件 编辑:程序博客网 时间:2024/05/04 00:50


Hibernate查询
  1. 概述:数据查询与检索是Hibernate中的一个亮点。相对其他ORM实现而言,Hibernate提供了灵活多样的查询机制。   
  2.   
  3. 标准化对象查询(Criteria Query):以对象的方式进行查询,将查询语句封装为对象操作。优点:可读性好,符合Java 程序员的编码习惯。缺点:不够成熟,不支持投影(projection)或统计函数(aggregation)   
  4. Hibernate语言查询(Hibernate Query Language,HQL):它是完全面向对象的查询语句,查询功能非常强大,具备继承、多态和关联等特性 。Hibernate官方推荐使用HQL进行查询。   
  5. Native SQL Queries(原生SQL查询):直接使用数据库提供的SQL方言进行查询。   

 

 
标准化对象查询(Criteria Query)
  1. 现在Hibernate也支持一种直观的、可扩展的条件查询API。目前为止,这个API还没有更成熟的HQL查询那么强大,也没有那么多查询能力。特别要指出,条件查询也不支持投影(projection)或统计函数(aggregation)。   
  2.   
  3. 简单例子:查询用户名以“J”开头的所有用户。   
  4.     Query ql=session.createQuery("from Authors where auLname like '%Wh%'");   
  5.     List ls=ql.list();   
  6.     System.out.println(ls.size());   

 

 
创建一个Criteria实例
  1. net.sf.hibernate.Criteria这个接口代表对一个特定的持久化类的查询。Session是用来制造Criteria实例的工厂。    
  2.   
  3. //从第一条到第五条   
  4. Query ql1=session.createQuery("from Authors");   
  5. ql1.setFirstResult(10);//从什么地方开始取值   
  6. ql1.setMaxResults(5);//最多取几条   
  7. List ls1=ql1.list();   
  8. System.out.println(ls1.size());   

 

 
分组统计查询.
  1. Query ql=session.createQuery("select type,sum(price) from Titles group by type");   
  2. List ls=ql.list();   
  3.   
  4.   
  5. for (int i = 0; i < ls.size(); i++) {   
  6.     Object ob[]=(Object[]) ls.get(i);   
  7.     for(int j=0;j
  8.         if(ob[j]!=null){   
  9.         System.out.println(ob[j].toString());   
  10.     }   
  11. }   

 

 
预制的条件类型
  1. Query ql=session.createQuery("from Titles where title_id=?");   
  2. ql.setString(0, "bu1032");   
  3. List ls=ql.list();   
  4. System.out.println(ls.size());   
  5.   
  6. 其中的?是一个占位符,它将会被所查询实体的行别名所替代。  

 

Hibernate语言查询 (Hibernate Query Language,HQL)
  1. HQL用面向对象的方式生成SQL   
  2. 以类和属性来代替表和数据列   
  3. 支持多态   
  4. 支持各种关联   
  5. 减少了SQL的冗余   
  6.   
  7. HQL支持所有的关系数据库操作   
  8. 连接(joins,包括Inner/outer/full joins),笛卡尔积(cartesian products)   
  9. 投影(projection)   
  10. 聚合(Aggregation,max, avg)和分组(group)   
  11. 排序(Ordering)   
  12. 子查询(Subqueries)   
  13. SQL函数(SQL function calls)   

 

 
大小写敏感性(Case Sensitivity)
  1. 除了Java类和属性名称外,查询都是大小写不敏感的。 所以, SeLeCT 和 sELEct 以及 SELECT 相同的,但是 net.sf.hibernate.eg.FOO 和 net.sf.hibernate.eg.Foo 是不同的, foo.barSet 和 foo.BARSET也是不同的。   

 

 
 from子句
  1. 最简单的Hibernate查询是这样的形式:    
  2.     from eg.Cat    
  3.     它简单的返回所有eg.Cat类的实例。    
  4.     大部分情况下,你需要赋予它一个别名(alias),因为你在查询的其他地方也会引用这个Cat。    
  5. from eg.Cat as cat    
  6. 上面的语句为Cat赋予了一个别名cat 。所以后面的查询可以用这个简单的别名了。   
  7. as关键字是可以省略的,我们也可以写成这样:    
  8.     from eg.Cat cat 可以出现多个类,结果是它们的笛卡尔积,或者称为“交叉”连接。    
  9. from Formula, Parameterfrom Formula as form, Parameter as param    
  10.     让查询中的别名服从首字母小写的规则,我们认为这是一个好习惯。这和Java对局部变量的命名规范是一致的。(比如,domesticCat).   

 

 
联合(Associations)和连接(joins
  1. 你可以使用join定义两个实体的连接,同时指明别名。   
  2.   
  3.     from eg.Cat as cat inner join cat.mate as mate left outer join cat.kittens as kitten from eg.Cat as cat left join cat.mate.kittens as kittens from Formula form full join form.parameter param   
  4.   
  5. 支持的连接类型是从ANSI SQL借用的:    
  6. 内连接,inner join    
  7. 左外连接,left outer join    
  8. 右外连接,right outer join    
  9. 全连接,full join (不常使用)    
  10.   
  11. inner join, left outer join 和 right outer join 都可以简写。    
  12.     from eg.Cat as cat join cat.mate as mate left join cat.kittens as kitten    
  13.     并且,加上 "fetch"后缀的抓取连接可以让联合的对象随着它们的父对象的初始化而初始化,只需要一个select语句。这在初始化一个集合的时候特别有用。它有效地覆盖了映射文件中对关联和集合的外连接定义。    
  14.     from eg.Cat as cat inner join fetch cat.mate left join fetch cat.kittens    
  15.     抓取连接一般不需要赋予别名,因为被联合的对象应该不会在where子句(或者任何其它子句)中出现。并且,被联合的对象也不会在查询结果中直接出现。它们是通过父对象进行访问的。    
  16.   
  17. 请注意,目前的实现中,在一次查询中只会抓取一个集合(其他的一切都做不到。)   
 
select子句
  1. select子句选择在结果集中返回哪些对象和属性。思考一下下面的例子:    
  2.     select mate from eg.Cat as cat inner join cat.mate as mate    
  3.     这个查询会选择出作为其它猫(Cat)朋友(mate)的那些猫。   
  4.   
  5. 当然,你可以更加直接的写成下面的形式:    
  6.     select cat.mate from eg.Cat cat   
  7.   
  8. 你甚至可以选择集合元素,使用特殊的elements功能。下面的查询返回所有猫的小猫。    
  9.     select elements(cat.kittens) from eg.Cat cat    
  10.   
  11. 查询可以返回任何值类型的属性,包括组件类型的属性:    
  12.     select cat.name from eg.DomesticCat cat where cat.name like 'fri%' select cust.name.firstName from Customer as cust    
  13.   
  14. 查询可以用元素类型是Object[]的一个数组返回多个对象和/或多个属性。    
  15.     select mother, offspr, mate.name from eg.DomesticCat as mother inner join mother.mate as mate left outer join mother.kittens as offspr    
  16.   
  17. 或者实际上是类型安全的Java对象    
  18.     select new Family(mother, mate, offspr) from eg.DomesticCat as mother join mother.mate as mate left join mother.kittens as offspr    
  19.   
  20.     上面的代码假定Family有一个合适的构造函数。    

 

 
统计函数(Aggregate functions)
  1. HQL查询可以返回属性的统计函数的结果。    
  2.   
  3. select avg(cat.weight), sum(cat.weight), max(cat.weight), count(cat) from eg.Cat    
  4.   
  5. cat 在select子句中,统计函数的变量也可以是集合。   

 

 
多态(polymorphism)查询
  1. 类似下面的查询:    
  2. from eg.Cat as cat 返回的实例不仅仅是Cat,也有可能是子类的实例,比如DomesticCat。Hibernate查询可以在from子句中使用任何Java类或者接口的名字。查询可能返回所有继承自这个类或者实现这个接口的持久化类的实例。下列查询会返回所有的持久化对象:    
  3. from java.lang.Object o 可能有多个持久化类都实现了Named接口:    
  4. from eg.Named n, eg.Named m where n.name = m.name 请注意,上面两个查询都使用了超过一个SQL的SELECT。这意味着order by子句将不会正确排序。(这也意味着你不能对这些查询使用Query.scroll()。)    

 

 
HQL示例
  1. Hibernate查询可以非常强大复杂。实际上,强有力的查询语言是Hibernate的主要卖点之一。   
  2.   
  3. 复杂例子:从User和Group中查找属于“admin”组的所有用户。   
  4.     Query query = session.createQuery(   
  5.         “from User user where user.group.name=‘admin’”);   
  6.   
  7. 如果用传统的SQL则查询语句如下:   
  8. select user.userId as userId, user.name as name, user.groupId as groupId, user.idCardId as idCardId  from TBL_USER user, TBL_GROUP group where (group.groupName='admin'  and user.groupId=group.groupId)   
  9.   
  10.   
  11. 下面给出的示例与我在近期实际项目中使用的一些查询很类似。请注意你编写的查询大部分等都不会这么复杂!   
 
HQL示例
  1. 下面的查询对特定的客户,根据给定的最小总计值(minAmount),查询出所有未付订单,返回其订单号、货品总数、订单总金额,结果按照总金额排序。在决定价格的时候,参考当前目录。产生的SQL查询,在ORDER,ORDER_LINE,PRODUCT,CATALOG和PRICE表之间有四个内部连接和一个没有产生关联的字查询。    
  2.   
  3. select order.id, sum(price.amount), count(item) from Order as order join order.lineItems as item join item.product as product, Catalog as catalog join catalog.prices as price where order.paid = false and order.customer = :customer and price.product = product and catalog = :currentCatalog group by order having sum(price.amount) > :minAmount order by sum(price.amount) desc    
 
HQL示例
  1. 下面的查询统计付款记录处于每种状态中的数量,要排除所有处于AWAITING_APPROVAL状态的,或者最近一次状态更改是由当前用户做出的。它翻译成SQL查询后,在PAYMENT,PAYMENT_STATUS和PAYMENT_STATUS_CHANGE表之间包含两个内部连接和一个用于关联的子查询。   
  2.   
  3. select count(payment), status.name from Payment as payment join payment.currentStatus as status join payment.statusChanges as statusChange where payment.status.name <> PaymentStatus.AWAITING_APPROVAL or ( statusChange.timeStamp = ( select max(change.timeStampfrom PaymentStatusChange change where change.payment = payment ) and statusChange.user <> :currentUser ) group by status.name, status.sortOrder order by status.sortOrder     
HQL示例
  1. 下面的查询使用了MS SQL Server的isNull()函数,返回当前用户所属的组织所有账户和未付支出。翻译为SQL查询后,在ACCOUNT, PAYMENT, PAYMENT_STATUS,ACCOUNT_TYPE, ORGANIZATION 和 ORG_USER表之间有三个内部连接,一个外部连接和一个子查询。   
  2.   
  3. select account, payment from Account as account left outer join account.payments as payment where :currentUser in elements(account.holder.users) and PaymentStatus.UNPAID = isNull(payment.currentStatus.name, PaymentStatus.UNPAID) order by account.type.sortOrder, account.accountNumber, payment.dueDate    

 

 
Hibernate最佳实践(Best Practices)示例
  1. 1、使用Configuration装载映射文件时,不要使用绝对路径装载。最好的方式是通过getResourceAsStream()装载映射文件,这样Hibernate会从classpath中寻找已配置的映射文件。   
  2.   
  3. 2、SessionFactory的创建非常消耗资源,整个应用一般只要一个SessionFactory就够了,只有多个数据库的时候才会使用多个SessionFactory。   
  4.   
  5. 3、在整个应用中,Session和事务应该能够统一管理。(Spring为Hibernate提供了非常好的支持)   
  6.   
  7. 4、将所有的集合属性配置设置为懒加载(lazy=”true”)。在hibernate2.x版本中,lazy默认值是“false”,但hibernate3.x已经将lazy的默认改为“true”了。   
  8. 5、在定义关联关系时,集合首选Set,如果集合中的实体存在重复,则选择List(在定义配置文件时,可以将List定义为bag),数组的性能最差。   
  9.   
  10. 6、在一对多的双向关联中,一般将集合的inverse属性设置为true,让集合的对方维护关联关系。例如:Group-User,由User来维护Group和User的关联关系。   
  11.   
  12. 7、HQL子句本身大小写无关,但是其中出现的类名和属性名必须注意大小写区分。   
  13.   
  14. 8、在非分布式架构中,不需要使用DTO来向上层传输数据。直接使用POJO的Entity就可以了。   
  15.   
  16. 9、如果要精通Hibernate,熟练掌握关系数据库理论和SQL是前提条件   

 

 
Hibernate资源
  1. 官方网站:http://www.hibernate.org   
  2. 国内网站:http://www.hibernate.org.cn   
  3. Java新视线论坛:http://forum.hibernate.org   
  4. 《Hibernate 中文开发指南》作者夏昕(http://www.redsaga.com/)   
  5. 《深入浅出Hibernate》作者:夏昕 曹晓钢 唐勇   
  6. (http://www.china-pub.com/computers/common/info.asp?id=24500)  
  7. 《Hibernate in Action》作者:Christian Bauer and Gavin King(http://www.javafan.net/可下载)  
  8. 《Hibernate: A Developer's Notebook》作者:James Elliott    
  • 第三章.rar (15.3 KB)
  • 描述: 这个能发的好短,很多代码一个帖子帖不全. 现把原PPT帖上!
  • 下载次数: 38