Hibernate总结(一)

  • 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

时间: 2024-10-17 21:39:57

Hibernate总结(一)的相关文章

Hibernate - HHH000352: Unable to release batch statement

这是hibernate的一个bug,具体看https://hibernate.atlassian.net/browse/HHH-11732?attachmentViewMode=list When using stateless session with jdbc batch size we get an HHH000352: Unable to release batch statement.. error in session.close() after rollback: Code:Con

Hibernate简述及入门实例

一.Hibernate简述 总的概括,Hibernate是一个ORM的轻量级持久层框架,解决了对象和关系数据库中表的不匹配问题(阻抗不匹配)以及拥有开发代码不用去继承hibernate类或接口的优势(无侵入性).hibernate框架实现使得开发人员可以避免反复地编写javajdbc部分代码,应用面向对象的思维操作关系型数据库. 二.使用myeclipse创建hibernate实例两种方法(以hibernate3.5.2及mysql为例) a)手动编写hibernate.cfg.xml及*.hb

对象序列化和反序列--Hibernate的查询和新增极其相似

Hibernate几个关键字持久化,ORM(关系对象映射)(数据库中关系称作是一张表) 应用在项目中,刘一从写的查询代码,每次都挂掉,想要弄出测试数据,自己想着把查询出来的复杂数据弄到文件里自己要是去造那些复杂数据很麻烦public class Object1 { public static void main(String args[]){ HashMap<String, Object> obj=new HashMap<String,Object>(); obj.put(&quo

Hibernate的七种映射关系之七种关联映射(二)

继续上篇博客 七.Hibernate双向一对多关联映射:让多的一端来维护关系. 主要是解决一对多单向关联的缺陷,而不是需求驱动的. 1.在Student.java实体类里添加Classes引用.private Classes classes; 2.Student.hbm.xml里添加many-to-one标签:<many-to-one name="classes" column="classesid"/>.Classes.hbm.xml在例子(六)里的那

Hibernate的七种映射关系之七种关联映射(一)

关联映射就是将关联关系映射到数据库里,在对象模型中就是一个或多个引用. 一.Hibernate多对一关联映射:就是在"多"的一端加外键,指向"一"的一端. 比如多个学生对应一个班级,多个用户对应一个级别等等,都是多对一关系. 1."多"端实体加入引用"一"端实体的变量及getter,setter方法. 比如说多个学生对应一个班级,在学生实体类加入:private Grade grade; 2."多"端配置文

mybatis与hibernate的区别

本文转载自:http://blog.csdn.net/wangpeng047/article/details/17038659 以前没怎么用过mybatis,只知道与hibernate一样是个orm数据库框架.随着使用熟练度的增加,发现它与hibernate区别是非常大的,结合至今为止的经验,总结出以下几点: 1. hibernate是全自动,而mybatis是半自动. hibernate完全可以通过对象关系模型实现对数据库的操作,拥有完整的JavaBean对象与数据库的映射结构来自动生成sql

hibernate载入持久化对象的两种方式——get、load

一.get与load对照 在hibernate中get和load方法是依据id取得持久化对象的两种方法.但在实际使用的过程中总会把两者混淆,不知道什么情况下使用get好,什么时候使用load方法效率更高.下边具体说一下get和load的不同,有些时候为了对照也会把find加进来. 1.从返回结果上对照: load方式检索不到的话会抛出org.hibernate.ObjectNotFoundException异常 get方法检索不到的话会返回null 2.从检索运行机制上对照: get方法和fin

org.hibernate.NonUniqueObjectException:a different object with the same identifier value was alread

转自: http://blog.csdn.net/zzzz3621/article/details/9776539 看异常提示意思已经很明显了,是说主键不唯一,在事务的最后执行SQL时,session缓存里面有多个(>1)主键一样的对象. 了解过hibernate的都知道它有一个一级缓存,即session级别的缓存,在一个事务的执行过程中可以管理持久化对象,在事务最后执行SQL,可以减少数据库的操作. 报这个异常就得仔细看看你的代码,一定有地方引用的对象已经不同了. 下面就是一个典型的例子: [

谈谈你对Hibernate的理解

答: 1. 面向对象设计的软件内部运行过程可以理解成就是在不断创建各种新对象.建立对象之间的关系,调用对象的方法来改变各个对象的状态和对象消亡的过程,不管程序运行的过程和操作怎么样,本质上都是要得到一个结果,程序上一个时刻和下一个时刻的运行结果的差异就表现在内存中的对象状态发生了变化. 2.为了在关机和内存空间不够的状况下,保持程序的运行状态,需要将内存中的对象状态保存到持久化设备和从持久化设备中恢复出对象的状态,通常都是保存到关系数据库来保存大量对象信息.从Java程序的运行功能上来讲,保存对

Hibernate session缓存

一级缓存(执行代码时查看console台上的sql语句)  清空缓存 @Test public void demo03(){ //清空缓存 Session session=factory.openSession(); session.beginTransaction(); //1.查询 User user = (User)session.get(User.class, 1); System.out.println(user); //session.evitc(user) //将执行对象从一级缓存