美文网首页
Hibernate之session接口(二)

Hibernate之session接口(二)

作者: 文先生_1357 | 来源:发表于2017-03-22 23:54 被阅读0次

    1.对象的几种状态

    在所有之前,说明一下,对于hibernate,它的对象有三种状态,transient、persistent、detached

    下边是常见的翻译办法:

    transient:瞬时态或者临时态

    (new DeptPo(1,”行政部”,20,”行政相关”),该po的实例和session没有关联,该po的实例处于transient)

    persistent:持久化状态

    (和数据库中记录想影射的Po实例,它的状态是persistent, 通过get和load等得到的对象都是persistent)

    detached:脱管状态或者游离态

    (1)当通过get或load方法得到的po对象它们都处于persistent,但如果执行delete(po)时(但不能执行事务),该 po状态就处于detached, (表示和session脱离关联),因delete而变成游离态可以通过save或saveOrUpdate()变成持久态

    (2)当把session关闭时,session缓存中的persistent的po对象也变成detached

    因关闭session而变成游离态的可以通过lock、save、update变成持久态

    持久态实例可以通过调用 delete()变成游离状态。

    通过get()或load()方法得到的实例都是持久化状态的。

    游离状态的实例可以通过调用lock()或者replicate()进行持久化。

    save()和persist()将会引发SQL的INSERT,delete()会引发SQLDELETE,

    而update()或merge()会引发SQL UPDATE。对持久化(persistent)实例的修改在刷新提交的时候会被检测到,它也会引起SQL UPDATE。

    saveOrUpdate()或者replicate()会引发SQLINSERT或者UPDATE

    可以通过session提供的方法用于改变对象的状态。

    save()方法:

    1.使一个临时对象成为持久化对象。

    2.为对象分配ID。

    3.在 flush缓存的时候发送一条insert语句。

    4.save之前设置的ID是无效的。

    5.持久化对象的ID是不可修改的。

    @Test

    public void testSave() {

    News news = new News();

    news.setAuthor("wenyu2");

    news.setDate(new Date());

    news.setTitle("php");

    news.setId(23);//该行设置无效

    System.out.println(news);

    session.save(news);

    System.out.println(news);

    news.setId(45);//改行抛出异常。

    persist()方法:

    与save方法类似的是persist()方法, persist()方法也可以执行insert操作,但是跟save的区别是,若在persist之前设置了ID值, 则抛出异常,不会insert操作。

    @Test

    public void testPersist() {

    News news = new News();

    news.setAuthor("wangwu");

    news.setDate(new Date());

    news.setTitle("py");

    news.setId(34);//抛异常,不会执行insert操作。

    session.persist(news);

    }

    get()方法:该方法会立即查询加载数据库中的对象(立即执行select语句)。但是若是该记录在数据库中不存在那么返回一个null(没有即没有很直接)。

    @Test

    public void testGet() {

    News news = (News) session.get(News.class, 4);

    session.close();//若是手动关闭session,下面的打印也会成功。

    System.out.println(news);

    }

    Load()方法:该方法功能和get相同,但是属于延迟加载的方法。

    也就是说,执行load方法之后,若是不使用该对象那么不会执行select语句,仅仅返回一个代理对象。与此同时若是查询的记录在数据库中不存在,那么会抛出异常(找不到对象),可以理解为返回代理对象之后,该代理对象无法找到与之匹配的真实对象,即抛异常。

    若是在使用对象之前手动关闭了session,在使用对象的时候会抛出懒加载异常。而get却是可以打印出来。

    @Test

    public void testLoad() {

    News news = (News) session.load(News.class, 4);

    System.out.println(news.getClass().getName());

    session.close();

    System.out.println(news);//调用的时候抛出懒加载异常。

    }

    update方法:

    1.若更新一个持久化对象,不需要显示的调用update方法,因为在Transaction 的commit方法之前会先执行flush操作(出发update语句)。

    2.当session关闭或者执行了evict方法,将对象从session 缓存中移除,那么该对象处于游离状态,此时需要显示调用update()方法,这个update()显示调用的时候,不论对象的属性是否发生变化都会执行update语句,在跟触发器协同工作的时候,为了避免这个问题,我们可以使用在hbm.xml文件中设置select-before-date值为true,检测是否有改变,若是没有改变那么不会发送update语句。(该方式不常用)。

    若数据表中没有该记录,但是还是执行update的话,会导致异常。

    当update方法关联一个游离状态的对象时,如果session中已经存在相同ID的持久化对象,会抛异常,因为session 中不能存在两个OID相同的对象。

    @Test

    public void testUpdate() {

    News news = (News) session.get(News.class, 4);

    transaction.commit();

    session.close();// 至此news对象是一个游离状态的。

    // news.setId(6);//该行会抛异常,ID在数据表中不存在。

    session = sessionFactory.openSession();

    transaction = session.beginTransaction();

    // news.setAuthor("JDBC");// news既不在原来的session缓存中,也不在新的缓存中。

    // News news2=(News)session.get(News.class, 5);//

    session.update(news);// 也就是需要通过显示的执行update方法,将该对象变为持久状态。

    }

    saveOrUpdate()方法:

    根据是否有OID 来判断是采用save操作还是update操作。 若OID不为空但是没有对应的记录,会抛异常。

    @Test

    public void testSaveOrUpdate() {

    News news = (News) new News("FF", "ff", new Date());

    news.setId(34);//若该ID在数据库中没有对应的记录,抛异常。

    session.saveOrUpdate(news);

    }


    delete方法:

    可删除一个游离对象,也可以删除一个持久化对象。session 的delete方法处理过程:

    计划执行一条delete语句,把对象从session缓存中删除,该对象成为删除状态。

    hibernate.use.identifier.rollback属性,默认值为false,若设置为true,将改变delete行为,那么会把对象的OID置为空,成为临时对象。

    @Test

    public void testDelete() {

    News news = (News) session.get(News.class, 11);

    session.delete(news);

    // session.update(news);//删除状态的不可以进行update操作。

    System.out.println(news);

    }

    Evict()方法:

    @Test

    public void testEvict() {

    News news1 = (News) session.get(News.class, 9);

    News news2 = (News) session.get(News.class, 8);

    news1.setTitle("uu");

    news2.setTitle("mm");

    session.evict(news2);// 从缓存中移除对象,该对象成为游离状态对象。

    session.update(news2);// 该对象若是要update的话,需要显示的调用,因为该对象已经属于游离对象。

    }

    相关文章

      网友评论

          本文标题:Hibernate之session接口(二)

          本文链接:https://www.haomeiwen.com/subject/qglonttx.html