科研管理系统总结 1——hibernate的部分update

开篇第一个问题,希望对大家有所帮助。

其实之前还遇到了关于级联保存的问题,但是网上有很多例子这里就不赘述了,把代码列在这里吧。

/**
		 * 具体情境:
		 * 三个实体:软件著作权Certificate 简称c
		 * 			用户信息 UserInfo 简称u
		 * 			软件著作权作者 CertificateAuthor 简称 ca
		 * c与ca 是一对多,在c内以set的形式关联ca
		 * u与ca 一对多 
		 * 
		 * 现在是需要保存c的时候级联保存ca,
		 * 需要设置cascade = CasedeType.ALL
		 */
		
		//c内的ca的set,将作为c的属性保存
		Set<CertificateAuthor> s = new HashSet<CertificateAuthor> (); 
		//构造新的c,没有Id
		Certificate c = new Certificate();
		//load用户信息实体
		UserInfo ui = userInfoService.loadById(1);
		//构造新的CA
		CertificateAuthor ca = new CertificateAuthor();
		/**
		 * 这两步是关键,设置关联
		 * 因为外键关系在ca内维护
		 * 所以两个都需要设置
		 * 否则相应的外键为null
		 */
		ca.setUserInfo(ui);
		ca.setCertificate(c);
		s.add(ca);
		//为c添加set列表
		c.setCertificateAuthors(s);
//		//保存c则会级联保存ca,结束	
		certificateService.save(c);


级联保存基本如上所示了。


进入正题关于hibernate的部分update,众所周知,hibernatee的update方法会把所有的属性都取出来然后更新一下。新的实体的属性会覆盖原有实体的所有属性,如果新的实体某些属性为空的话那么,那么原有的数据也就没了。

关于这一点,hibernate的update不实现部分保存可能是因为部分保存需要先取出原有的数据的version,比较version是否更改然后更新,这样的开销太大了,索性直接更新。

基本的方法有这几种:

1、设置某型是字段为不可更新的,annotation里就是设置列属性(updatable = false);
2、一种xml的设置方法,dymatic-update什么的记不得了网上应该有;
3、HQL 最王道的,就是写的有点麻烦;
4、先把实体load出来,然后逐个对改变的属性set,再更新,但是这样要写很多set

我的方法:
我的思路基本是采用第四种方式,但是做了一定的改动:
用的是org.springframework.beans.BeanUtils的一个copyProperty的方法

直接上代码

/*
		 * 该部分测试实现对Certificate实体的更新
		 */
		/*
		 * 设置一个VO里面有需要更新的属性
		 * 其实这个VO的设置并没有增加代码量
		 * 它主要用来前后台交互的,要么也要写
		 * 而且用它来做中间的复制媒介恰到好处,
		 * 下面有说明
		 */
		CertificateVO c = new CertificateVO();
		//加载待更新的实体
		Certificate uc = certificateService.getById(29);
		/*
		 * 设置待更新的属性
		 * 这个是测试方法,正常情况下是struts自动获取对象
		 * 这步就省了
		 */
		c.setName("test");
//		c.setId(14);
//		certificateService.saveOrUpdate(c);
		/*
		 * 复制属性
		 * 可以查看BeanUtil的API
		 * 第一个参数是源实体
		 * 第二个是目标实体
		 * 第三个参数标明那些实体不能更新
		 * 这个方法只会覆盖属性类型和方法相同的属性
		 * 所以这里用VO真是恰到好处
		 */
		BeanUtils.copyProperties(c, uc,new String[]{"id"});
		
		//更新实体,完成
		certificateService.update(uc);


好了,先写到这里,希望大家多多赐教!!

你可能感兴趣的:(C++,c,Hibernate,C#,软件测试)