IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    Hibernate总结(一)

    summer发表于 2016-10-31 04:32:45
    love 0
    • Hibernate为了提高性能,提供了缓存与快照机制。

    它的缓存分为一级缓存与二级缓存。

    Hibernate一级缓存:当一个事务中执行一次Sql语句时,就将返回的结果存储在Session中的Map集合中(当然,还有快照)。

    • 测试:(以下所有代码处于try/catch块中)
         Configuration config=new Configuration().configure();//configure()方法是加载src/hibernate.cfg.xml配置文件
    SessionFactory sf
    =config.buildSessionFactory();
    Session s
    =sf.openSession();//Session是高一级的对Connection的封装
    Transaction tran
    =null;
    try {
    tran
    =s.beginTransaction();

    //代码在此
    tran.commit();
    }
    catch (HibernateException e) {
    if(tran!=null){
    tran.rollback();
    }
    e.printStackTrace();
    }
    finally{
    s.close();
    sf.close();
    }

    • 查询:包括get(),load(),原生Sql,HQL,Criteria(比HQL更面向对象的一种查询方式)
           //1.get(),load()方法测试
    User u=(User) s.get(User.class, 1);//第一次查询生成SQL语句,并将结果放入缓存
    User u1=(User) s.get(User.class, 1);//第二次查询并无生成SQL语句,但结果取自缓存
    p(u==u1);//
    true
    //2.HQL查询
    Query q=s.createQuery("from domain.User where id=1");
    User u2=(User) q.uniqueResult();//第三次查询生成了SQL语句,但结果取自缓存
    p(u2==u);//
    true
    //3.原生Sql
    SQLQuery q1=s.createSQLQuery("select * from User where id=1");
    q1.addEntity(User.class);
    User u3=(User) q1.uniqueResult();//第四次查询生成了SQL语句,但结果取自缓存
    p(u3==u);//
    true
    //4.Criteria查询
    Criteria c=s.createCriteria(User.class);
    c.add(Restrictions.eq("id", 1));
    User u4=(User) q1.uniqueResult();//第五次查询生成了SQL语句,但结果取自缓存
    p(u4==u);//true

    总结查询:

      get(),load() 原生Sql,HQL,Criteria
    Sql语句的缓存 √

    X

    查询对象的缓存 √ √
    • 增加:save(),persist()
           User user = new User();//对象的瞬态
    user.setName(
    "xiaobai");
    user.setAge(
    121);
    s.save(user);//对象的持久态
              s.persist(user);

    这里两个方法的区别是:执行方法之前设置主键问题与执行方法之后返回主键问题。

    1,persist(),把一个瞬态的实例持久化,但是并"不保证"标识符(identifier主键对应的属性)被立刻填入到持久化实例中,标识符的填入可能被推迟到flush的时候。

    2,save(), 把一个瞬态的实例持久化标识符,及时的产生,它要返回标识符,所以它会立即执行Sql insert。

    User u = new User();
    u.setName(
    "xiaobai");
    u.setAge(
    121);
    s.save(u);//插入数据库,并将对象瞬态转为持久态,将返回对象存入缓存
    User u1
    =(User) s.get(User.class, u.getId());//这次查询没有生成SQL语句,结果取自Session的缓存
    p(u1==u);//true
    • 删除:delete()
    User u=(User) s.get(User.class, 10);//执行查询操作
    s.delete(u);//将对象持久态转为游离态

    当然,如果感觉为了删除一个数据,还的执行查询操作降低性能,可以这样:

    User u=new User();
    u.setId(
    5);
    s.delete(u);
    • 更新:update()
    User u=(User) s.get(User.class, 1);
    u.setName(
    "set");

    但有时候,我们不需要执行s.update(对象)方法,这这涉及到对象的持久态一个特性(也有【快照】作用其中):

    当对象为持久态时,当它更新数据时,框架会拿它与之前的快照作比较,若相同,则无动作;若不同,则自动更新至数据库。

    //当然,也可以这么做
    User u=new User();//对象的瞬态,不具备自动更新功能,需要我们手动update()
    u.setAge(
    1);
    u.setId(
    1);
    u.setName(
    "1");
    s.update(u);
    • 总结:

    有一点非常重要:在事务中虽然形成了Sql语句,但只有事务.commit()之后才会真正操作数据库。

    Hibernate关于数据库的操作,需要弄清楚【缓存,快照,对象三态】等等些许东西。

    对象三态:

    * 瞬时态:和hibernate没关联,在数据库表中没有对应的id
    * 持久态:和hibernate有关联,在数据库表中有对应的id---OID
    * 游离态:和hibernate没关联,在数据库表中有对应的id

     



沪ICP备19023445号-2号
友情链接