zoukankan      html  css  js  c++  java
  • HQL查询 忆江南

      HQL 是非常有意识的被设计为完全面向对象的查询,它可以理解如继承、多态和关联之类的概念,简化了SQL语句的编写,除了类跟属性以外,本身对大小写并不敏感。但嵌入到java代码中,小写可观性更好些。下面介绍些HQL的常见用法:

      以下面的User和Role为测试对象:

    User类:

    View Code
     1 public class User {
    2
    3 private int user_id ;
    4
    5 private String user_name ;
    6
    7 private String password ;
    8
    9 private Date add_date;
    10
    11 private Set<Role> roles = new HashSet<Role>();
    12
    13 public User(){} ;
    14
    15 public User(int user_id,String user_name ,String password ,Date add_date){
    16
    17 this.user_id = user_id ;
    18 this.user_name = user_name;
    19 this.password = password ;
    20 this.add_date = add_date ;
    21 }
    22 //set和get方法省略
    23
    24 }

    User.hbm.xml:

    View Code
     1 <?xml version="1.0"?>
    2 <!DOCTYPE hibernate-mapping PUBLIC
    3 "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    4 "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    5
    6 <hibernate-mapping package="model">
    7 <class name="User" table="sy_user">
    8 <id name="user_id" column="user_id">
    9 <generator class="native"/>
    10 </id>
    11 <property name="user_name"/>
    12 <property name="password"/>
    13 <property name="add_date"/>
    14 <set name="roles" table="user_role">
    15 <key column="user_id" not-null="true"/>
    16 <many-to-many class="Role" column="role_id" />
    17 </set>
    18 </class>
    19 </hibernate-mapping>

    Role类:

    View Code
     1 public class Role {
    2
    3 private int role_id ;
    4
    5 private String role_name ;
    6
    7 private String DESCRIPE ;
    8
    9 //get和set方法省略
    10 }

    Role.hbm.xml:

    View Code
     1 <?xml version="1.0"?>
    2 <!DOCTYPE hibernate-mapping PUBLIC
    3 "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    4 "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    5
    6 <hibernate-mapping package="model">
    7 <class name="Role" table="sy_role">
    8 <id name="role_id" column="role_id">
    9 <generator class="native"/>
    10 </id>
    11 <property name="role_name"/>
    12 <property name="DESCRIPE"/>
    13 </class>
    14 </hibernate-mapping>
    1.   from 子句
    View Code
    1 from User as user           //as可以省略  返回User的所有实例
    2
    3 from User user ,Role role //同时出现多个类,其查询结果是产生一个笛卡儿积或产生跨表的连接

     2.    join 连接  

    我们可以为相关联的实体甚至是对一个集合中的全部元素指定一个别名,这时要使用关键字 join

     join 分为:join、left join 、right join 、full join

    View Code
    1 /自动用条件on 关联   fetch抓取 把role同时查询出来,但并不会放入结果集中,只是可以通过User可以得到role数据,不会因session关闭抛异常
    2 String hql = "select user from User user join fetch user.roles role " +
    3 "where user.user_id = :user_id" ;
    4 List<User> rolesList = session.createQuery(hql)
    5 .setInteger("user_id", user_id)
    6 .list();

    注意: 使用 iterate() 来调用查询 ,fetch 构造是不能使用的 ,fetch 也不应该与 setMaxResults()setFirstResult() 共用,这是因为这些操作是基于结果集的,而在预先抓取集合类时可能包含重复的数据,也就是说无法预先知道精确的行数.

    使用 full join fetchright join fetch 是没有意义的。

    如果你使用属性级别的延迟获取(lazy fetching)(这是通过重新编写字节码实现的),可以使用  fetch all properties来强制 Hibernate 立即取得那些原本需要延迟加载的属性:

    View Code
    1 from Document fetch all properties order by name

    HQL 支持两种关联 join 的形式:implicit(隐式)explicit(显式)

    显式 :就是form 子句中明确给出了 join 关键字。这是建议使用的方式。

    隐式: 形式不使用 join 关键字。关联使用"点号"来进行“引用”。如:

    View Code
    1 select user from user where User.roles.role_name like 'ro%' ;

    3.select 子句:

    select 子句选择将哪些对象与属性返回到查询结果集中 。 如:

    View Code
    1 select role from User user join user.roles role //  只返回用户拥有的role的属性。可以简写:
    2 select user.roles from User user

    查询语句可以返回多个对象和(或)属性,存放在 Object[]队列中,查询结果返回Object[]:

    select user.user_id ,user.user_name ,user.password ,role 
    from User user join user.role


    也可以存放在list中,查询结果返回List:

    select new List(user.user_id ,user.user_name ,user.password ,role )     
         from User user join user.role 


    若对象有符合类型的构造方法,也可以存在自定义对象中,查询结果返回User对象:

    View Code
    1 String hql = "select new User(user.user_id , user.user_name ,user.password ,user.add_date) " +
    2 "from User user where user.user_id = :user_id" ;
    3 User user = (User) session.createQuery(hql)
    4 .setInteger("user_id",user_id)
    5 .uniqueResult() ;

    可以使用关键字 as 给“被选择了的表达式”指派别名:

    select count(user.user_id) as count from User user 

    这种做法在与子句 select new map 一起使用时最有用:

    select new map( max(user_id) as max, min(user_id) as min, count(*) as n )
    from User user
    该查询返回了一个 Map 的对象,内容是别名与被选择的值组成的名-值映射。
    4.分组函数:
    avg(...), sum(...), min(...), max(...) count(*) count(...), count(distinct ...), count(all...) ...为属性
    可以在选择子句中使用数学操作符、连接以及经过验证的 SQL 函数:
    select '用户名:'||user.user_name from User user
    5.多态查询
    Hibernate 可以在 from 子句中指定任何 Java 类或接口。查询会返回继承了该类的所有持久化子类的实例或返回声明了该接口的所有持久化类的实例
    select user.user_name from User user
    这个将会查询出所有继承了User类的对象的user_name属性,实现接口也是一样的。

    6.where 子句
    from Cat cat where cat.mate.name is not null
    该查询将被翻译成为一个含有表连接(内连接)的 SQL 查询
    7. 表达式
     在 where 子句中允许使用的表达式包括 大多数可以在 SQL 使用的表达式种类:
    • 数学运算符 +,-,*,/

    • 二进制比较运算符 =, >=, <=, <>, !=, like

    • 逻辑运算符 and,or,not

    • 括号 ( ),表示分组 

    • in, not in, between, is null, is not null, is empty, is not empty, member of and not member of

    • "Simple" case, case ... when ... then ... else ... end, and "searched" case, case when ... then ... else ... end

    • 字符串连接符 ...||... or concat(...,...)

    • current_date(), current_time(), and current_timestamp()

    • second(...)minute(...)hour(...)day(...)month(...)year(...)

    • EJB-QL 3.0 定义的任何功能或操作符:substring(), trim(), lower(), upper(), length(), locate(), abs(), sqrt(), bit_length(), mod()

    • coalesce()nullif()

    • str() 把数字或者时间值转换为可读的字符串

    • cast(... as ...),其第二个参数是某 Hibernate 类型的名字,以及 extract(... from ...),只要 ANSI cast() 和  extract() 被底层数据库支持

    • HQL index() 函数,作用于 join 的有序集合的别名。

    • HQL 函数,把集合作为参数:size(), minelement(), maxelement(), minindex(), maxindex(),还有特别的 elements()indices 函数,可以与数量词加以限定:some, all, exists, any, in。 

    • 任何数据库支持的 SQL 标量函数,比如 sign(), trunc(), rtrim(), sin()

    • JDBC 风格的参数传入 ?

    • 命名参数 :name:start_date:x1

    • SQL 直接常量 'foo', 69, 6.66E+2, '1970-01-01 10:00:01.0'

    • Java public static final 类型的常量 eg.Color.TABBY

    关键字 inbetween 可按如下方法使用: 

    from DomesticCat cat where cat.name between 'A' and 'B'
    from DomesticCat cat where cat.name in ( 'Foo', 'Bar', 'Baz' )
    而且否定的格式也可以如下书写: 
    from DomesticCat cat where cat.name not between 'A' and 'B'
    from DomesticCat cat where cat.name not in ( 'Foo', 'Bar', 'Baz' )
    同样,子句 is nullis not null 可以被用来测试空值(null)。 

    在 Hibernate 配置文件中声明 HQL“查询替代(query substitutions)”之后,布尔表达式(Booleans)可以在其他表达式中轻松的使用: 

    <property name="hibernate.query.substitutions">true 1, false 0</property>
    系统将该 HQL 转换为 SQL 语句时,该设置表明将用字符 1 和  0 来取代关键字 truefalse
    from Cat cat where cat.alive = true
    你可以用特殊属性 size,或是特殊函数 size() 测试一个集合的大小。 
    from Cat cat where cat.kittens.size > 0
    from Cat cat where size(cat.kittens) > 0
    对于索引了(有序)的集合,你可以使用 minindex 与  maxindex 函数来引用到最小与最大的索引序数。同理,你可以使用 minelementmaxelement 函数来引用到一个基本数据类型的集合中最小与最大的元素。例如:
    from Calendar cal where maxelement(cal.holidays) > current_date
    from Order order where maxindex(order.items) > 100
    from Order order where minelement(order.items) > 10000
    在传递一个集合的索引集或者是元素集(elementsindices 函数)或者传递一个子查询的结果的时候,可以使用 SQL 函数 any, some,all, exists, in
    select mother from Cat as mother, Cat as kit
    where kit in elements(foo.kittens)
    select p from NameList list, Person p
    where p.name = some elements(list.names)
    from Cat cat where exists elements(cat.kittens)
    from Player p where 3 > all elements(p.scores)
    from Show show where 'fizard' in indices(show.acts)
    注意,在 Hibernate3 中,这些结构变量 —  sizeelementsindicesminindexmaxindexminelementmaxelement — 只能在 where 子句中使用。 

    一个被索引过的(有序的)集合的元素(arrays,lists,maps)可以在其他索引中被引用(只能在 where 子句中): 

    from Order order where order.items[0].id = 1234
    select person from Person person, Calendar calendar
    where calendar.holidays['national day'] = person.birthDay
    and person.nationality.calendar = calendar
    select item from Item item, Order order
    where order.items[ order.deliveredItemIndices[0] ] = item and order.id = 11
    select item from Item item, Order order
    where order.items[ maxindex(order.items) ] = item and order.id = 11
    [] 中的表达式甚至可以是一个算数表达式:
    select item from Item item, Order order
    where order.items[ size(order.items) - 1 ] = item
    对于一个一对多的关联(one-to-many association)或是值的集合中的元素,HQL 也提供内建的 index() 函数。
    select item, index(item) from Order order
    join order.items item
    where index(item) < 5
    如果底层数据库支持标量的 SQL 函数,它们也可以被使用:
    from DomesticCat cat where upper(cat.name) like 'FRI%'
    8.order by 子句
    查询返回的列表(list)可以按照一个返回的类或组件(components)中的任何属性(property)进行排序:
    from DomesticCat cat
    order by cat.name asc, cat.weight desc, cat.birthdate
    9.group by 子句
    一个返回聚集值(aggregate values)的查询可以按照一个返回的类或组件(components)中的任何属性(property)进行分组:  
    
    
    select cat.color, sum(cat.weight), count(cat)
    from Cat cat
    group by cat.color
    having cat.color in (eg.Color.TABBY, eg.Color.BLACK)
    10. 子查询
    Hibernate 支持在查询中使用子查询。一个子查询必须被圆括号包围起来
    from Cat as cat
    where not exists (
    from Cat as mate where mate.mate = cat
    )
    11.Row value 构造函数语法
    通常指的是多值(multi-valued)的比较
    from Cat as cat
    where not ( cat.name, cat.color ) in (
    select cat.name, cat.color from DomesticCat cat
    )
    
    
    from Person p where p.name=('John', 'Jingleheimer-Schmidt')
    决定是否使用这个语法的一件因素就是:这个查询将依赖于元数据里的组件子属性(sub-properties)的顺序。
  • 相关阅读:
    mysql命令行备份数据库
    js关闭当前页面的几种方式
    Linux添加FTP用户并设置权限
    在Activity的Title中加入进度条
    android例子程序(ApiDemo)的简单分类整理
    使用WindowManager窗口管理员,把View显示在屏幕中间
    android手动调用振动器(Vibrator)
    android 监听SDCard安装和卸载的代码片段(测试通过)
    android Paint和Color类介绍 使用示例
    GC_EXTERNAL_ALLOC freed 与 GC_EXPLICIT freed 是什么?
  • 原文地址:https://www.cnblogs.com/taxuewuhen/p/2295321.html
Copyright © 2011-2022 走看看