session 操作对象的方法

save方法:瞬时态------>持久态 ,会初始化OID

              1.执行save方法,立即触发insert语句,从数据库获得主键的值(OID值)

              2.执行save方法前,设置OID将忽略。

              3.如果执行查询,session缓存移除了,在执行save方法,将执行insert

   @Test

   public void demo01(){

      User user = new User(); 

      user.setUid(100);

      user.setUsername("jack");

      user.setPassword("1234");

     

      Session session = factory.openSession();

      session.beginTransaction();

      session.save(user);

  

      session.getTransaction().commit();

      session.close();

   }

@Test

   public void demo03(){

      //代理  assigned

      User user = new User(); 

      //user.setUid(100);

      user.setUsername("jack");

      user.setPassword("1234");

     

      Session session = factory.openSession();

      session.beginTransaction();

      session.save(user);

     

      session.getTransaction().commit();

      session.close();

   }

  1. 注意:持久态对象不能修改OID的值

   @Test

   public void demo04(){

      Session session = factory.openSession();

      session.beginTransaction();

      User user = (User) session.get(User.class, 100);

      user.setUid(101);

      session.save(user);

      session.getTransaction().commit();

      session.close();

   }

      

persist方法:瞬时态----->持久态 ,不会立即初始化OID

注意: persist方法不会立即得到ID,所以执行sql语句的时机要靠后.

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

      Serializable save = s.save(null);

      s.persist(null);

HIbernatesession的的save方法必须要事务才能插入数据库吗

测试方法:        

 Session session = getSession();//取得session

        Client client = new Client();

        client.setClientName("client");

        session.save(client); // 保存

        session.close();

当不加入事务的时候执行,在控制台打印sql语句:

     Hibernate: insert into chapter6.clients (clientName) values (?)

问题1:

但是查询数据库中并没有添加记录?这是为什么?

但是我用sql手动添加数据时候,发现clientId已经自增了,这又是为什么?

测试方法:        

Session session = getSession();

tx = session.beginTransaction();        

 Client client = new Client();

client.setClientName("client");

  session.save(client);

   tx.commit();

    session.close();

当加入事务的时候,数据插入没有问题,数据库中也可以查询到。

问题2:

       session的sava方法必须加入事务才能成功提交吗?

问题补充:

System.out.println(session.getFlushMode());打印结果为AUTO,没有设置FlushModel,默认就为AUTO,同时我调用session.flush()同样不能持久到数据库。

但是我用sql手动添加数据时候,发现clientId已经自增了,这又是为什么?

 

Update

  1. update:脱管态------>持久态

       如果OID在数据存放的,将执行update语句

       如果OID不存在将抛异常

@Test

   public void demo01(){

      //自然 assigned

      User user = new User(); 

      user.setUid(101);

      user.setUsername("jack1");

      user.setPassword("12345");

     

      Session session = factory.openSession();

      session.beginTransaction();

     

      session.update(user);

     

      session.getTransaction().commit();

      session.close();

   }

  1. 注意1:如果数据没有修改,执行save方法,将触发update语句。

       查询速度 更新速度快

       通过<class select-before-update> 来设置更新前先查询,如果没有改变就不更新。

总结:

       update 之后对象 持久态

merge

new一个对象,如果该对象设置了ID,则这个对象就当作游离态即托管态处理:

ID在数据库中不能找到时,用update的话肯定会报异常,然而用merge的话,就会insert

ID在数据库中能找到的时候,updatemerge的执行效果都是更新数据,发出update语句;

如果没有设置ID的话,则这个对象就当作瞬时状态处理:

update的话,由于没有ID,所以会报异常,merge此时则会保存数据,根据ID生产策略生成一条数据;

@Test

   public void demo03(){

      // merge 合并

      User user = new User(); 

      user.setUid(1);

      user.setUsername("jack3");

      user.setPassword("12345");

     

      Session session = factory.openSession();

      session.beginTransaction();

     

      // 1 oid =1 持久态对象

      User user2 = (User) session.get(User.class, 1);

       //session.update(user);

      session.merge(user);

     

      session.getTransaction().commit();

      session.close();

   }

saveOrUpdate

  1. 代理主键:

       判断是否有OID

              如果没有OID,将执行insert语句

              如果有OID,将执行update语句。

@Test

   public void demo02(){

      // 代理 native

      User user = new User(); 

//    user.setUid(2);

      user.setUsername("jack2");

      user.setPassword("12345");

     

      Session session = factory.openSession();

      session.beginTransaction();

     

      session.saveOrUpdate(user);

     

      session.getTransaction().commit();

      session.close();

   }

 

  1. 自然主键:

       先执行select语句,查询是否存放

       如果不存在,将执行insert

       如果存在,将执行update

   @Test

   public void demo02(){

      // 自然 assigned

      User user = new User(); 

      user.setUid(2);

      user.setUsername("jack2333");

      user.setPassword("12345333");

     

      Session session = factory.openSession();

      session.beginTransaction();

     

      session.saveOrUpdate(user);

     

      session.getTransaction().commit();

      session.close();

   }

 

  1. 注意1native下,默认OID是存在,使用默认值。例如:Integer 默认null

       通过<id  unsaved-value="1"> 修改使用默认值,如果设置1进行insert语句。此内容提供hibernate使用的,录入到数据库后,采用自动增长。

在上例中,程序并没有显式的session.save(child);

那么Hibernate需要知道child究竟是一个临时对象,还是已经在数据库中有的持久对象。

如果child是一个新创建的临时对象(本例中就是这种情况),那么Hibernate应该自动产生session.save(child)这样的操作,

如果child是已经在数据库中有的持久对象,那么Hibernate应该自动产生session.update(child)这样的操作。

       因此我们需要暗示一下Hibernate,究竟child对象应该对它自动save还是update。在上例中,显然我们应该暗示Hibernate对child自动save,而不是自动update。那么Hibernate如何判断究竟对child是save还是update呢?它会取一下child的主键属性 child.getId() ,这里假设id是 java.lang.Integer类型的。如果取到的Id值和hbm映射文件中指定的unsave-value相等,那么Hibernate认为child是新的内存临时对象,发送save,如果不相等,那么Hibernate认为child是已经持久过的对象,发送update。

unsaved-value="null" (默认情况,适用于大多数对象类型主键 Integer/Long/String/...)

当Hibernate取一下child的Id,取出来的是null(在上例中肯定取出来的是null),和unsaved-value设定值相等,发送save(child)

当Hibernate取一下child的id,取出来的不是null,那么和unsaved-value设定值不相等,发送update(child)

delete

1) session的delete方法是通过主键进行删除的,主键不存在则异常

2) 持久状态对象被delete后变成瞬时状态对象

 

 

猜你喜欢

转载自blog.csdn.net/uotail/article/details/81835061
今日推荐