Hibernate第四阶段

Hibernate

1.Hibernate的检索方式

Hibernate提供对于对象的查询的方式

1.1Hibernate中五种查询方式

1.1.1OID检索:根据主键查询

+ session 中的get 和load方法

1.1.2对象导航检索:通过一个对象获得到其关联对象。

LinkMan linkMan = session.get(LinkMan.class,1L);Customer customer=Linkman.getCustomer();

1.1.3HQL 检索:通过编写一个HQL语句检索

1.1.3.1HQL的基本的查询,别名查询,排序查询

在创建实体类的时候,生成toString的时候,不要把两个实体都生成,要不会互相打印,形成死循环,可以去掉一个set集合

  • 查询全部
    //里面不能使用select * .
1
2
3
4
5
6
7
8
9
Query query = session.createQuery("from Customer c");  //给Customer取得别名
List<Customer> lists=query.list();
//也可以这么写
List<Customer> list=session.createQuery("select c from Customer c").list();
//HQL还支持多肽查询,查询所有Object下的持久化类
Query query=session.createQuery("from java.util.Object");
List<Object> lists=query.list();
  • 排序查询
1
2
//默认asc,可以加desc降序
List<Customer> list=session.createQuery("from Customer order by cust_id").list();
1.1.3.2HQL的条件查询
  1. 按位置绑定参数
1
2
3
4
5
6
Query query = session.createQuery("from Customer where cust_name=? and cust_id=?");
query.setParameter(0,"...");
query.setParameter(1,"...");
List<Customer> lists=query.list();
//如果确定一条结果可以用
Customer customer=(Customer) query.uniqueResult();
  1. 按名称绑定参数
1
2
3
4
5
6
Query query = session.createQuery("from Customer where cust_name=:name and cust_id=:id");
query.setParameter("name","...");
query.setParameter("id","...");
List<Customer> lists=query.list();
//如果确定一条结果可以用
Customer customer=(Customer) query.uniqueResult();
1.1.3.3HQL的分页查询
1
2
3
4
Query query = session.createQuery("from LinkMan");
query.setFirstResult(0);
query.setMAxResults(10);
List<LinkMan> lists=query.list();
1.1.3.4HQL的投影查询
  1. 查询所有的名字
1
2
Query query = session.createQuery("select cust_name from Customer");
List<String> names=query.list();
  1. 查询所有客户的id和名称
1
2
3
4
5
Query query = session.createQuery("select cust_id,cust_name from Customer");
List<Object[]> lists=query.list();
for(Object[] objects : list){
   System.out.println(Arrays.toString(objects));
}
  1. 构造查询,现在实体类中写出相应的构造方法
    //不要忘了加无参构造
1
2
Query query = session.createQuery("select new Customer(cyst_id,cust_name) from Customer");
List<Customer> lists=query.list();
1.1.3.5HQL的分组统计查询
  1. 统计个数
1
2
Query query = session.createQuery("select count(*) from Customer");
Long count=query.uniqueResult();
  1. 按名称分组统计
1
2
3
4
5
Query query = session.createQuery("select cust_name,count(*) from Customer group by cust_name");
List<Object[]> lists=query.list();
for(Object[] objects : list){
   System.out.println(Arrays.toString(objects));
}
  1. 按姓氏的名称统计个数
1
2
3
4
5
6
Query query = session.createQuery("select cust_name,count(*) from Customer where cust_name like ? group by cust_name");
query.setParameter(0,"郝%");
List<Object[]> lists=query.list();
for(Object[] objects : list){
   System.out.println(Arrays.toString(objects));
}

1.1.4QBC 检索:通过Criteria对象进行检索

1.1.4.1基本查询
1
2
Criteria criteria=session.createCriteria(Customer.class);
List<Customer> list=criteria.list();
1.1.4.2排序查询
1
2
3
Criteria criteria=session.createCriteria(Customer.class);
criteria.addOrder(Order.asc("cust_id")); //倒序换为desc即可
List<Customer> list=criteria.list();
1.1.4.3条件查询
1
Criteria criteria=session.createCriteria(Customer.class);
  • crteria.add(Restrictions.下边的值());
1
2
3
4
5
6
7
8
9
10
11
 == eq
 > gt great than
 >= ge great equal
 < lt less than
 <= le less equal
 <> ne not equal
like 模糊查询
like模糊查询还有一种方式
//MatchMode.START指的是前面的字在哪个位置
crteria.add(Restrictions.like("cust_name","郝",MatchMode.START));

//crteria.add(Restrictions.。。 可以写多个,相当于and

1.1.4.4分页查询
1
2
3
4
5
Criteria criteria=session.createCriteria(Customer.class);
crteria.add(Restrictions.like("cust_name","郝"));
crteria.setFirstResult(2);
crteria.setMaxResult(2);
List<Customer> lists=criteria.list();
1.1.4.5统计查询

setProjection 是单独值,用来设置聚集函数

1
2
3
Criteria criteria=session.createCriteria(Customer.class);
crteria.setProjection(Projections.rowCount());
Object result=criteria.uniqueResult();
1.1.4.6离线查询 DetachedCriteria

这个对象可以前期脱离session来使用,后期再绑定session。
所以可以在web层中封装好一个DetachedCriteria对象,然后传到dao中,在调用getExecutableCriteria(session); 获取一个Criteria对象使用

1.1.5SQL检索 :通过输入SQL语句进行检索

1.2 多表查询

1.2.1 SQL中连接查询

1.2.2 HQL中的连接查询

sql连接

  • 交叉连接

  • 内连接

    • 隐式内连接,显式内连接
    • 迫切内连接

      fetch可以通知Hibernate,把结果封装成一个customer对象,包括集合
      但是有一个问题:封装对象的时候会有重复的对象,所以要去重
  • 外连接

    • 左外连接
    • 右外连接
    • 迫切外连接
      跟内连接一样加一个 fetch

2.Hibernate的抓取策略

2.1Hibernate延迟加载机制

延迟加载(懒加载 lazy):指的是,当执行到这行操作的时候,不会马上与数据库进行交互,等到真正使用该对象的属性的时候,才会发送sql语句进行查询。

2.1.1类级别的延迟加载

类级别的延迟加载:查询某个类(对象)的时候,这个对象是否采用延迟。
主要体现在使用load方法查询某个对象的时候,这个对象是否采用了延迟加载(默认使用延迟加载)

  • 使类级别的延迟加载失效,跟get的效果一样:
    • 在实体类中加final
    • 在配置文件中的class标签上设置lazy属性为false

2.1.2 关联级别的延迟加载

关联级别的延迟加载:查询某个类以后,查询这个类的关联的对象的时候,关联对象是否采用延迟,默认为true是延迟加载。

  • 使关联级别的延迟加载失效:
    • 在实体类中加final
    • 在配置文件中的set标签上设置lazy属性为false

lazy上还有一个值 extra,只是在关联级别有,及其懒惰,要什么只查什么。

2.2Hibernate的抓取策略(关联关系上配置fetch属性)

抓取策略:用来查询到一个对象之后抓取其关联对象。

2.2.1set上的fetch和lazy:

fetch控制的SQL语句的格式:
lazy控制关联对象是否一致被查询

  • set集合上配置fetch属性:
    • select 默认值,普通的select查询语句
    • join 会发送一条迫切连接,将关联的信息一起查询出来,所以此时lazy会失效
    • subselect 子查询 ,用 in
  • set集合上配置lazy属性:
    • true 默认值,延迟加载
    • false 不使用延迟加载
    • extra 及其懒惰

一般情况下就用默认的,但是如果经常一查多的一方,可以fetch用join

2.2.2 many-to-one 上的fetch和lazy:

  • many-to-one集合上配置fetch属性:

    • select 默认值,普通的select查询语句
    • join 会发送一条迫切连接,将关联的信息一起查询出来,所以此时lazy会失效
  • many-to-one集合上配置lazy属性:

    • proxy 默认值,具体的取值取决于一的一方的类的fetch的值
    • false 不使用延迟加载
    • no-proxy

一般情况下就用默认的

2.3批量抓取


  • 本来是先查所有,在一个一个查查三个 发四条语句

    在set上加一个batch-size="3"; 一下查三个,共发2条语句

  • 在many-to-one上没有batch-size,需要时要在一的一方的class上配
张冲 wechat
欢迎扫一扫上面的微信关注我,一起交流!
坚持原创技术分享,您的支持将鼓励我继续创,点击打赏!