一、OID检索
**OID检索:**根据对象的主键OID进行检索
- get方法
如下所示:
User user = sesson.get(User.class,1);
- load方法
如下所示:
User user = sesson.load(User.class,1);
第三篇已经使用此方法
二、HQL检索
2.1 HQL简单查询
实例代码:
package com.hibernate.demo;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import com.hibernate.utils.HibernateUtils;
public class HibernateDemo03 {
@Test
//HQL的简单查询
public void demo01() {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
Query query = session.createQuery("from Product");
List<Product> list = query.list();
for (Product product : list) {
System.out.println(product);
}
tx.commit();
}
}
结果如下:
2.2 HQL排序查询
实例代码:
@Test
//HQL的排序查询
public void demo02() {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
//默认主键升序asc
//设置降序desc
List<Product> list = session.createQuery("from Product order by p_id desc").list();
for (Product product : list) {
System.out.println(product);
}
tx.commit();
}
结果如下:
2.3 HQL条件查询
实例代码:
@Test
//HQL的条件查询
public void demo03() {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
//按位置绑定,类似于数据库查询
// Query query = session.createQuery("from Product where p_id = ? and p_name like ?");
// query.setParameter(0, 14);
// query.setParameter(1, "C%");
// List<Product> list = query.list();
//按名称绑定
Query query = session.createQuery("from Product where p_id =:pid and p_name like:pname");
query.setInteger("pid", 14);
query.setParameter("pname", "C%");
List<Product> list = query.list();
for (Product product : list) {
System.out.println(product);
}
tx.commit();
}
结果如下:
2.4 HQL投影查询
投影查询:查询对象的某个或某些属性
实例如下:
@Test
//HQL的投影查询
public void demo04() {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
//投影查询,多个属性
// List<Object[]> list = session.createQuery("select p.p_name, p.p_price from Product p").list();
//
// for (Object[] object : list) {
// System.out.println(Arrays.toString(object));
// }
//查询多个属性,用面向对象的方式
List<Product> list = session.createQuery("select new Product(p_name, p_price) from Product p").list();
for (Product product : list) {
System.out.println(product);
}
tx.commit();
}
结果如下:
2.5 HQL分组统计查询
实例代码:
@Test
//HQL的分组统计查询
public void demo06() {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
Object object = session.createQuery("select count(*) from Product").uniqueResult();
System.out.println(object);
tx.commit();
}
结果如下:
2.6 HQL分页查询
@Test
//HQL的分页查询
public void demo05() {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
//分页查询
Query query = session.createQuery("from Product");
query.setFirstResult(0);
query.setMaxResults(3);
List<Product> list = query.list();
for (Product product : list) {
System.out.println(product);
}
tx.commit();
}
结果如下:
三、QBC检索
QBC: Query by Criiteria,条件查询。更面向对象化。
3.1 简单查询
package com.hibernate.demo;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import com.hibernate.utils.HibernateUtils;
/**
* QBC查询
* @author cf
*
*/
public class HibernateDemo04 {
@Test
//简单查询
public void demo01() {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
//获得Criteria对象
Criteria criteria = session.createCriteria(Product.class);
List<Product> list = criteria.list();
for (Product product : list) {
System.out.println(product);
}
tx.commit();
}
}
3.2 排序查询
@Test
//排序查询
public void demo02() {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
//获得Criteria对象
Criteria criteria = session.createCriteria(Product.class);
List<Product> list = criteria.addOrder(Order.desc("p_id")).list();
for (Product product : list) {
System.out.println(product);
}
tx.commit();
}
3.3 分页查询
@Test
//分页查询
public void demo03() {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
//获得Criteria对象
Criteria criteria = session.createCriteria(Product.class);
criteria.setFirstResult(0);
criteria.setMaxResults(2);
List<Product> list = criteria.list();
for (Product product : list) {
System.out.println(product);
}
tx.commit();
}
3.4 条件查询
Test
//条件查询
public void demo04() {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = se ssion.beginTransaction();
//获得Criteria对象
Criteria criteria = session.createCriteria(Product.class);
criteria.add(Restrictions.gt("p_price", new Double(300)));
List<Product> list = criteria.list();
for (Product product : list) {
System.out.println(product);
}
tx.commit();
}
3.5 统计分组查询
@Test
//统计查询
public void demo05() {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
Criteria criteria = session.createCriteria(Product.class);
/*
add : 普通的条件,where后面的条件
addOrder: 排序
setProjection: 聚合函数和group by having
*/
criteria.setProjection(Projections.rowCount());
Long num = (Long) criteria.uniqueResult();
System.out.println(num);
tx.commit();
}
3.6 离线条件查询(SSH)–DetachedCriteria
SSH中常用到
@Test
//离线条件查询
public void demo06() {
DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Product.class);
detachedCriteria.add(Restrictions.like("p_name", "C%"));
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
Criteria criteria = detachedCriteria.getExecutableCriteria(session);
List<Product> list = criteria.list();
for (Product product : list) {
System.out.println(product);
}
tx.commit();
}
四、抓取策略(优化)
4.1 延迟加载
延迟加载:lazy(懒加载),执行到改行代码时,不会发送语句去查询,只有在真正使用这个对象的属性时才会发送SQL语句进行查询
4.1.1延迟级别的分类:
(1) 类级别的延迟加载
通过load方法查询某个对象时,是否采用延迟
session.load(Product.class,1);
在映射文件的class标签上可以通过lazy设置,默认为true,开启延迟。但对关联对象无效。
<class name="com.hibernate.demo.Product" table="product" lazy="true">
(2) 关联级别的延迟加载
在查询到某个对象的时候,在查询其关联的对象的时候,是否采用延迟加载
Category category = session.get(Category.class, 1);
category.getProducts();---通过category获得产品,产品是否采用延时加载
4.2 抓取策略
*抓取策略:*通过一个对象抓取到关联对象需要发送SQL语句,SQL语句发送格式。
通过set或many-to-one标签的fetch属性设置
4.3 通过set标签优化
fetch: 抓取策略,控制SQL语句格式
- select : 默认值,发送普通的select语句,查询关联对象
- join : 发送迫切左外连接茶轩关联对象
- subselect : 发送一条自查询查询其关联对象
lazy:延迟加载,控制查询关联对象的时候是否采用延迟
- true : 默认值,查询关联对象时,采用延迟加载
- false : 查询关联对象的时候,不采用延迟加载
- extra : 极其懒惰
默认值:fetch=“select” lazy="true"
package com.hibernate.demo;
import java.util.Set;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import com.hibernate.utils.HibernateUtils;
public class HibernateDemo05 {
@Test
//默认值:fetch="select" lazy="true"
public void demo01() {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
//查询category
Category category = session.get(Category.class, 5);//发送查询category的SQL语句
System.out.println(category.getC_name());
//查询分类下的所有商品
Set<Product> products = category.getProducts();//发送根据category ID查询product的SQL语句
for (Product product : products) {
System.out.println(product);
}
tx.commit();
}
}
控制台输出:
fetch=“select” lazy="false"
@Test
//默认值:fetch="select" lazy="false"
public void demo02() {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
//查询category
Category category = session.get(Category.class, 5);//发送两条查询语句:不延迟加载
System.out.println(category.getC_name());
//查询分类下的所有商品
Set<Product> products = category.getProducts();
for (Product product : products) {
System.out.println(product);
}
tx.commit();
}
结果如下:
fetch=“select” lazy="extra"
@Test
//默认值:fetch="select" lazy="extra"
public void demo03() {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
//查询category
Category category = session.get(Category.class, 5);//发送一次查询语句
System.out.println(category.getC_name());
//查询分类下的所有商品数量
System.out.println(category.getProducts().size()); //仅发送select count(*)语句
tx.commit();
}
结果如下:
fetch=“join” lazy=“失效”,直接两个表数据全部查询
@Test
//默认值:fetch="join" lazy="失效",直接两个表数据全部查询
public void demo04() {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
//查询category
Category category = session.get(Category.class, 5);//发送一次查询语句
System.out.println(category.getC_name());
//查询分类下的所有商品数量
System.out.println(category.getProducts().size()); //仅发送select count(*)语句
tx.commit();
}
4.3 通过many-to-one标签优化
fetch: 抓取策略,控制SQL语句格式
- select : 默认值,发送普通的select语句,查询关联对象
- join : 发送迫切左外连接茶轩关联对象
lazy:延迟加载,控制查询关联对象的时候是否采用延迟
- proxy : 默认值,取决于一的一方的lazy设置
- false : 查询关联对象的时候,不采用延迟加载
- no-proxy: 不会使用
默认值:fetch=“select” lazy="proxy"
@Test
//默认值:fetch="select" lazy="proxy"
public void demo01() {
Session session = HibernateUtils.getCurrentSession();
Transaction tx = session.beginTransaction();
Product product = session.get(Product.class, 14);//发送一条查询
System.out.println(product.getP_name());
System.out.println(product.getCategory().getC_name());//发送一条查询
tx.commit();
}
fetch=“select” lazy="false"
fetch=“join” lazy=失效
合理选用fetch可以优化对数据库的访问次数,从而优化性能