三 Session中的主要方法
1.保存数据:save,presist 说明:这两种方法的主要区别主要体现在未开启事务时。save方法如果是没开启事务,会执行相关sql语句,随后再回滚。而presist根本就不执行这些sql语句。
2.删除对象:delete
3.更新数据:update 说明,如果数据库中没有记录将会出现异常
4.查找数据:get,立刻访问数据库 load,返回的是代理,不会立即访问数据库。
5.选择操作:saveOrUpdate,merge,根据id和version的值来确定是save还是update。saveOrUpdate方法的主要作用:可以把瞬时对象或脱管对象转成持久对象,而不需要具体判断对象是处在瞬时态或是脱管态来选择save或update来让对象变成持久态。只要调用此方法就能由id和version来灵活选择是保存或更新。而merge方法一个对象后,对象仍是脱管态。
5.持久对象:lock,把对象变成持久对象,但不会同步对象的状态。
四 对象三种状态:
1.瞬时(transient):数据库中没有数据与之对应,超过作用域会被JVM垃圾回收器回收,一般是new出来的且与Session无关系的对象。
2.脱管-游离(detached):数据库中有数据与之对应,但当前没有Session与之关联:脱管对象状态发生改变,Hibernate不能检测到。
3.持久(persistent):数据库有数据与之对应,当前与Session有关联,并且相关联的Session没有关闭,事务没有提交:持久对象状态发生改变时,在事务提交时会影响到数据库。
理解:与Session是否关联,数据库是否有数据与之对应是判断三种对象状态的依据。比如,瞬时状态跟它们均无关;脱管,只是数据库有数据与之对应,失去了Session对它的管理;而持久与两者有关。
从过程中理解三种对象状态:结合前面的实例,当我们User user=new User()一个对象时,它表示创建一个瞬时对象,当调用save(user)方法时,这个对象成为持久对象,直到事务提交,数据库连接关闭。在这期间,如果我们user.setXXX()时,会对这个持久对象产生影响,最终它也会被提交到数据库,它的最终提交是在提交事务时。比如save(user)方法后,跟user.setName("new name");和user.setPassword("new password");这两句,这样它会在提交时务时,采取对数据库的更新操作,也就是说数据库连接关闭后,数据库存的是“new name”和“new password” 而如果开启了“数据库语言显示”可以发现执行两次操作:一次是save方法的插入操作,一次是setXXX后提交事务时的更新作(特别说明,持久对象在发生改变时,比如setXXX方法改变对象内容时,会在最后,即提交事务时统一进行更新操作,而并非每一次改变就执行一次更新,这样可以保证与数据库的交互更高效合理)。当执行完save方法后,我们关闭数据库连接时,这时的user对象就是脱管状态,因为它在数据库有数据与之对应而脱管状态的最好例子是当我们用get方法得到一个对象并关闭连接时
补充说明:既然我们已经知道了持久对象可以被Hibernate检测到进行更新操作,那么update是否还有用了?有,比如脱管对象就可以调用update来更新数据库中的数据,而调用update()方法后的脱管对象又变成了持久对象。 下面是三种对象状态相互转换的图例:
再谈saveOrUpdate方法:此方法兼具了save和update两种方法。它根据传递的参数来选择执行其中的一种方法。如果参数对象是瞬时态,则执行save方法,而如果参数对象是脱管态,则执行update方法。最终都是把传递的参数对象转成持久态。 如何判断对象的状态?主要依据是看:实体对象id(或者version)取值与实体配置文件中<id>元素的unsaved-value属性值的匹配情况。 只要满足下面的任一情况则可以说明对象处在瞬时态:情况一,实体对象(持久化对象)的id取值为null形式(比如int型为0,字串为null)。 情况二,实体对象(持久化对象)的id取值与预设的unsaved-value属性值不同。 情况三,实体对象(持久化对象)的具有的versionn属性,并且为null。 情况四,实体对象(持久化对象)的version取值与预设的unsaved-value属性值不同