袁艺

个人站

欢迎来到我的个人站~


Hibernate入门(四)

hibernate检索方式分类

  • 导航对象图检索方式
  • OID检索方式
  • HQL检索方式
  • QBC检索方式
  • SQL检索方式

对象图导航检索

根据已经加载的对象,导航到他的关联对象。利用类与类的关系来检索对象。

例子:

查找一个联系人对应的客户,就可以由联系人对象自动导航到联系人所属的客户对象,前提是必须在对象关系映射文件上配置了多对一关系

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

OID检索

主要指用session的get方法和load方法加载某条记录对应的对象

例子:

LinkMan linkMan = (LinkMan) session.get(LinkMan.class,1);
LinkMan linkMan = (LinkMan) session.load(LinkMan.class,1);

HQL基础语法总结

hql使用的是类、对象、属性的概念,没有表和字段的概念

功能:

  • 在查询语句中设定各种查询条件
  • 支持投影查询,即仅检索出对象的部分属性
  • 支持分页查询
  • 支持分组查询,允许使用group by 和having关键字
  • 提供内置聚集函数,如:sum()、min()和max()
  • 能够调用用户定义的sql函数
  • 支持子查询
  • 支持动态绑定参数

基本检索

@Test
    public void demo04(){
        Session session=HibernateUtils.getCurrentSession();
        Transaction tx=session.beginTransaction();
        //基本查询
        Query query=session.createQuery("from SysUser");
        List<SysUser> list = query.list();

        for (SysUser user : list) {
            System.out.println(user);
        }
        tx.commit();
    }

排序检索

@Test
    public void demo05(){
        Session session=HibernateUtils.getCurrentSession();
        Transaction tx=session.beginTransaction();
        //
        Query query=session.createQuery("from SysUser order by userId desc");
        List<SysUser> list = query.list();

        for (SysUser user : list) {
            System.out.println(user.toString());
        }
        tx.commit();
    }

条件检索

 @Test
    public void demo06(){
        Session session=HibernateUtils.getCurrentSession();
        Transaction tx=session.beginTransaction();
        //按位置绑定参数
        Query query=session.createQuery("from SysUser where userName = ?");
        query.setParameter(0,"敖哈哈");
        List<SysUser> list = query.list();

        for (SysUser user : list) {
            System.out.println(user.toString());
        }
        //按名称绑定参数
        Query query1=session.createQuery("from SysUser where userName = :username");
        query1.setParameter("username","袁嘻嘻");
        SysUser user= (SysUser) query1.uniqueResult();
        System.out.println(user.toString());
        tx.commit();
    }

分页检索

@Test
    public void demo07() {
        Session session = HibernateUtils.getCurrentSession();
        Transaction tx = session.beginTransaction();
        Query query = session.createQuery("from SysUser ");
        query.setFirstResult(0);
        query.setMaxResults(5);
        List<SysUser> list = query.list();

        for (SysUser user : list) {
            System.out.println(user.toString());
        }
        tx.commit();
    }

统计检索

Query query = session.createQuery("select count(*) from SysUser ");
Long num=(Long)query.uniqueResult();

投影检索

@Test
    public void demo08() {
        Session session = HibernateUtils.getCurrentSession();
        Transaction tx = session.beginTransaction();
        //投影查询一列
        Query query = session.createQuery("select userName from SysUser ");
        List<String> list = query.list();
        for (String user : list) {
            System.out.println(user);
        }

        //投影查询多列
        List<Object[]> list1=session.createQuery("select userName,userId from SysUser").list();
        for (Object[] o : list1) {
            System.out.println(Arrays.toString(o));
        }
        

        //使用构造方法查询,前提是类中必须有这个构造方法
        List<SysUser> list2=session.createQuery("select new SysUser(userId,userName) from SysUser").list();
        for (SysUser user : list2) {
            System.out.println(user.toString());
        }
        tx.commit();
    }

连接查询

  • 交叉连接

  • 内连接

    • 显示内连接:from Customer c inner join c.linkMans

    • 隐式内连接

    • 迫切内连接:from Customer c inner join fetch c.linkMans

      fetch作用:
      在封装数据的时候,普通内连接会将属于客户的数据封装到Customer中,会将属于联系人的数据封装到LinkMan中,所以每条记录都会是两个对象的集合,所以在封装后的数据是List<Object[]>;添加了fetch之后,将数据封装到一个对象中,把属于联系人的部分封装到了customer中的联系人集合中,List<Customer>,会出现重复数据最好加上distinct
      
  • 外连接

    • 左外连接
    • 迫切左外连接
    • 右外连接

QBC检索

qbc是使用Restrictions对象编写查询条件的,常用方法如下:

41

抓取策略

抓取策略是当应用程序需要在关联关系间进行导航的时候,hibernate如何获取关联对象的策略。

hibernate的抓取策略是hibernate提升性能的一种手段,可以在获取关联对象的时候,对发送的语句进行优化,但往往抓取策略需要和延迟加载一起使用

  • set标签上的fetch三个取值
    • select:默认值,发送的是普通的select语句查询
    • join:发送一条迫切左外连接查询
    • subselect:发送一条子查询语句查询其关联对象
  • many-to-one标签上fetch的两个取值
    • select:默认值,发送的是普通的select语句查询
    • join:发送一条迫切左外连接查询

fetch如果设置为join,lazy就会失效了

延迟加载分类

  • 类级别延迟:查询某个对象的时候,是否采用有延迟,这个时候通常在class标签上配置lazy属性
  • 关联级别延迟:查询一个对象的关联对象的时候是否采用延迟加载,通常在set标签或者many-to-one上配置lazy属性
    • set标签上的lazy通常有三个取值
      • true:默认值,采用延迟加载
      • false:检索有关对象的时候,不适用延迟加载
      • extra:及其懒惰
    • many-to-one标签上的lazy的三个取值
      • proxy:默认值,是否采用延迟取决于一的一方类上的lazy属性的值
      • false:检索有关对象的时候,不采用延迟加载
      • no-proxy:

批量抓取

当要查询所有客户批量抓取联系人的时候,在set标签上配置batch-size属性;

当要查询所有联系人,批量抓取客户的时候,在客户类的class标签杀手给你配置batch-size属性