科研管理系统总结 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,没有IdCertificate c = new Certificate();//load用户信息实体UserInfo ui = userInfoService.loadById(1);//构造新的CACertificateAuthor 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);
好了,先写到这里,希望大家多多赐教!!