Hibernate之二

Hibernate之稍稍进阶

一、持久化类概述

  1. 什么是持久化类?
    • 持久化:讲内存中的一个对象持久化到数据库中的过程,Hibernate框架就是用来进行持久化的框架.
    • 持久化类:一个Java对象与数据库建立了映射关系,那么这个类在Hibernate中被称为持久化类。
  2. 持久化类的编写规则
    1. 对持久化类提供一个无参的构造方法
      • Hibernate底层需要使用反射生成实例
    2. 属性需要私有,对私有属性提供public的 get和set方法
      • Hibernate中获取,设置对象的值
    3. 对持久化类提供一个唯一标识ID与数据库主键对应
      • Java中通过对象的地址区分是否是同一个对象,数据库中通过主键确定是否是同一个记录,在Hibernate中通过持久类的ID的属性区分是否是同一个对象。
    4. 持久化类的属性尽量使用包装类类型,因为基本的数据类型默认是0 ,那么0 就有很多的歧义。包装类的类型,默认值是null
    5. 持久化类不要使用final进行修饰
      • 延迟加载本身是Hibernate的一个优化的手段,返回的是一个代理对象(javassist可以对没有实现接口的类产生代理,使用了非常底层的字节码增强技术,继承这个类进行代理)。如果不能被继承,不能产生代理对象,延迟加载也就失效了。
  3. 持久化类的三种状态
    • 瞬时态:不被session管理且在数据库中没有没有关联的记录,且没有唯一标识ID
    • 持久态:在瞬时态的基础上被session所管理,并且有了唯一标识的ID
    • 托管态:在持久态的基础之上,被session释放就变成了持久态对象
    @Test
    //三种状态的区分区分
    public void test01() {
        Session session = HibernateUtils.getSession();
        Transaction transaction = session.beginTransaction();
        Book book = new Book();
        book.setBname("我是一个天才!"); //瞬时态对象:没有设置id
        session.save(book); //持久态对象:有ID 且被管理
        transaction.commit();
        session.close();
        System.out.println(book);//瞬时态对象:session已经关闭,且有ID
    }
    

二、再谈主键

  1. 主键的分类

    在数据库中,主键被分为自然主键以及代理主键,自然主键是指主键的本身就是表中的一个字段,比如人口信息表中,身份证是唯一的,就可以当做主键,这就被称为自然主键;代理主键是指主键的本省不是表中的一个字段,而是自己添加的一个主键。前边的Book表所使用的就是代理主键。在开发中应尽量使用代理主键,因为方便以后修改。

  2. 主键的生成策略
    • 在配置持久化类与数据库表之间的映射的时候,需要配置主键的生成策略,Hibernate提供了很多的主键生成策略,下边举例一些比较常用的主键生成策略。
      • increment:Hibernate中提供的自动增长机制,使用short、int、 long类型的主键,在单线程的程序中使用。
      • identity:适用于short、int、long类型的主键,使用的是数据库底层的自动增强机制,适用于有自动增强机制的数据库。
      • sequence:使用与short、int、long类型的主键,采用的是序列化的方式。
      • uuid:使用与字符串类型的主键,使用hibernate中随机的方式生成字符串的主键。
      • native:本地策略,可以在identity和sequence之间进行自动切换。
      • assigned:Hibernate放弃外键的管理,需要通过手动编写代码或者用户自己设置主键。
      • foreign:外部的。一对一的一种关系映射的情况下使用。

三、Hibernate的关联映射

  • 一对多

在这里插入图片描述

  • 多对多

在这里插入图片描述

  • 一对一

在这里插入图片描述

  • 级联操作
    • 未开启级联操作的代码:

      @Test
      // 保存2个客户  和 3个联系人  并且建立好关系
      public void demo1(){
          Session session = HibernateUtils.getCurrentSession();
          Transaction tx = session.beginTransaction();
          // 创建两个客户
          Customer customer1 = new Customer();
          customer1.setCust_name("張三");
          Customer customer2 = new Customer();
          customer2.setCust_name("李四");
          // 创建三个联系人
          LinkMan linkMan1 = new LinkMan();
          linkMan1.setLkm_name("凤姐");
          LinkMan linkMan2 = new LinkMan();
          linkMan2.setLkm_name("如花");
          LinkMan linkMan3 = new LinkMan();
          linkMan3.setLkm_name("旺财");
          // 设置关系:
          linkMan1.setCustomer(customer1);
          linkMan2.setCustomer(customer1);
          linkMan3.setCustomer(customer2);
          customer1.getLinkMans().add(linkMan1);
          customer1.getLinkMans().add(linkMan2);
          customer2.getLinkMans().add(linkMan3);
          // 保存数据:
          session.save(linkMan1);
          session.save(linkMan2);
          session.save(linkMan3);
          session.save(customer1);
          session.save(customer2);
          tx.commit();
      }
      
    • 开启级联操作之后:

    @Test
    /**
    *  级联保存或更新操作:
    *  * 保存客户级联联系人,操作的主体是客户对象,需要在Customer.hbm.xml中进行配置
    *  * <set name="linkMans" cascade="save-update">
    */
    public void demo3(){
        Session session = HibernateUtils.getCurrentSession();
        Transaction tx = session.beginTransaction();
        Customer customer = new Customer();
        customer.setCust_name("赵洪");
        LinkMan linkMan = new LinkMan();
        linkMan.setLkm_name("如花");
        customer.getLinkMans().add(linkMan);
        linkMan.setCustomer(customer);
        session.save(customer);
        tx.commit();
    }
    
    • 级联:操作一个对象的时候,是否会同时操作其关联的对象。开启级联操作之后,可以简化代码,避免很多重复的代码。
    • 开启级联的方法,在持久化类的配置文件中开启:
    <!-- casade:开启级联操作 -->
    <set name="linkMans" cascade="save-update">
    ...
    </set>
    

四、查询

  1. OID查询

    Hibernate根据对象的OID(主键)进行检索

    • 使用get方法:
    Customer customer = session.get(Customer.class,1l);
    
    • 使用load方法:
    Customer customer = session.load(Customer.class,1l);
    
  2. HQL

    HQL查询:Hibernate Query Language,Hibernate的查询语言,是一种面向对象的方式的查询语言,语法类似SQL。通过session.createQuery(),用于接收一个HQL进行查询方式。

    • 简单查询
    @Test
    public void demo2() {
        Session session = HibernateUtils.getCurrentSession();
        Transaction tx = session.beginTransaction();
        // 简单的查询
        Query query = session.createQuery("from Customer");
        List<Customer> list = query.list();
        for (Customer customer : list) {
            System.out.println(customer);
        }
        tx.commit();
    }
    
    • 别名查询
    @Test
    public void demo3() {
        Session session = HibernateUtils.getCurrentSession();
        Transaction tx = session.beginTransaction();
        List<Customer> list = session.createQuery("from Customer c").list;
        for (Customer customer : list) {
            System.out.println(customer);
        }
        tx.commit();
    }
    
    • 排序查询
    public void demo4() {
        Session session = HibernateUtils.getCurrentSession();
        Transaction tx = session.beginTransaction();
        List<Customer> list = session.createQuery("from Customer order by cust_id").list();
        List<Customer> list = session.createQuery("from Customer order by cust_id desc").list();
        for (Customer customer : list) {
            System.out.println(customer);
        }
        tx.commit();
    }
    
    • 条件查询
    @Test
    public void demo5() {
        Session session = HibernateUtils.getCurrentSession();
        Transaction tx = session.beginTransaction();
        // 一、按位置绑定:根据参数的位置进行绑定。
    	Query query = session.createQuery( "from Customer where cust_source = ? and cust_name like ?");
    	query.setParameter(0, "小广告"); query.setParameter(1, "李%");
    	 List<Customer> list = query.list();
        // 二、按名称绑定
        Query query = session.createQuery("from Customer where cust_source = :aaa and cust_name like :bbb");
        query.setParameter("aaa", "朋友推荐");
        query.setParameter("bbb", "李%");
        List<Customer> list = query.list();
        for (Customer customer : list) {
            System.out.println(customer);
        }
        tx.commit();
    }
    
    • 投影查询
    @Test
    public void demo6() {
        Session session = HibernateUtils.getCurrentSession();
        Transaction tx = session.beginTransaction();
        List<Customer> list = session.createQuery("select new Customer(cust_name,cust_source) from Customer").list();
        for (Customer customer : list) {
            System.out.println(customer);
        }
        tx.commit();
    }
    
    • 分页查询
    @Test
    public void demo7() {
        Session session = HibernateUtils.getCurrentSession();
        Transaction tx = session.beginTransaction();
        Query query = session.createQuery("from LinkMan");
        query.setFirstResult(20);
        query.setMaxResults(10);
        List<LinkMan> list = query.list();
        for (LinkMan linkMan : list) {
            System.out.println(linkMan);
        }
        tx.commit();
    }
    
    • 统计查询
    @Test
    public void demo8() {
        Session session = HibernateUtils.getCurrentSession();
        Transaction tx = session.beginTransaction();
        // 聚合函数的使用:count(),max(),min(),avg(),sum()
        Object object = session.createQuery("select count(*) from Customer").uniqueResult();
        System.out.println(object);
        // 分组统计:
        List<Object[]> list = session.createQuery("select cust_source,count(*) from Customer group by cust_source")
            .list();
        for (Object[] objects : list) {
            System.out.println(Arrays.toString(objects));
        }
        tx.commit();
    }
    
  3. QBC

    QBC查询:Query By Criteria,条件查询。是一种更加面向对象化的查询的方式。

    • 简单查询
    @Test
    public void demo1(){
        Session session = HibernateUtils.getCurrentSession();
        Transaction tx = session.beginTransaction();
        // 获得Criteria的对象
        Criteria criteria = session.createCriteria(Customer.class);
        List<Customer> list = criteria.list();
        for (Customer customer : list) {
            System.out.println(customer);
        }
        tx.commit();
    }
    
    • 排序查询
    @Test
    public void demo2(){
        Session session = HibernateUtils.getCurrentSession();
        Transaction tx = session.beginTransaction();
        Criteria criteria = session.createCriteria(Customer.class);
        criteria.addOrder(Order.asc("cust_id")); // 升序
        criteria.addOrder(Order.desc("cust_id")); // 降序
        List<Customer> list = criteria.list();
    
        for (Customer customer : list) {
            System.out.println(customer);
        }
    
        tx.commit();
    }
    
    • 分页查询
    @Test
    public void demo3(){
        Session session = HibernateUtils.getCurrentSession();
        Transaction tx = session.beginTransaction();
        // 分页查询
        Criteria criteria = session.createCriteria(LinkMan.class);
        criteria.setFirstResult(10);
        criteria.setMaxResults(10);
        List<LinkMan> list = criteria.list();
        for (LinkMan linkMan : list) {
            System.out.println(linkMan);
        }
        tx.commit();
    }
    
    • 条件查询
    @Test
    /**
    	 * 条件查询
    	 */
    public void demo4(){
        Session session = HibernateUtils.getCurrentSession();
        Transaction tx = session.beginTransaction();
        // 条件查询
        Criteria criteria = session.createCriteria(Customer.class);
        // 设置条件:
        /**
    		 * =   eq
    		 * >   gt
    		 * >=  ge
    		 * <   lt
    		 * <=  le
    		 * <>  ne
    		 * like
    		 * in
    		 * and
    		 * or
    		 */
        criteria.add(Restrictions.eq("cust_source", "小广告"));
    	criteria.add(Restrictions.or(Restrictions.like("cust_name", "李%")));
        criteria.add(Restrictions.like("cust_name", "李%"));
        List<Customer> list = criteria.list();
        for (Customer customer : list) {
            System.out.println(customer);
        }
        tx.commit();
    }
    
    • 统计查询
    @Test
    public void demo5(){
        Session session = HibernateUtils.getCurrentSession();
        Transaction tx = session.beginTransaction();
    
        Criteria criteria = session.createCriteria(Customer.class);
        /**
    		 * add				:普通的条件。where后面条件
    		 * addOrder			:排序
    		 * setProjection	:聚合函数 和 group by having
    		 */
        criteria.setProjection(Projections.rowCount());
        Long num = (Long) criteria.uniqueResult();
        System.out.println(num);
        tx.commit();
    }
    
    • 离线条件查询(SSH)—DetachedCriteria
    @Test
    public void demo6(){
        DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Customer.class);
        detachedCriteria.add(Restrictions.like("cust_name", "李%"));
        Session session = HibernateUtils.getCurrentSession();
        Transaction transaction = session.beginTransaction();
        Criteria criteria = detachedCriteria.getExecutableCriteria(session);
        List<Customer> list = criteria.list();
        for (Customer customer : list) {
            System.out.println(customer);
        }
        transaction.commit();
    }
    
  4. SQL
    @Test
    public void demo1(){
        Session session = HibernateUtils.getCurrentSession();
        Transaction tx = session.beginTransaction();
        /*SQLQuery sqlQuery = session.createSQLQuery("select * from cst_customer");
    		List<Object[]> list = sqlQuery.list();
    		for (Object[] objects : list) {
    			System.out.println(Arrays.toString(objects));
    		}*/
        SQLQuery sqlQuery = session.createSQLQuery("select * from cst_customer");
        sqlQuery.addEntity(Customer.class);
        List<Customer> list = sqlQuery.list();
        for (Customer customer : list) {
            System.out.println(customer);
        }
        tx.commit();
    }
    

注:以上内容为观看Hibernate总结

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值