Hibernate框架的学习--第二天

一、 hibernate中的实体规则

   1.   实体类创建的注意事项

  1)  持久化类提供无参数构造

  2)  成员变量私有,提供共有get/set方法访问.需提供属性

  3)  持久化类中的属性,应尽量使用包装类型

  4)  持久化类需要提供oid.与数据库中的主键列对应

  5)  不要用final修饰class

  hibernate使用cglib代理生成代理对象.代理对象是继承被代理对象.如果被final修饰.将无法生成代理.

   2. 主键类型

  1)  自然主键(少见)

  表的业务列中,有某业务列符合,必须有,并且不重复的特征时,该列可以作为主键使用.

  2)  代理主键(常见)

  表的业务列中,没有某业务列符合,必须有,并且不重复的特征时,创建一个没有业务意义的列作为主键

   3.  主键生成策略

  1)  代理主键

  identity : 主键自增.由数据库来维护主键值.录入时不需要指定主键.

  sequence: Oracle中的主键生成策略.

  increment(了解): 主键自增.由hibernate来维护.每次插入前会先查询表中id最大值.+1作为新主键值.                   

  hilo(了解): 高低位算法.主键自增.由hibernate来维护.开发时不使用.

  native:hilo+sequence+identity 自动三选一策略.

  uuid: 产生随机字符串作为主键. 主键类型必须为string 类型.

  2)   自然主键

  assigned:自然主键生成策略. hibernate不会管理主键值.由开发人员自己录入.

二、 hibernate中的对象状态

  1.   对象分为三种状态

    1)  瞬时状态

    没有id,没有在session缓存中

  2)  持久化状态

    有id,在session缓存中

  3)  游离|托管状态

    有id,没有在session缓存中

  2.  三种状态的转换图

           

三、 hibernate进阶-一级缓存

  1.  缓存:提高效率.hibernate中的一级缓存也是为了提高操作数据库的效率.

  2.  提高效率手段1:提高查询效率

        

  3.  提高效率手段2:减少不必要的修改语句发送

        

四、 hibernate中的事务

  1.  事务

     1) 事务特性

     a 原子性

     c 一致性

     i 隔离性

     d 持久性

   2) 事务并发问题

    1.脏读

    2.不可重复度

    3.幻|虚读

      3) 事务的隔离级别

    1)  读未提交- 123

    2)  读已提交 - 23

    3)  可重复读(mysql默认级别)-3

    4)  串行化 - 没有问题

  2. 知识点:如何在hibernate中指定数据库的隔离级别

               

  3. 知识点2:在项目中如何管理事务

    1)  业务开始之前打开事务,业务执行之后提交事务. 执行过程中出现异常.回滚事务.

    2)   在dao层操作数据库需要用到session对象.在service控制事务也是使用session对象完成. 我们要确保dao层和service层使用的使用同一个session对象

          3)   在hibernate中,确保使用同一个session的问题,hibernate已经帮我们解决了. 我们开发人员只需要调用sf.getCurrentSession()方法即可获得与当前线程绑定的session对象

   4)  注意1: 调用getCurrentSession方法必须配合主配置中的一段配置

   

  5)  注意2:通过getCurrentSession方法获得的session对象.当事务提交时,session会自动关闭.不要手动调用close关闭.

  4. 案例中的代码实现:

        1)service层

 public class CustomerServiceImpl implements CustomerService {

    private CustomerDao customerDao = new CustomerDaoImpl();

    public void save(Customer c) {
        Session session =  HibernateUtils.getCurrentSession();
        //打开事务
        Transaction tx = session.beginTransaction();
        //调用Dao保存客户
        try {
            customerDao .save(c);
        } catch (Exception e) {
            e.printStackTrace();
            tx.rollback();
        }
        //关闭事务
        tx.commit();
    }
}

         2)dao层

      

public class CustomerDaoImpl implements CustomerDao {

    public void save(Customer c) {
        //1 获得session
        Session session = HibernateUtils.getCurrentSession();
        //3 执行保存
        session.save(c);
    }
}

五、hibernate中的批量查询(概述)

  1.   HQL查询-hibernate Query Language(多表查询,但不复杂时使用)

     Hibernate独家查询语言,属于面向对象的查询语言

          1) 基本查询

   /**
     * 基本查询
     */
    @Test
    public void fun() {
        //1. 获得session对象
        Session session = HibernateUtils.getSession();
        //2. 开启事务并获得操作事务的对象
        Transaction tx = session.beginTransaction();
        //3. 执行操作
        //1>书写hql语句
        //String hql = "from com.java.domain.Customer";
        String hql = " from Customer "; //查询所有的Customer对象
        //2>根据hql语句创建查询对象
        Query query = session.createQuery(hql);
        //3>根据查询对象获得查询结果
        List<Customer> list = query.list(); //返回list结果
        //Object result = query.uniqueResult(); //接收唯一的查询结果
        System.out.println(list);
        //4. 提交事务并释放资源
        tx.commit();
        session.close();
    }

   2)条件查询

    /**
     * 条件查询
     * HQL语句中,不出现与数据库相关的
     */
    @Test
    public void fun2() {
        //1. 获得session对象
        Session session = HibernateUtils.getSession();
        //2. 开启事务并获得操作事务的对象
        Transaction tx = session.beginTransaction();
        //3. 执行操作
        //1>书写hql语句
        //String hql = "from com.java.domain.Customer";
        String hql = " from Customer where cust_id=1l "; //查询所有的Customer对象
        //2>根据hql语句创建查询对象
        Query query = session.createQuery(hql);
        //3>根据查询对象获得查询结果
        Customer result = (Customer) query.uniqueResult(); //接收唯一的查询结果
        System.out.println(result);
        //4. 提交事务并释放资源
        tx.commit();
        session.close();
    }
  /**
     * 条件查询
     * ?占位符
     */
    @Test
    public void fun3() {
        //1. 获得session对象
        Session session = HibernateUtils.getSession();
        //2. 开启事务并获得操作事务的对象
        Transaction tx = session.beginTransaction();
        //3. 执行操作
        //1>书写hql语句
        //String hql = "from com.java.domain.Customer";
        String hql = " from Customer where cust_id=? "; 
        //2>根据hql语句创建查询对象
        Query query = session.createQuery(hql);
        //设置参数
        //query.setLong(0, 2l);
        query.setParameter(0, 2l);
        //3>根据查询对象获得查询结果
        Customer result = (Customer) query.uniqueResult(); //接收唯一的查询结果
        System.out.println(result);
        //4. 提交事务并释放资源
        tx.commit();
        session.close();
    }
   /**
     * 条件查询
     * 命名占位符
     */
    @Test
    public void fun4() {
        //1. 获得session对象
        Session session = HibernateUtils.getSession();
        //2. 开启事务并获得操作事务的对象
        Transaction tx = session.beginTransaction();
        //3. 执行操作
        //1>书写hql语句
        //String hql = "from com.java.domain.Customer";
        String hql = " from Customer where cust_id=:cust_id "; 
        //2>根据hql语句创建查询对象
        Query query = session.createQuery(hql);
        //设置参数
        query.setParameter("cust_id", 3l);
        //3>根据查询对象获得查询结果
        Customer c = (Customer) query.uniqueResult(); //接收唯一的查询结果
        System.out.println(c);
        //4. 提交事务并释放资源
        tx.commit();
        session.close();
    }

  3)分页查询

   /**
     * 分页查询
     * limit ?,?
     * query.setFirstResult(2); 
     * query.setMaxResults(2);
     */
    @Test
    public void fun5() {
        //1. 获得session对象
        Session session = HibernateUtils.getSession();
        //2. 开启事务并获得操作事务的对象
        Transaction tx = session.beginTransaction();
        //3. 执行操作
        //1>书写hql语句
        //String hql = "from com.java.domain.Customer";
        String hql = " from Customer "; //查询所有的Customer对象
        //2>根据hql语句创建查询对象
        Query query = session.createQuery(hql);
        
        //设置分页信息 limit ?,?
        query.setFirstResult(2);
        query.setMaxResults(2);
        
        //3>根据查询对象获得查询结果
        List<Customer> list = query.list();
        System.out.println(list);
        //4. 提交事务并释放资源
        tx.commit();
        session.close();
    }

  2.   Criteria查询(单表条件查询)

    Hibernate自创的无语句面向对象查询

   1)   基本查询

   /**
     * 基本查询
     */
    @Test
    public void fun1() {
        //1. 获得session对象
        Session session = HibernateUtils.getSession();
        //2. 开启事务并获得操作事务的对象
        Transaction tx = session.beginTransaction();
        //3. 执行操作
        
        //查询所有的Customer对象
        Criteria criteria = session.createCriteria(Customer.class);
        List<Customer> list = criteria.list();
        System.out.println(list);
        
        //4. 提交事务并释放资源
        tx.commit();
        session.close();
    }

  2)条件查询      

  条件查询各个条件对应Criteria的函数API
   >             gt
   >=           ge
   <         lt
   <=       le
   ==       eq
   !=        ne
   in         in
   between and between
   in         in
   like          like
   is not null    isNotNull
   is null      isNull
   or        or
   and       and

  /**
     * 条件查询
     * >                 gt
     * >=                ge
     * <                 lt
     * <=                le
     * ==                eq
     * !=                ne
     * in                in
     * between and       between
     * in                in
     * like              like
     * is not null       isNotNull
     * is null           isNull
     * or                or
     * and               and
     *
     */
    @Test
    public void fun2() {
        //1. 获得session对象
        Session session = HibernateUtils.getSession();
        //2. 开启事务并获得操作事务的对象
        Transaction tx = session.beginTransaction();
        //3. 执行操作
        
        //创建criteris对象
        Criteria criteria = session.createCriteria(Customer.class);
        //添加查询条件的参数  查询cust_id为1的Customer对象
        //criteria.add(Restrictions.eq("cust_id", 1l));
        //Customer c = (Customer) criteria.uniqueResult();
        //System.out.println(c);
        
        //查询cust_id在1和3之间的Customer对象
        criteria.add(Restrictions.between("cust_id", 1l, 3l));
        List<Customer> list = criteria.list();
        System.out.println(list);
        
        //4. 提交事务并释放资源
        tx.commit();
        session.close();
    }

  3)分页查询

  /**
     *分页查询
     *  limit ?,?
     *    criteria.setFirstResult(3);
     *    criteria.setMaxResults(3);
     */
    @Test
    public void fun3() {
        //1. 获得session对象
        Session session = HibernateUtils.getSession();
        //2. 开启事务并获得操作事务的对象
        Transaction tx = session.beginTransaction();
        //3. 执行操作
        
        //创建criteris对象
        Criteria criteria = session.createCriteria(Customer.class);
        //分页查询 limit ?,?
        criteria.setFirstResult(3);
        criteria.setMaxResults(3);
        List<Customer> list = criteria.list();
        System.out.println(list);
        
        //4. 提交事务并释放资源
        tx.commit();
        session.close();
    }

  4)聚合函数

  /**
     * 聚合函数
     * criteria.setProjection(Projections.rowCount());
     *查询总记录数
     */
    @Test
    public void fun4() {
        //1. 获得session对象
        Session session = HibernateUtils.getSession();
        //2. 开启事务并获得操作事务的对象
        Transaction tx = session.beginTransaction();
        //3. 执行操作
        
        //创建criteris对象
        Criteria criteria = session.createCriteria(Customer.class);
        //设置查询的聚合函数  总行数
        criteria.setProjection(Projections.rowCount());
        //执行查询
        Long count = (Long) criteria.uniqueResult();
        System.out.println(count);
        
        //4. 提交事务并释放资源
        tx.commit();
        session.close();
    }

  3.  原生SQL查询(复杂的业务查询)

    1)   基本查询

  /**
     * 基本查询
     */
    @Test
    public void fun1() {
        //1. 获得session对象
        Session session = HibernateUtils.getSession();
        //2. 开启事务并获得操作事务的对象
        Transaction tx = session.beginTransaction();
        //3. 执行操作
        
        //1>. 书写sql语句
        String sql = "select * from cst_customer";
        //2>. 创建sql语句的查询对象
        SQLQuery query = session.createSQLQuery(sql);
        //3>. 执行查询操作
        List<Object[]> list = query.list();
        for(Object[] objs : list) {
            System.out.println(Arrays.toString(objs));
        }
        //4. 提交事务并释放资源
        tx.commit();
        session.close();
        
    }
  /**
     * 基本查询
     * 指定将结果封装到哪个对象中去
     * query.addEntity(Customer.class);
     */
    @Test
    public void fun2() {
        //1. 获得session对象
        Session session = HibernateUtils.getSession();
        //2. 开启事务并获得操作事务的对象
        Transaction tx = session.beginTransaction();
        //3. 执行操作
        
        //1>. 书写sql语句
        String sql = "select * from cst_customer";
        //2>. 创建sql语句的查询对象
        SQLQuery query = session.createSQLQuery(sql);
        //指定将结果封装到哪个对象中去
        query.addEntity(Customer.class);
        //3>. 执行查询操作
        List<Customer> list = query.list();
        System.out.println(list);
        //4. 提交事务并释放资源
        tx.commit();
        session.close();
    }

  2)条件查询

  /**
     * 条件查询
     */
    @Test
    public void fun3() {
        //1. 获得session对象
        Session session = HibernateUtils.getSession();
        //2. 开启事务并获得操作事务的对象
        Transaction tx = session.beginTransaction();
        //3. 执行操作
        
        //1>. 书写sql语句
        String sql = "select * from cst_customer where cust_id=?";
        //2>. 创建sql语句的查询对象
        SQLQuery query = session.createSQLQuery(sql);
        //设置?占位符的参数
        query.setParameter(0, 5l);
        //指定将结果封装到哪个对象中去
        query.addEntity(Customer.class);
        
        //3>. 执行查询操作
        Customer c = (Customer) query.uniqueResult();
        System.out.println(c);
        //4. 提交事务并释放资源
        tx.commit();
        session.close();
    }

  3)分页查询

  /**
     * 分页查询
     */
    @Test
    public void fun4() {
        //1. 获得session对象
        Session session = HibernateUtils.getSession();
        //2. 开启事务并获得操作事务的对象
        Transaction tx = session.beginTransaction();
        //3. 执行操作
        
        //1>. 书写sql语句
        String sql = "select * from cst_customer limit ?,?";
        //2>. 创建sql语句的查询对象
        SQLQuery query = session.createSQLQuery(sql);
        //设置?占位符的参数
        query.setParameter(0, 2);
        query.setParameter(1, 2);
        //指定将结果封装到哪个对象中去
        query.addEntity(Customer.class);
        
        //3>. 执行查询操作
        List<Customer> list = query.list();
        System.out.println(list);
        //4. 提交事务并释放资源
        tx.commit();
        session.close();
    }
原文地址:https://www.cnblogs.com/guodong-wang/p/7471003.html