Read Sean

          Read me, read Sean.
          posts - 508, comments - 655, trackbacks - 9, articles - 4

          [Tips] Spring+Hibernate之“暴力”update

          Posted on 2009-01-29 16:54 laogao 閱讀(2841) 評論(4)  編輯  收藏 所屬分類: On Java

          先簡單介紹一下問題的語境。

          手頭有個開發(fā)了3年的Spring+iBATIS應(yīng)用(經(jīng)典三層架構(gòu)),最近嘗試用Hibernate實現(xiàn)原有SQLMap版的部分CRUD操作。除開混合事務(wù)和其他一些底層配置細節(jié)(如TransactionAwareDataSource、禁用lazy-load等)之外,最大的一個"pattern-mismatch"是:Model層和持久層采用了dirty flag機制,即每次INSERT和UPDATE操作,都會根據(jù)每個字段的dirty與否決定是否參加INSERT/UPDATE,而這些dirty flag可以被外部重置,所以業(yè)務(wù)層的代碼,經(jīng)常可以看到類似這樣的pattern:

          1- new一個model類并setId() (或者在已有的model上重置dirty flag)
          2- set需要update的字段(通常都只是部分字段)
          3- 丟給DAO層去update

          最終的效果是某張表某個ID的某條記錄的某些字段被更新了,而其他字段不受影響,這就是我在標題中提到的所謂"暴力"update,雖不elegant,但卻也簡單實用,至少很"直接"。

          為了讓Hibernate版的DAO(默認除Trasient之外全體字段參加INSERT和UPDATE)繼續(xù)支持這樣的"use-pattern",除了按照Hibernate的習慣去配置映射和SessionFactory等之外,我們需要做一些額外的工作:

          1- 在BO/Entity類上追加注解
          @org.hibernate.annotations.Entity(dynamicInsert=true,?dynamicUpdate=true)

          2- 實現(xiàn)org.hibernate.Interceptor接口的findDirty()方法,Hibernate提供了一個EmptyInterceptor可以作為起點,方法簽名如下:
          public?int[]?findDirty(
          ????Object?entity,?
          ????Serializable?id,?
          ????Object[]?currentState,?
          ????Object[]?previousState,?
          ????String[]?propertyNames,?
          ????Type[]?types
          );
          返回的int[]包含所有應(yīng)該被認為是dirty的字段索引,返回null表示默認處理,傳入的entity是持久對象,字段列表會通過propertyNames參數(shù)傳給你。

          3- 注入到Spring的Application Context中,類似這樣:
          <bean?id="findDirtyInterceptor"?class="gao.sean.hybrid.interceptor.FindDirtyInterceptor"/>

          <bean?id="sessionFactory"
          ????class
          ="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
          ????
          ????
          <property?name="entityInterceptor"><ref?bean="findDirtyInterceptor"/></property>
          ????
          </bean>

          在這樣的配置下,業(yè)務(wù)層的代碼就可以繼續(xù)"暴力"update了。

          Feedback

          # re: [Tips] Spring+Hibernate之“暴力”update  回復  更多評論   

          2009-02-01 12:14 by BeanSoft
          不錯, 非常的實用!

          # re: [Tips] Spring+Hibernate之“暴力”update  回復  更多評論   

          2009-02-05 13:40 by IT公司面試手冊
          好文章

          # re: [Tips] Spring+Hibernate之“暴力”update  回復  更多評論   

          2009-02-10 00:47 by Evan.Shen
          1、不知樓主是怎么實現(xiàn)org.hibernate.Interceptor接口的findDirty()方法的
          2、在業(yè)務(wù)層使用能不能給個例子

          # re: [Tips] Spring+Hibernate之“暴力”update  回復  更多評論   

          2009-02-10 09:56 by 大胃
          @Evan.Shen
          1- 早先的代碼BO/model類中,已經(jīng)對每個字段都提供了相應(yīng)的dirty flag,我在findDirty()實現(xiàn)中,無非是根據(jù)傳入的propertyNames數(shù)組,檢查傳入的entity對象上對應(yīng)的property是否標記為dirty,然后返回int[]結(jié)果,沒什么特別的。
          2- 至于業(yè)務(wù)層怎么使用,原文中已經(jīng)有說明:
          # new一個model類并setId()
          # set需要update的字段
          # 丟給DAO層去update
          主站蜘蛛池模板: 金堂县| 长顺县| 包头市| 河池市| 江津市| 渭南市| 荆州市| 吉木萨尔县| 绵竹市| 友谊县| 博兴县| 剑川县| 大理市| 通道| 晋中市| 嵊州市| 阿城市| 德化县| 磐石市| 青铜峡市| 鲁甸县| 兴宁市| 吴桥县| 会东县| 鄢陵县| 高平市| 麦盖提县| 泾阳县| 清流县| 临泽县| 康平县| 达孜县| 手机| 高青县| 卓尼县| 阿拉善盟| 孝感市| 都江堰市| 潞西市| 乐都县| 凤冈县|