zoukankan      html  css  js  c++  java
  • 7.Hibernate 检索

    1.Hibernate检索方式

    检索方式简介:

    导航对象图检索方式:
    根据已经加载的对象,导航到其他对象。
    OID检索方式:
    按照对象的OID来检索对象。Session 的 get() 和 load() 方法提供了这种功能。

    HQL检索方式:
    使用面向对象的HQL查询语言。
    QBC检索方式:
    使用QBC(Query By Criteria)API来检索对象。这种API封装了基于字符串形式的查询语句,提供了更加面向对象的接口。
    本地SQL检索方式:
    使用本地数据库的SQL查询语句。

    HQL简介:

    HQL是一种面向对象的查询语言,和SQL查询语言有些类似。
    在Hibernate提供的各种检索方式中,HQL是使用最广的一种检索方式。
    Query接口是HQL查询接口,提供各种查询功能。

    HQL实体检索:

    where 子句。
    where 子句中给出的是类的属性名而不是数据库表字段名,其中属性名必须区分大小写。

    String hql = "from User where userName='张三'";
    Query query = session.createQuery(hql);
    List userList = query.list();

    HQL支持的各种运算符:

    程序中指定的连接类型

    HQL运算符

    比较运算符

    =、<>、>=、<=、>、<、is null、is not null

    范围运算符

    in、not in、between…and、not between…and

    字符串模式匹配运算符

    like

    逻辑运算符

    and、or、not

    HQL使用别名查询:

    HQL检索一个类的实例时,如果查询语句的其它地方需要引用它,可以给类指定一个别名。
    as 关键字用来指定别名,as 关键字也可以省略。

    from User where userName='张三'
    from User as u where u.userName='张三'
    from User u where u.userName='张三'

    HQL支持多态查询:

    多态查询指查询出当前类以及所有子类的实例。
    Employee 有两个子类:HourlyEmployee 和 SalariedEmployee。

    Query query 
        = session.createQuery("from Employee");
    List employeeList = query.list();

    HQL检索单个对象:

    HQL查询返回结果方法:
    list():返回List类型的查询结果,返回所有满足条件的对象。
    uniqueResult():返回单个对象。

    Query query = session.createQuery("from User u
                          where u.userName='张三'");
    User user = (User)query.uniqueResult();

    HQL分组与排序:

    order by 字句:

    from User u order by u.userName
    from User u order by u.userName desc
    from User u order by u.userName, u.id desc

    group by 子句:

    select count(u) from User u group by u.age 

    having子句:

    select count(u) from User u group 
    by u.age having count(u)<4 

    HQL参数绑定:

    前述HQL中查询参数均直接在HQL中表达。

    String hql 
        = "from User as u where u.userName='张三'";
    String hql 
        = "from User as u where u.userName =" + name;

    缺陷:
    代码更加零乱,可读性降低;
    难以进行性能优化;
    引入额外的安全风险。

    在HQL查询语句中按照参数位置绑定参数。
    setParameter() 参数位置从0开始。

    String hql = "from User u where u.userName=?";
    Query query = session.createQuery(hql);
    query.setParameter(0, "张三");
    List<User> userList = query.list();

    在HQL查询语句中按参数名称绑定参数。

    String hql = "from User u 
            where u.userName=:name";
    Query query = session.createQuery(hql);
    query.setParameter("name", "张三");
    List<User> userList = query.list();

    HQL的绑定参数方法:
    setParameter() 绑定任意类型的参数。
    setProperties() 用于把命名参数与一个对象的属性值绑定,并且参数名称要与对象属性名称一致。

    HQL实体更新:

    不使用HQL的实体更新;

    Transaction tx = session.beginTransaction();
    User user = (User) session.get(User.class, 1);
    user.setUserName("Tom");
    tx.commit();

    HQL实现实体更新的方式。

    Transaction tx = session.beginTransaction();
    String hql = "update User set userName='Tom' 
            where id=2"; 
    Query query = session.createQuery(hql);
    int ret = query.executeUpdate();
    tx.commit();

    HQL实体删除:

    Transaction tx = session.beginTransaction();
    String hql = "delete from User where id = 1";
    Query query  = session.createQuery(hql);
    int ret = query.executeUpdate();
    tx .commit();

    HQL子查询:

    HQL支持在 where 子句中嵌入子查询语句,并且子查询语句必须放在括号内。
    查询订单数量大于0的所有用户:

    from User u 
    where 0<(select count(o) from u.orderSet o)

    对应的SQL语句:

    select * from user u 
    where 0<(select count(o) from orders o 
             where u.id=o.userId )

    HQL子查询说明以下几点:
    子查询分为相关子查询和无关子查询;
    相关子查询:子查询语句引用了外层查询语句定义的别名。
    无关子查询:子查询语句没有引用外层查询语句定义的别名。
    HQL子查询功能依赖于底层数据库对子查询的支持;
    HQL子查询返回的是多条记录,使用以下关键字量化。
    all、any、some、in、exists。

    如果HQL子查询的是集合,HQL提供了一组操作集合的函数。
    size(),获得集合中元素的个数;
    maxIndex(),对于建立索引的集合,获得最大索引值;
    minIndex(),对于建立索引的集合,获得最小索引值;
    elements(),获得集合中所有元素。

    HQL分页查询:

    做批量查询时,如果数据量很大就需要分页功能,HQL提供了用于分页查询的方法:
    setFirstResult(int firstResult)—设定从哪个对象开始检索。
    setMaxResult(int maxResult)—设定一次检索对象的数目。

    HQL引用查询 :

    引用查询指在映射文件中定义查询语句。
    在O/R映射xml文件中,用与<calss>元素同级的<query name="XXX">元素定义一个HQL查询语句。

    <query name="findUser">from User</query>

    程序中通过session.getNamedQuery("XXX")调用对应的HQL。

    Query query 
        = session.createNamedQuery("findUser",
                                   User.class);
    List userList = query.list();

    Qauery By Criteria(QBC) 可以看作是传统SQL的对象化表示。
    它主要由Criteria接口,Criterion接口,Expression类组成。

    QBC表达式:

    检索姓名为 Erica 的所有用户。

    Criteria criteria=session.createCriteria(User.class);
    Criterion c1= Restrictions.eq("userName", "张三");
    criteria.add(c1);
    List result = criteria.list();

    步骤:
    调用 Session 的 createCriteria() 创建 Criteria 实例;
    通过 Restrictions 设定查询条件;
    调用 Criteria 实例的 list() 方法执行查询。

    运算类型

    方法

    描述

    比较运算符

    Restrictions.eq

    等于

    Restrictions.ne

    不等于

    Restrictions.gt

    大于

    Restrictions.ge

    大于等于

    Restrictions.lt

    小于

    Restrictions.le

    小于等于

    Restrictions.isNull

    等于空值

    Restrictions.isNotNull

    非空值

    运算类型

    方法

    描述

    范围运算符

    Restrictions.in

    等于列表中的某个值

    Restrictions.not(Restrictions.in)

    不等于列表中的任意值

    Restrictions.between

    大于等于值1小于等于值2

    字符串模糊匹配

    Restrictions.like

    字符串模糊匹配 like

    逻辑运算符

    Restrictions.and

    逻辑与

    Restrictions.or

    逻辑或

    Restrictions.not

    逻辑非

    本地SQL查询:

    HQL 和 QBC 查询,Hibernate 会生成标准的 SQL 语句适合不同的数据库平台。
    有时需要根据底层数据库生成特殊的 SQL 查询语句, Hibernate 对本地 SQL 查询提供了内置支持。

    查询所有的用户信息:

    String sql = "select * from  user";
    NativeQuery query = session.createNativeQuery(sql, 
        User.class);
    List list = query.list();

    步骤:
    调用session.createNativeQuery()创建NativeQuery实例,并指定查询的实体类型;
    调用NativeQuery实例的list() 方法执行查询(如果查询单个对象,调用uniqueResult() )。

    2.Hibernate检索策略

    检索策略:

    立即检索:立即加载检索方法指定的对象。
    加载多于需要的对象白白浪费内存空间;
    select 语句数量多,频繁访问数据库,影响系统性能。
    延迟检索:延迟加载检索方法指定的对象。
    避免多加载应用程序不需要访问的数据对象。

    迫切左外连接检索:利用SQL外连接查询功能加载检索方法指定对象。
    减少执行select语句的数量,减少数据库访问,提高系统性能。

    检索执行分析:

    Query query = session.createQuery("from User");
    List userList = query.list();

    Hibernate在执行检索方法时,要获取以下两种信息:
    类级别的检索策略:Hibernate检索方法指定的检索对象(User)的检索策略;
    关联级别的检索策略:与检索方法指定的检索对象相关联的对象(Order)的检索策略。

    类级别和关联级别可选的检索策略:

    检索策略的作用域

    可选的检索策略

    默认的检索策略

    影响到的检索方法

    类级别

    立即检索

    立即检索

    (除Session的load()默认延迟检索)

    影响Session的load()方法

    延迟检索

    关联级别

    立即检索

    默认延迟检索

    影响所有检索方法

    延迟检索

    迫切左外连接检索

    影响session的load()和get()方法


    三种检索策略的运行机制:

    检索策略类型

    类级别

    关联级别

    立即检索

    立即加载 检索方法指定的对象

    立即加载与检索方法指定的对象相关联的对象

    延迟检索

    延迟加载 检索方法指定的对象

    延迟加载与检索方法指定的对象相关联的对象

    迫切左外连接

    <class name="User" table="USER" lazy="false">

    检索

    不适

    User user = session.load(User.class, 
                             new Integer(1));

    通过左外连接加载与检索方法指定的对象相关联的对象

    类级别检索策略:

    立即检索(加载):映射配置文件中<class>元素的 lazy 属性设置为 false。

    <class name="User" table="USER" lazy="false">

    延迟检索(加载):映射配置文件中<class>元素的 lazy 属性设置为 true。

    <class name="User" table="USER" lazy="true">

    立即检索:

    立即检索
    Hibernate立即执行 "select* from user where id=1" 。

    延迟检索:

    User user = session.get(User.class, 
                            new Integer(1));

    延迟检索
    创建 User 的代理类实例(代理类是 Hibernate 动态生成的User的扩展类);
    Hibernate 创建的 User 代理类的实例仅仅初始化了 OID 属性,其他属性均为 null;
    当程序第一次访问代理类实例时(比如user.getX()),Hibernate会初始化代理类实例,执行 select 语句;
    如果程序访问 User 的 getId() 方法时,Hibernate并不会初始化代理类实例,因为 id 值已经存在。

    类级别的检索策略只会影响到 Session 的 load() 方法,对 get() 和其它查询不起作用。
    延迟加载对 load() 方法的影响:
    如果数据库中不存在对应的对象不会抛出异常,只有在调用 user.getXX() 时才会抛异常;
    代理类实例只能在当前 Session 范围内初始化;
    Hibernate.initialize() 方法可以显示初始化代理类实例。

    关联级别检索策略:

    Hibernate需要确定以下检索策略:
    User 类级别的检索策略;
    User 一对多关联的Order对象的检索策略,User.hbm.xml 中<set>元素 lazy 和 outer-join 属性。

    在映射文件中用 <set>元素 来配置 一对多 和 多对多 关联关系。

    lazy

    outer-join

    检索策略

    flase

    false

    立即检索策略。

    false

    true

    迫切左外连接检索,在配置文件中如果有多个<set>元素,只允许一个设置 outer-join=true。

    true

    false

    Order order = session.get(Order.class, 
                            new Integer(1));

    延迟加载,优先考虑的检索策略。

    true

    true

    迫切左外连接检索。

    关联级别检索策略-多对一

    Hibernate需要确定以下检索策略:
    Order 类级别的检索策略;
    Order 多对一关联的 User 对象检索策略,Order.hbm.xml 中 <many-to-one>元素 outer-join 属性和 User.hbm.xml 中<class>元素的 lazy 属性。

    Order order = session.get(Order.class, 
                            new Integer(1));

    关联级别检索策略 - 多对一 和 一对一

    在映射文件中用 <many-to-one>元素 和 <one-to-one>元素 来分别设置多对一和一对一关联关系。
    <many-to-one>元素的 outer-join 属性:
    auto、true、false三种取值。

    关联级别检索策略 - 多对一

    <many-to-one>元素的outer-join属性值

    对应one方<class>元素的lazy属性值

    检索many方(Orders)对象时,对关联的one方(Users)对象的检索策略

    auto

    false

    迫切左外连接检索

    auto

    true

    延迟检索

    true

    true or false

    迫切左外连接检索

    false

    false

    立即检索

    false

    true

    延迟检索

    使用注解配置检索策略

    fetch 参数可以设置为 FetchType.LAZY 或者 FetchType.EAGER。
    EAGER:通过 outer join select 直接获取关联的对象。
    LAZY(默认值):在第一次访问关联对象的时候才会触发相应的 select 操作。

  • 相关阅读:
    机器人能都返回原点
    解码字母
    学习W3C
    字符重排
    字符串相加
    ARC107F Sum of Abs
    6830. 【2020.10.25提高组模拟】排列
    6828. 【2020.10.25提高组模拟】幂
    CF1434D Roads and Ramen
    2020 计蒜之道 线上决赛 C 攀登山峰
  • 原文地址:https://www.cnblogs.com/Firesun/p/9869551.html
Copyright © 2011-2022 走看看