Hibernate 4

Hibernate 4

检索方式

导航对象图检索

  • 根据已经加载的对象导航到其关联对象

OID检索

  • 指session的get和load方法
  • Customer c = (Customer)session.get(Customer.class,1);

HQL检索

  • 是面向对象的查询语言,与SQL语言相似,但使用的是类、对象和属性的概念,没有表和字段的概念
  • 功能
    • 在查询时设定各种查询条件
    • 支持投影查询,即仅查询出对象的部分属性
    • 支持分页查询
    • 支持分组查询
    • 提供内置聚集函数
    • 能够调用用户自定义的SQL函数
    • 支持子查询
    • 支持动态绑定参数
  • 完整HQL语句:select…from…where…group by…having…order by…asc/desc
  • 通常情况下省略select关键字
    • String hql = “from Customer”;
    • Customer是表名
    Query query = session.createQuery("select c from Customer c");
    List<Customer> list = query.list();
    //条件查询
    Query query = session.createQuery("select c from Customer c where name=?");
    quey.setParamter(0,"小王");
      //quey.setString(0,"小王");
    List<Customer> list = query.list();
    
    Query query = session.createQuery("select c from Customer c where name=:n");
    quey.setParamter("n","小王");
    quey.setParamter(0,"小王");
    Customer cust = (Customer)query.uniqueResult();
    //分页查询
    Query query = session.createQuery("from Customer order by id desc");
    query.setFirstResult(5);
    query.setMaxResults(5);
    List<Customer> list = query.list();
    
    //投影查询,即查询某一列或者某几列
    List<String> list = session.createQuery("select name,id from Customer").list();
    
  • 连接查询:from Customer c inner join c.linkMans:因为customer的linkMans的集合对应的是外键,所以这里不用写关联字段
  • 迫切连接:join后添加fetch
    • 普通连接查询结果为两个对象,如Customer对象和Customer类关联的外键对象LinkMans,所以查询结果一般为List<object []>
    • 迫切连接:Hibernate发现查询语句中有fetch时,数据被封装到Customer对象c,关于其外键对象的数据则被封装到c中的联系人集合中
    • 所以主要区别在封装的数据上
    • 迫切连接封装后会出现重复数据,可以使用distinct去掉重复值
      List<Customer> list = session.createQuery("select distinct c from Customer c inner join fetch c.linkMans").list()

QBC检索

  • 主要由Criter接口、Criterion接口和Expression类组成

    • Criter接口由session创建
    • Criterion是查询条件
    • Restrictions对象用来编写查询条件
    Restriction静态方法说明
    eq等于
    allEq使用Map,使用key/value进行多个等于的比较
    gtdayu
    ge大于等于
    lt小于
    le小于等于
    between对应SQL的between子句
    like对应SQl的like
    in对应SQL的in
    andand关系
    oror关系
    sqlRestrictionSQL限定查询
      //创建criteria对象
      Criteria criteria = session.createCriteria(Customer.class);
      //设定查询条件
      Critertion critertion = Restrictions.eq("id",1);
      Restrictions.like("name","%小%");
      //添加查询条件
      criteria.add(critertion);
      //执行查询并返回查询结果
      List<Customer> cs = criteria.list()
    
      //分页查询时
      criteria.setFirstResult(5);
      criteria.setMaxResults(5);
      //排序查询
      criteria.addOrder(Order.desc("id"));//asc
    
      //统计查询
      criteria.setProjection(Projections.rowCount())
      Long count = (Long)criteria.uniqueResult();
    
    
  • 离线条件检索:detachedCriteria,可以脱离session的一种条件查询(SSH整合时经常使用)

    DetachedCriteria dc = DetachedCriteria.forClass(Customer.class);
    dc.add(Restrictions.eq("cust_name","小明"));
    //离线查询与session绑定
    List<Customer> list = dc.getExcutableCriteria(session).list()
    

SQL检索

  • 内查询:select … from 表1 [inner] join 表2 on 表1.字段=表2.字段
  • 外连接:Left或者Right
  • 迫切连接:join后添加fetch

查询优化

抓取策略

  • 指查询的时候如何抓取其关联对象
  • 是提升性能的一种手段,可以在获取关联对象的时候,对发送的语句进行优化,往往抓取策略和延迟加载一起使用
  • 在关联对象的标签上配置fetch属性
    • set上fetch取值
      • select:默认值,发送普通select语句
      • join:发送迫切左外连接查询
      • subselect:发送子查询语句
    • many-to-one取值
      • select:默认值,发送普通查询语句
      • join:发送迫切左外连接查询语句
  • fetch设置为join,lazy会失效

延迟加载

  • 可以避免无无谓的开销,在真正需要数据的时候才进行数据加载操作
  • 分为两类:类级别延迟和关联级别延迟
    • 类级别延迟:查询某个对象的时候,是否采用延迟,在class标签上配置lazy,默认为true
    • 关联级别延迟:查询一个对象的关联对象的时候是否采用延迟加载,在<set>或<many-to-one>上配置lazy属性,
      • set上lazy取值有三个
        • true:默认值
        • false
        • extra:极其懒惰
      • many-to-one上lazy取值有三个
        • proxy:默认值,是否采用延迟加载取决于一的一方的lazy属性的值
        • false
        • no-proxy
    //默认情况
    Customer cust = session.get(Customer.class,1l);//1条select
    customer.getLinkMans.size();//1条select
    
    //<set>fetch="select",lazy="false"
    Customer cust = session.get(Customer.class,1l);//两条查询语句
    customer.getLinkMans.size();//不发送查询语句
    
    //fetch = "select",lazy="extra"
    Customer cust = session.get(Customer.class,1l);//一条select
    customer.getLinkMans.size();//一条count
    
    //fetch="join",lazy失效
    Customer cust = session.get(Customer.class,1l);//一条迫切左外连接查询两个对象
    customer.getLinkMans.size();//不
    
    //fetch="subselect" lazy="true"
    List<Customer> list = session.createQuery("from Customer").list();//发送查询所有客户
    for(Customer customer:list){
      customer.getLinkMans().size();//发送子查询
    }
    
    //fetch="subselect" lazy="false"
    List<Customer> list = session.createQuery("from Customer").list();//发送查询所有客户及子查询
    for(Customer customer:list){
      customer.getLinkMans().size();//不发送子查询
    }
    

批量抓取

  • set上通过batch-size=num配置
  • 抓取少的一方时,在多的一方配置
  • 抓取多的一方时,在少的一方配置
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值