检索策略
1.检索(查询)方式:
- 立即检索:当查询数据,马上执行查询select语句
- 延迟检索:当执行查询,但只到需要时再查询。
优化:减少当时对数据库访问压力。
hibernate实现,必须使用代理类进行增强。
2.检索策略
- 类级别:查询当前对象,除了OID,其他的字段是否延迟。
- 关联级联:查询当前前对象,需要获得关联对象时,是否进行延迟。
3.查询方法,类级别
- get() 类级别,立即检索。如果查询数据不存在,将返回null
- load() 类级别,默认延迟检索。如果查询数据不存在,将抛异常
- hbm.xml <class name="" table="" lazy="">
true: 默认值,延迟检索
false:立即检索
4.关联级别:
一对多或 多对多: 多方存在容器(集合Set)
- <set lazy="" fetch="">
lazy: false/true/extra
lazy="false" 所有select立即查询。
lazy="true" 与关联对象select 只有当需要是才查询。
lazy="extra" 极其懒惰,如果可以使用聚合函数完成功能,就不进行详细查询。
fetch: join/select/subselect
fetch="join" 底层使用迫切左外连接,只执行一个select语句,底层使用左外连接。
fetch="select" 默认,将执行多条select语句
fetch="subselect" 将执行子查询,注意:需要使用Query查询
检索策略:多对一或一对一
1.介绍:<many-to-one fetch="" lazy="">
- fetch取值:join、select
fetch="join" ,将采用迫切左外连接,lazy无效。 将采用一条select,查询所有需要的数据。
fetch="select" 将执行多条select语句 - lazy取值:false、proxy、no-proxy
lazy="false"立即,当查询订单,同时再查询客户,使用多条select语句
lazy="proxy" 订单使用客户的数据,客户何时初始化,取决客户的类级别检索策略。
lazy="no-proxy" 不研究
Customer.hbm.xml
<class name="cn.itcc...Customer" lazy="true"> 延迟
<class name="cn.itcc...Customer" lazy="false"> 立即
2.示例:
①修改Order.hbm.xml
<!-- 多对一:多个订单 属于 一个客户 -->
<many-to-one name="customer" class="Customer" column="customer_id" fetch="join" ></many-to-one>
②api操作
@Test
public void demo03() {
// 查询订单,如何初始化客户数据
Session session = factory.openSession();
session.beginTransaction();
//1 查询订单
Order order = (Order) session.get(Order.class, 1);
//2 获得客户
Customer customer = order.getCustomer();
System.out.println(customer.getCname());
session.getTransaction().commit();
session.close();
}
检索(查询)方式总结
HQL:hibernate查询语句,类似与sql语句
QBC: query by criteria hibernate提供纯面向对象查询语句,没有任何sql影子。
1.查询所有
@Test
public void demo01(){
Session session = factory.openSession();
session.beginTransaction();
//1 HQL ,使用对象
List<Customer> allCustomer = session.createQuery("from Customer").list();
//2 sql,使用表 ,通过addEntity设置如何封装数据
//List<Customer> allCustomer = session.createSQLQuery("select * from t_customer").addEntity(Customer.class).list();
//3 QBC
//List<Customer> allCustomer = session.createCriteria(Customer.class).list();
//打印
for (Customer customer : allCustomer) {
System.out.println(customer);
}
session.getTransaction().commit();
session.close();
}
2.固定值条件查询
@Test
public void demo02(){
//固定条件值查询
// * uniqueResult()将查询唯一结果,如果没有返回null,如果结果大于1将抛异常。
Session session = factory.openSession();
session.beginTransaction();
//1 HQL
Customer customer = (Customer) session.createQuery("from Customer c where c.cname = 'rose' ").uniqueResult();
//2 sql
//Customer customer = (Customer) session.createSQLQuery("select * from t_customer where cname='rose'").addEntity(Customer.class).uniqueResult();
//3 QBC
/*
Customer customer = (Customer) session.createCriteria(Customer.class)
.add(Restrictions.eq("cname", "rose"))
.uniqueResult();
*/
//打印
System.out.println(customer);
session.getTransaction().commit();
session.close();
}
3.排序
@Test
public void demo03(){
//排序 ,mysql语法 : select ... order by 字段名 asc|desc
// * asc :升序 , desc:降序
Session session = factory.openSession();
session.beginTransaction();
//1 HQL ,使用对象
List<Customer> allCustomer = session.createQuery("from Customer c order by c.cid desc").list();
//2 sql,使用表 ,通过addEntity设置如何封装数据
//List<Customer> allCustomer = session.createSQLQuery("select * from t_customer c order by c.cid desc").addEntity(Customer.class).list();
//3 QBC , hibernate 提供Order对象进行排序, desc(属性名称)方法降序, asc(属性名称)方法升序
/*
List<Customer> allCustomer = session.createCriteria(Customer.class)
.addOrder(org.hibernate.criterion.Order.desc("cid"))
.list();
*/
//打印
for (Customer customer : allCustomer) {
System.out.println(customer);
}
session.getTransaction().commit();
session.close();
}
4.分页
@Test
public void demo04(){
//分页,mysql格式: select ... limit 开始索引,每页显示个数
// hibernate分页,提供 setFirstResult() 设置开始索引, setMaxResults() 设置每页显示个数
Session session = factory.openSession();
session.beginTransaction();
//1 HQL ,使用对象
List<Customer> allCustomer = session.createQuery("from Customer")
.setFirstResult(0)
.setMaxResults(2)
.list();
//2 sql,使用表 ,通过addEntity设置如何封装数据
/*
List<Customer> allCustomer = session.createSQLQuery("select * from t_customer")
.addEntity(Customer.class)
.setFirstResult(0)
.setMaxResults(2)
.list();
*/
//3 QBC
/*
List<Customer> allCustomer = session.createCriteria(Customer.class)
.setFirstResult(0)
.setMaxResults(2)
.list();
*/
//打印
for (Customer customer : allCustomer) {
System.out.println(customer);
}
session.getTransaction().commit();
session.close();
}
5.绑定参数
@Test
public void demo05(){
/* 绑定参数
* 方式1:占位符? ,使用?替换实际参数
* setXxx(int,Object) , 第一参数int,表示?索引号,从0开始。
* 例如:setString(0,"rose")
* 方式2:别名格式 “:名称”
* setXxx(String,Object) ,第一个参数String,表示之前进行命名
* 例如:setString("别名","rose")
*/
Session session = factory.openSession();
session.beginTransaction();
//1 HQL
Customer customer = (Customer) session.createQuery("from Customer c where c.cname = ? ").setString(0, "rose").uniqueResult();
// Customer customer = (Customer) session.createQuery("from Customer c where c.cname = :xxx ").setString("xxx", "rose").uniqueResult();
//2 sql
/*
Customer customer = (Customer) session.createSQLQuery("select * from t_customer where cname=?")
.addEntity(Customer.class)
.setString(0, "rose")
.uniqueResult();
*/
//3 QBC 不变
/*
Customer customer = (Customer) session.createCriteria(Customer.class)
.add(Restrictions.eq("cname", "rose"))
.uniqueResult();
*/
//打印
System.out.println(customer);
session.getTransaction().commit();
session.close();
}
6.聚合函数
@Test
public void demo06(){
/* 聚合函数
*/
Session session = factory.openSession();
session.beginTransaction();
//1 HQL count(*) , count(c)
Object obj = session.createQuery("select count(c) from Customer c").uniqueResult();
//2 sql
//Object obj = session.createSQLQuery("select count(*) from t_customer").uniqueResult();
//3 QBC 不变
/*
Object obj = session.createCriteria(Customer.class)
.setProjection(Projections.projectionList().add(Projections.rowCount()))
.uniqueResult();
*/
//打印
System.out.println(obj);
session.getTransaction().commit();
session.close();
}
7.分组
@Test
public void demo07(){
/* 分组
*/
Session session = factory.openSession();
session.beginTransaction();
//1 HQL count(*) , count(c)
Object obj = session.createQuery("select c.cname from Customer c group by c.cname").list();
//2 sql
//Object obj = session.createSQLQuery("select c.cname from t_customer c group by c.cname").list();
//3 QBC 不变
/*
Object obj = session.createCriteria(Customer.class) .setProjection(Projections.projectionList().add(Projections.groupProperty("cname")))
.list();
*/
//打印
System.out.println(obj);
session.getTransaction().commit();
session.close();
}
8.投影
@Test
public void demo08(){
//查询部分数据:投影查询
Session session = factory.openSession();
session.beginTransaction();
//1 HQL , 默认情况,如果查询一列,将封装Object,如果查询多列,将封装Object[]
// * 可以通过构造方法进行对象创建,从而将数据封装到指定对象中,例如:new Customer(cname)
List<Customer> allCustomer = session.createQuery("select new Customer(cname) from Customer").list();
//2 sql,使用表 ,通过addEntity设置如何封装数据
// * 设置结果集转换,按照查询别名和对象属性对应赋值
/*
List<Customer> allCustomer = session.createSQLQuery("select cname from t_customer")
.setResultTransformer(new AliasToBeanResultTransformer(Customer.class))
.list();
*/
//3 QBC
/* Projections.projectionList() 设置查询的列表 , select ... from
* Projections.alias() 设置别名
* Projections.property("cname") 确定使用属性
List<Customer> allCustomer = session.createCriteria(Customer.class) .setProjection(Projections.projectionList().add(Projections.alias(Projections.property("cname"), "cname")))
.setResultTransformer(new AliasToBeanResultTransformer(Customer.class))
.list();
*/
//打印
for (Customer customer : allCustomer) {
System.out.println(customer);
}
session.getTransaction().commit();
session.close();
}
命名查询
- 将hql语句存放配置文件
- 之后通过session.getNamedQuery("名称")
- getNamedQuery("名称") <hibernate-mapping><query name="名称">
- getNamedQuery("类全路径.名称") <hibernate-mapping><class name="类全路径"><query name="名称">
@Test
public void demo10(){
//命名查询:将hql或sql语句,存放配置文件中,之后通过给语句起一个名称,在代码通过名称执行
Session session = factory.openSession();
session.beginTransaction();
//1 HQL
List<Customer> allCustomer = session.getNamedQuery("findAllCustomer").list();
//打印
for (Customer customer : allCustomer) {
System.out.println(customer + ", 订单数: " + customer.getOrderSet().size());
}
session.getTransaction().commit();
session.close();
}