知道美河 | 上传资料 | VIP申请 | 精品课程 | 资料搜索 | 问题反馈 | 会员手册 | 积分消费 | 积分充值 | 帐号保护
美河学习学习在线赞助VIP

美河学习在线(主站) eimhe.com

 找回密码
 建立账号
查看: 8762|回复: 4

[原创] 用实际项目讲解hibernate持久化对象的native属性

[复制链接]
发表于 2007-9-6 13:28:40 | 显示全部楼层 |阅读模式
项目名称:军乐团综合管理系统
在该系统最重要的环节[添加使用记录]的时候,我从UI获取了资产和学生的以及记录本身的基本信息,通过控制器传给业务层,业务层通过数据访问层的接口调用不用的DAO实现物理表的更新操作。
记录本生有个很重要的属性[最后状态]用来保存记录的状态,内容有:使用中、以结束两种状态,在添加新的历史记录的时候,我先把记录的基本信息保存到传给数据访问层,然后再更新[最后状态]字段为[使用中],这样在业务层就有两个数据访问语句:sava记录本身以及update记录状态属性,于是,实现该功能“至少”要写一次数据库,修改一次数据库,然后读数据库返回到UI*,这MD不是自找麻烦吗?
为什么不在控制器里面直接将记录的[状态]属性直接设置为[使用中]呢?这样只需要写一次数据库不就完了!于是我在控制器内就直接set了记录的[状态]属性,最后结果是一样的。
*废话讲完,开始native!我对记录表的ID设置的时自增,配置为nactive,既然如此,在set记录的属性的时候就用不着set他的ID了,而我在业务层进行了这样的操作:
  this.insUseHistroyService.addInsUseHistroy(insUseHistroy);
  Instrument instrument = insUseHistroy.getInstrument();
  instrument.setStatus("1");
  insUseHistroy.setLaststatus("0");
  
  this.insService.updateSatus(instrument);
  this.insUseHistroyService.updateLastStatus(insUseHistroy);
注意到了么?在执行第6行的时候,更新的时[记录]表的单个字段[lasetStatus],在DAO执行此项操作的时候,必然需要记录的ID才可以更新单个字段,而此时,从高层穿过来的纪录对象本身并没有设置它的ID属性,但是!我在这里System.out.println(insUseHistroy.getId());的时候居然读出来的他的ID!记录对象只有在保存到数据库之后才由数据库给他自增一个ID,而此时,insUseHistroy是从高层穿过来的对象根本不存在ID,那么这个ID是从哪里来的?
于是得出结论,在执行了save之后,hibernate会自动从数据库读取相应的记录,来覆盖掉原来的对象!!恐怖!这就是我在DAO执行的操作:
public void updateLastStatus(InsUseHistroy insUseHistroy) {
  // TODO Auto-generated method stub
  HibernateTemplate ht = this.getHibernateTemplate();
  System.out.println("update LasetStatus in DAO" );
  System.out.println("update LasetStatus in DAO and ouhid=" + insUseHistroy.getId() );
  InsUseHistroy iuh = (InsUseHistroy)ht.load(InsUseHistroy.class, insUseHistroy.getId());
  iuh.setLaststatus(insUseHistroy.getLaststatus());
  
  ht.flush();
  try {
   ht.saveOrUpdate(iuh);
  } catch (DataAccessException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
}
在第五行分明就能读出来数据库给他分配的ID!这么说hibernate一旦执行了sava,就自动从数据库读取记录然后再动生成相应的对象并覆盖掉原来的对象么?

其实并不是这样的(要是这样的话,hibernate早就被淘汰了),从配置文件不知道你可以看出端倪不
<id name="id" type="java.lang.Integer">
            <column name="ID" />
            <generator class="native" />
        </id>
是的,id设置为natice!
也就是说!再使用hibernate的sava之前,对象ID为空,但是,一点沾上hibernate,那么,该对象的id将自动被native,具体实现要看数据库了,如果是sqlSERVER,必然是incremant,于是,hibernate便自动在插入数据库之前就为该对象准备了一个id。
举个例子来说,人刚生下没有名字,这时候必然不能从名字来查找人,而一旦父母为你取了个名字,今后在上大学的时候就需要注册名字,而这个名字是从父母那里来的,在这里,hibernate'就像当于“父母”,而数据库就像当于“大学”了

个人体会,讲的不好请多多包涵!!

[ 本帖最后由 djhyoo 于 2007-9-6 13:29 编辑 ]
发表于 2007-9-14 09:51:49 | 显示全部楼层
同意.hibernate中为设置为native的属性设置了一个记录变量.每次产生的ID由这个变量来决定.
我做了一个简单的实验.实例化产生一个对象设置并对象属性.但不设置ID属性.这时读取ID为NULL,在调用Session的save方法来保存这个对象.但不执行事务提交.再读取ID,这时有一个值.重复执行Session的save方法,ID值递增.(注在同一个session中重复保存同一个对象,ID是不会增长的).而此时间数据库里根本没有相关的数据记录.些时你要是向库里插入一条数据,会发现最后那条记录与前一条记录之间ID不连续.而之间的差值就是由于之前调用Session的save方法时把记录ID的变量给递增了.

[ 本帖最后由 jenney 于 2007-9-14 09:53 编辑 ]
发表于 2007-9-14 12:50:02 | 显示全部楼层
发表于 2007-12-13 16:13:55 | 显示全部楼层
发表于 2009-4-6 08:35:36 | 显示全部楼层
您需要登录后才可以回帖 登录 | 建立账号

本版积分规则

 
QQ在线咨询

QQ|小黑屋|手机版|Archiver|美河学习在线 ( 浙网备33020302000026号 )

GMT+8, 2025-5-2 10:57

Powered by Discuz!

© 2001-2025 eimhe.com.

快速回复 返回顶部 返回列表