JavaWeb - Hibernate框架使用(二)

hibernate中的实体(Entity)类规则

  • 实体类创建的注意事项

    1. 持久化类提供无参数构造
    2. 成员变量私有,提供共有get/set方法访问.需提供属性
    3. 持久化类中的属性,应尽量使用包装类型
    4. 持久化类需要提供oid.与数据库中的主键列对应
    5. 不要用final修饰class
      hibernate使用cglib代理生成代理对象.代理对象是继承被代理对象.如果被final修饰.将无法生成代理.
  • 主键类型

    1. 自然主键(少见)
      表的业务列中,有某业务列符合,必须有,并且不重复的特征时,该列可以作为主键使用.
    2. 代理主键(常见)
      表的业务列中,没有某业务列符合,必须有,并且不重复的特征时,创建一个没有业务意义的列作为主键
  • 主键生成策略(7种)

    1. 代理主键
      • identity : 主键自增.由数据库来维护主键值.录入时不需要指定主键.
      • sequence: Oracle中的主键生成策略.
      • increment(了解): 主键自增.由hibernate来维护.每次插入前会先查询表中id最大值.+1作为新主键值.
      • hilo(了解): 高低位算法.主键自增.由hibernate来维护.开发时不使用.
      • native:hilo+sequence+identity 自动三选一策略.
      • uuid: 产生随机字符串作为主键. 主键类型必须为string 类型.
    2. 自然主键
      • assigned:自然主键生成策略. hibernate不会管理主键值.由开发人员自己录入.

hibernate中的对象状态

  • 对象分为三种状态

    1. 瞬时状态:没有id,没有在session缓存中
    2. 持久化状态:有id,在session缓存中
    3. 游离|托管状态:有id,没有在session缓存中
  • 三种状态的转换图

JavaWeb - Hibernate框架使用(二)_第1张图片
hibernate中的对象状态

hibernate进阶 - 一级缓存

  • 缓存

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

  • 提高查询效率

JavaWeb - Hibernate框架使用(二)_第2张图片
提高效率手段1
  • 减少不必要的修改语句发送

JavaWeb - Hibernate框架使用(二)_第3张图片
提高效率手段2
  • 代码测试
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test;
import domain.Customer;
import utils.HibernateUtils;
//测试一级缓存
public class Demo {
    @Test
    //证明一级缓存存在
    public void fun1(){
        //1 获得session
        Session session = HibernateUtils.openSession();
        //2 控制事务
        Transaction tx = session.beginTransaction();
        //3执行操作
        Customer c1 = session.get(Customer.class, 1l);
        Customer c2 = session.get(Customer.class, 1l);
        Customer c3 = session.get(Customer.class, 1l);
        Customer c4 = session.get(Customer.class, 1l);
        Customer c5 = session.get(Customer.class, 1l);
        System.out.println(c3==c5);//true
        //4提交事务.关闭资源
        tx.commit();
        session.close();// 游离|托管 状态, 有id , 没有关联
    }
    @Test
    //
    public void fun2(){
        //1 获得session
        Session session = HibernateUtils.openSession();
        //2 控制事务
        Transaction tx = session.beginTransaction();
        //3执行操作
        Customer c1 = session.get(Customer.class, 1l);
        c1.setCust_name("哈哈");
        c1.setCust_name("嘿嘿");
        //4提交事务.关闭资源
        tx.commit();
        session.close();// 游离|托管 状态, 有id , 没有关联
    }
    @Test
    //持久化状态对象其实就是放入session缓存中的对象
    public void fun3(){
        //1 获得session
        Session session = HibernateUtils.openSession();
        //2 控制事务
        Transaction tx = session.beginTransaction();
        //3执行操作
        Customer c1 = new Customer();
        c1.setCust_id(1l);//托管|游离
        session.update(c1);//c1被放入session缓存了
        Customer c2 = session.get(Customer.class, 1l);
        //4提交事务.关闭资源
        tx.commit();
        session.close();// 游离|托管 状态, 有id , 没有关联
    }
}

hibernate中的事务

  • 事务

    1. 事务特性(ACID)
      a 原子性(Atomicity)
      c 一致性(Consistency)
      i 隔离性(Isolation)
      d 持久性(Durability)

    2. 事务并发问题

      1. 脏读
      2. 不可重复度
      3. 幻|虚读

      更新丢失(lost update):当系统允许两个事务同时更新同一数据是,发生更新丢失。
      脏读(dirty read):当一个事务读取另一个事务尚未提交的修改时,产生脏读。
      不可重复读取(nonrepeatableread):同一查询在同一事务中多次进行,由于其他提交事务所做的修改或删,每次返回不同的结果集,此时发生不可重复读取。
      幻像(phantom read):同一查询在同一事务中多次进行,由于其他提交事务所做的插入操作,每次返回不同的结果集,此时发生幻像读。

    3. 事务的隔离级别
      读未提交- 123
      读已提交 - 23
      可重复读(mysql默认级别)-3
      串行化 - 没有问题

  • 如何在hibernate中指定数据库的隔离级别

在Hibernate主配置文件hibernate.cfg.xml中:


    
        ...
         
         4
         
         thread
        ...
    

  • 在项目中如何管理事务

    1. 业务(Service层)开始之前打开事务,业务执行之后提交事务. 执行过程中出现异常.回滚事务.
    2. 在dao层操作数据库需要用到session对象.在service控制事务也是使用session对象完成. 我们要确保dao层和service层使用的使用同一个session对象
    3. 在hibernate中,确保使用同一个session的问题,hibernate已经帮我们解决了. 我们开发人员只需要调用sessionFactory.getCurrentSession()方法即可获得与当前线程绑定的session对象
    4. 注意1: 调用getCurrentSession方法必须配合主配置中的一段配置
      thread
    5. 注意2: 通过getCurrentSession方法获得的session对象.当事务提交时,session会自动关闭.不要手动调用close关闭.

hibernate中的批量查询(概述)

  • HQL查询-Hibernate Query Language

多表查询,但不复杂时使用,Hibernate独家查询语言,属于面向对象的查询语言

  1. 基本查询
  2. 条件查询
    ?号占位符
    命名占位符
  3. 分页查询

测试代码

import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;
import domain.Customer;
import utils.HibernateUtils;
//测试HQL语句
public class Demo {
    @Test
    //基本查询
    public void fun1(){
        //1 获得session
        Session session = HibernateUtils.openSession();
        //2 控制事务
        Transaction tx = session.beginTransaction();
        //3执行操作
        //-------------------------------------------
        //1> 书写HQL语句
//      String hql = " from domain.Customer ";
        String hql = " from Customer "; // 查询所有Customer对象
        //2> 根据HQL语句创建查询对象
        Query query = session.createQuery(hql);
        //3> 根据查询对象获得查询结果
        List list = query.list(); // 返回list结果
        //query.uniqueResult();//接收唯一的查询结果
        System.out.println(list);
        //-------------------------------------------
        //4提交事务.关闭资源
        tx.commit();
        session.close();// 游离|托管 状态, 有id , 没有关联
    }
    @Test
    //条件查询
    //HQL语句中,不可能出现任何数据库相关的信息的
    public void fun2(){
        //1 获得session
        Session session = HibernateUtils.openSession();
        //2 控制事务
        Transaction tx = session.beginTransaction();
        //3执行操作
        //-------------------------------------------
        //1> 书写HQL语句
        String hql = " from Customer where cust_id = 1 "; // 查询所有Customer对象
        //2> 根据HQL语句创建查询对象
        Query query = session.createQuery(hql);
        //3> 根据查询对象获得查询结果
        Customer c = (Customer) query.uniqueResult();
        System.out.println(c);
        //-------------------------------------------
        //4提交事务.关闭资源
        tx.commit();
        session.close();// 游离|托管 状态, 有id , 没有关联
    }
    @Test
    //条件查询
    //问号占位符
    public void fun3(){
        //1 获得session
        Session session = HibernateUtils.openSession();
        //2 控制事务
        Transaction tx = session.beginTransaction();
        //3执行操作
        //-------------------------------------------
        //1> 书写HQL语句
        String hql = " from Customer where cust_id = ? "; // 查询所有Customer对象
        //2> 根据HQL语句创建查询对象
        Query query = session.createQuery(hql);
        //设置参数
        //query.setLong(0, 1l);
        query.setParameter(0, 1l);
        //3> 根据查询对象获得查询结果
        Customer c = (Customer) query.uniqueResult();
        System.out.println(c);
        //-------------------------------------------
        //4提交事务.关闭资源
        tx.commit();
        session.close();// 游离|托管 状态, 有id , 没有关联
    }
    @Test
    //条件查询
    //命名占位符
    public void fun4(){
        //1 获得session
        Session session = HibernateUtils.openSession();
        //2 控制事务
        Transaction tx = session.beginTransaction();
        //3执行操作
        //-------------------------------------------
        //1> 书写HQL语句
        String hql = " from Customer where cust_id = :cust_id "; // 查询所有Customer对象
        //2> 根据HQL语句创建查询对象
        Query query = session.createQuery(hql);
        //设置参数
        query.setParameter("cust_id", 1l);
        //3> 根据查询对象获得查询结果
        Customer c = (Customer) query.uniqueResult();
        System.out.println(c);
        //-------------------------------------------
        //4提交事务.关闭资源
        tx.commit();
        session.close();// 游离|托管 状态, 有id , 没有关联
    }
    @Test
    //分页查询
    public void fun5(){
        //1 获得session
        Session session = HibernateUtils.openSession();
        //2 控制事务
        Transaction tx = session.beginTransaction();
        //3执行操作
        //-------------------------------------------
        //1> 书写HQL语句
        String hql = " from Customer  "; // 查询所有Customer对象
        //2> 根据HQL语句创建查询对象
        Query query = session.createQuery(hql);
        //设置分页信息 limit ?,?
        query.setFirstResult(1);
        query.setMaxResults(1);
        //3> 根据查询对象获得查询结果
        List list =  query.list();
        System.out.println(list);
        //-------------------------------------------
        //4提交事务.关闭资源
        tx.commit();
        session.close();// 游离|托管 状态, 有id , 没有关联
    }
}
  • Criteria查询

单表条件查询时使用方便,Hibernate自创的无语句面向对象查询
测试代码:

import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.junit.Test;
import domain.Customer;
import utils.HibernateUtils;
//测试Criteria查询
public class Demo {
    @Test
    //基本查询
    public void fun1(){
        //1 获得session
        Session session = HibernateUtils.openSession();
        //2 控制事务
        Transaction tx = session.beginTransaction();
        //3执行操作
        //-------------------------------------------
        //查询所有的Customer对象
        Criteria criteria = session.createCriteria(Customer.class);
        List list = criteria.list();
        System.out.println(list);
//      Customer c = (Customer) criteria.uniqueResult();
        //-------------------------------------------
        //4提交事务.关闭资源
        tx.commit();
        session.close();// 游离|托管 状态, 有id , 没有关联
    }
    @Test
    //条件查询
    //HQL语句中,不可能出现任何数据库相关的信息的
    // >                gt
    // >=               ge
    // <                lt
    // <=               le
    // ==               eq
    // !=               ne
    // in               in
    // between and      between
    // like             like
    // is not null      isNotNull
    // is null          isNull
    // or               or
    // and              and
    public void fun2(){
        //1 获得session
        Session session = HibernateUtils.openSession();
        //2 控制事务
        Transaction tx = session.beginTransaction();
        //3执行操作
        //-------------------------------------------
        //创建criteria查询对象
        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);
        //-------------------------------------------
        //4提交事务.关闭资源
        tx.commit();
        session.close();// 游离|托管 状态, 有id , 没有关联
    }
    @Test
    //分页查询
    public void fun3(){
        //1 获得session
        Session session = HibernateUtils.openSession();
        //2 控制事务
        Transaction tx = session.beginTransaction();
        //3执行操作
        //-------------------------------------------
        //创建criteria查询对象
        Criteria criteria = session.createCriteria(Customer.class);
        //设置分页信息 limit ?,?
        criteria.setFirstResult(1);
        criteria.setMaxResults(2);
        //执行查询
        List list = criteria.list();
        System.out.println(list);
        //-------------------------------------------
        //4提交事务.关闭资源
        tx.commit();
        session.close();// 游离|托管 状态, 有id , 没有关联
    }
    @Test
    //查询总记录数
    public void fun4(){
        //1 获得session
        Session session = HibernateUtils.openSession();
        //2 控制事务
        Transaction tx = session.beginTransaction();
        //3执行操作
        //-------------------------------------------
        //创建criteria查询对象
        Criteria criteria = session.createCriteria(Customer.class);
        //设置查询的聚合函数 => 总行数
        criteria.setProjection(Projections.rowCount());
        //执行查询
        Long count = (Long) criteria.uniqueResult();
        System.out.println(count);
        //-------------------------------------------
        //4提交事务.关闭资源
        tx.commit();
        session.close();// 游离|托管 状态, 有id , 没有关联
    }
}
  • 原生SQL查询

复杂的业务查询使用
测试代码:

import java.util.Arrays;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.junit.Test;
import domain.Customer;
import utils.HibernateUtils;
//测试原生SQL查询
public class Demo {
    @Test
    //基本查询
    public void fun1(){
        //1 获得session
        Session session = HibernateUtils.openSession();
        //2 控制事务
        Transaction tx = session.beginTransaction();
        //3执行操作
        //-------------------------------------------
        //1 书写sql语句
        String sql = "select * from cst_customer";
        //2 创建sql查询对象
        SQLQuery query = session.createSQLQuery(sql);
        //3 调用方法查询结果
        List list = query.list();
        //query.uniqueResult();
        for(Object[] objs : list){
            System.out.println(Arrays.toString(objs));
        }
        //-------------------------------------------
        //4提交事务.关闭资源
        tx.commit();
        session.close();// 游离|托管 状态, 有id , 没有关联
    }
    @Test
    //基本查询
    public void fun2(){
        //1 获得session
        Session session = HibernateUtils.openSession();
        //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 list = query.list();
        System.out.println(list);
        //-------------------------------------------
        //4提交事务.关闭资源
        tx.commit();
        session.close();// 游离|托管 状态, 有id , 没有关联
    }
    @Test
    //条件查询
    public void fun3(){
        //1 获得session
        Session session = HibernateUtils.openSession();
        //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, 1l);
        //指定将结果集封装到哪个对象中
        query.addEntity(Customer.class);
        //3 调用方法查询结果
        List list = query.list();
        System.out.println(list);
        //-------------------------------------------
        //4提交事务.关闭资源
        tx.commit();
        session.close();// 游离|托管 状态, 有id , 没有关联
    }
    @Test
    //分页查询
    public void fun4(){
        //1 获得session
        Session session = HibernateUtils.openSession();
        //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, 0);
        query.setParameter(1, 1);
        //指定将结果集封装到哪个对象中
        query.addEntity(Customer.class);
        //3 调用方法查询结果
        List list = query.list();
        System.out.println(list);
        //-------------------------------------------
        //4提交事务.关闭资源
        tx.commit();
        session.close();// 游离|托管 状态, 有id , 没有关联
    }
}

你可能感兴趣的:(JavaWeb - Hibernate框架使用(二))