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进行多个等于的比较 gt dayu ge 大于等于 lt 小于 le 小于等于 between 对应SQL的between子句 like 对应SQl的like in 对应SQL的in and and关系 or or关系 sqlRestriction SQL限定查询 //创建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:发送迫切左外连接查询语句
- set上fetch取值
- 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
- set上lazy取值有三个
//默认情况 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配置
- 抓取少的一方时,在多的一方配置
- 抓取多的一方时,在少的一方配置