鷹翔宇空

          學習和生活

          BlogJava 首頁 新隨筆 聯系 聚合 管理
            110 Posts :: 141 Stories :: 315 Comments :: 1 Trackbacks

          原文引自:http://forum.javaeye.com/viewtopic.php?t=9035

          偶們經常會遇到一些用戶需求, 需要實現一個區間類型的東東:

          public class Entity {
          private Date startDate;
          private Date endDate;
          private ......;
          }

          如項目的開始/結束時間, 人員的任職期間等等

          但是如要比較這個對象和其他對象區間的關系, 就得寫一些惡心的code:
          if(this.startDate > that.startDate && this.endDate < that.endDate)
          if(this.startDate < that.startDate) ......
          一堆的if else了.

          或許你會覺得這些小東西這樣寫就可以了, 但是為了有一個更完美, 更好用的Domain Object, 是值得偶們在這些小細節上操勞的.

          有一些現成的lib就是做這些東西的, 比如:
          http://timeandmoney.sourceforge.net/
          http://joda-time.sourceforge.net/

          這里用timeandmoney lib為例子, 來介紹一下利用Hibernate的UserType來創建一個Domain Object

          首先是一個業務對象:
          java代碼: 


          import com.domainlanguage.time.TimeInterval;

          public class RecordLog extends Entity {
              private String description;
              private TimeInterval interval;
              //getters and setters......
          }



          然后是mapping文件:
          xml代碼: 


                  <class name="RecordLog">
                          <id name="id">
                                  <generator class="native"/>
                          </id>
                  <property name="description"/>
                  <property name="interval" type="TimeIntervalType">
                      <column name="LOWER_LIMIT"/>
                      <column name="INCLUDES_LOWER_LIMIT"/>
                      <column name="UPPER_LIMIT"/>
                      <column name="INCLUDES_UPPER_LIMIT"/>
                  </property>
                  </class>



          一個操作它的Manager:
          java代碼: 


          public class Manager extends HibernateDaoSupport {
              public RecordLog load(Long id) {
                  return (RecordLog) getHibernateTemplate().load(RecordLog.class, id);
              }

              public void save(RecordLog log) {
                  getHibernateTemplate().saveOrUpdate(log);
              }
          }



          偶們先來看看它是怎么運行的:
          java代碼: 


              public void test() {
                  TimePoint nov01 = TimePoint.atMidnightGMT(2004, 11, 01);
                  TimePoint nov03 = TimePoint.atMidnightGMT(2004, 11, 03);
                  TimePoint nov02 = TimePoint.atMidnightGMT(2004, 11, 02);
                  TimePoint nov05 = TimePoint.atMidnightGMT(2004, 11, 05);
                 
                  RecordLog log1 = new RecordLog();
                  log1.setDescription("Record Log 1");
                  log1.setInterval(TimeInterval.closed(nov01, nov03));       
                  RecordLog log2 = new RecordLog();
                  log2.setDescription("Record Log 2");
                  log2.setInterval(TimeInterval.closed(nov02, nov05));
                 
                  //這里, 偶們只取交叉區間
                  //比原來的一堆if else簡潔多了吧?
                  if(log1.getInterval().intersects(log2.getInterval())){
                      log1.setInterval(log1.getInterval().intersect(log2.getInterval()));
                  }
                  manager.save(log1);

                  RecordLog loaded = manager.load(log1.getId());
                  assertEquals("Record Log 1", loaded.getDescription());
                  assertEquals(nov02, loaded.getInterval().lowerLimit());
                  assertEquals(nov03, loaded.getInterval().upperLimit());
                  assertTrue(loaded.getInterval().includesLowerLimit());
                  assertTrue(loaded.getInterval().includesUpperLimit());
              }



          怎么樣, 是不是比原來的代碼簡單多了? 在背后干臟活,累活的就是這個TimeIntervalType和TimeAndMoney Lib:
          代碼格式好難看阿, 只好用quote 寫道:

          public class TimeIntervalType implements UserType {

          private static final int[] SQL_TYPES = new int[] { Hibernate.TIMESTAMP.sqlType(), Hibernate.BOOLEAN.sqlType(), Hibernate.TIMESTAMP.sqlType(),
          Hibernate.BOOLEAN.sqlType() };

          public int[] sqlTypes() {
          return SQL_TYPES;
          }

          public Class returnedClass() {
          return TimeInterval.class;
          }

          public boolean equals(Object x, Object y) throws HibernateException {
          if (x == y)
          return true;
          if (x == null || y == null)
          return false;
          return ((TimeInterval) x).compareTo((TimeInterval) y) == 0;
          }

          public Object nullSafeGet(ResultSet rs, String[] names, Object owner) throws HibernateException, SQLException {
          TimePoint lower = TimePoint.from((Timestamp) Hibernate.TIMESTAMP.nullSafeGet(rs, names[0]));
          boolean lowerIncluded = ((Boolean) Hibernate.BOOLEAN.nullSafeGet(rs, names[1])).booleanValue();
          TimePoint upper = TimePoint.from((Timestamp) Hibernate.TIMESTAMP.nullSafeGet(rs, names[2]));
          boolean upperIncluded = ((Boolean) Hibernate.BOOLEAN.nullSafeGet(rs, names[3])).booleanValue();
          return new TimeInterval(lower, lowerIncluded, upper, upperIncluded);
          }

          public void nullSafeSet(PreparedStatement st, Object value, int index) throws HibernateException, SQLException {
          TimeInterval interval = (TimeInterval) value;
          Hibernate.TIMESTAMP.nullSafeSet(st, new Timestamp(((TimePoint) interval.lowerLimit()).asJavaUtilDate().getTime()), index);
          Hibernate.BOOLEAN.nullSafeSet(st, new Boolean(interval.includesLowerLimit()), index + 1);
          Hibernate.TIMESTAMP.nullSafeSet(st, new Timestamp(((TimePoint) interval.upperLimit()).asJavaUtilDate().getTime()), index + 2);
          Hibernate.BOOLEAN.nullSafeSet(st, new Boolean(interval.includesUpperLimit()), index + 3);
          }

          public Object deepCopy(Object value) throws HibernateException {
          if (value == null)
          return null;
          TimeInterval interval = (TimeInterval) value;
          return new TimeInterval((TimePoint) interval.lowerLimit(), interval.includesLowerLimit(), (TimePoint) interval.upperLimit(), interval
          .includesUpperLimit());
          }

          public boolean isMutable() {
          return true;
          }

          }

          posted on 2006-02-11 09:23 TrampEagle 閱讀(348) 評論(0)  編輯  收藏 所屬分類: hibernate
          主站蜘蛛池模板: 内黄县| 额济纳旗| 黔南| 巨野县| 鄂州市| 南城县| 吴桥县| 定日县| 车致| 和龙市| 鸡西市| 南乐县| 诸暨市| 耒阳市| 安泽县| 志丹县| 镇宁| 南部县| 玉环县| 拉孜县| 广昌县| 东丽区| 封丘县| 灵寿县| 民县| 梁河县| 鄂托克旗| 德庆县| 贺兰县| 昆山市| 金堂县| 北票市| 新安县| 屏山县| 武乡县| 西城区| 乌拉特前旗| 青州市| 徐闻县| 沈丘县| 三门县|