近期寫了一個增刪改查的東東,其中修改功能涉及到時間的比較,這個地方發現了一個問題,這個問題在我們的開發環境不存在,但是經過版本管理員發布int之后就出來了。后來發現這個確實也涉及到jdk版本的問題,但是確實也是個問題。
首先,在數據庫里定義的該時間字段類型是date類型,Hibernate里.hbm.xml文件中orm映射的是 java.util.Date,javabean里也是java.util.Date,hbm.xml里的代碼如下:
<property name="tBedinDate" type="java.util.Date"> <column name="T_BEDIN_DATE" length="7"> <comment>起期</comment> </column> </property> <property name="tEndDate" type="java.util.Date"> <column name="T_END_DATE" length="7"> <comment>止期</comment> </column> </property>
當修改功能進行操作時,從頁面傳入后台的數據跟從數據庫里的查詢出來的數據進行比較,由於這兩個時間字段是必輸字段,我直接用了java.util.Date的compareTo函數來進行比較,這個是問題所在,在jdk1.5版本之后的jdk進行編譯,就會出現問題。
// if(objOld.gettEndDate().compareTo(obj.gettEndDate())!=0){ // objOld.settEndDate(obj.gettEndDate()); // }
后來我分析了問題所在:首先從數據庫里查詢的這個時間字段的類型,已經被Hibernate默認轉化為:java.sql.Timestamp類型,而從數據獲取的數據經過在頁面展示之后,傳回來的時間字段則是正常的javabean里定義的java.util.Date類型,在使用compareTo進行比較的時候會拋出異常,因為這已經是兩個不同的類型在比較了。
這個問題的解決方法有好幾種吧,可以把Timestamp轉成Date, 也可以把Date轉成Timestamp,然后比較,我用的方法是直接把兩個時間字段都轉化成固定格式的String,然后進行比較。
1、都轉成String 再比較:
String tEndDate = new SimpleDateFormat("yyyy-MM-dd").format(objOld.gettEndDate()); String tEndDateNew = new SimpleDateFormat("yyyy-MM-dd").format(obj.gettEndDate()); if(!tEndDate.equals(tEndDateNew)){ objOld.settEndDate(obj.gettEndDate()); }
2、Timestamp轉成Date
Timestamp t = new Timestamp(System.currentTimeMillis()); Date d = new Date(t.getTime());
3、Date轉成Timestamp
//SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd:HH:mm:ss"); String tsStr = new SimpleDateFormat("yyyy-MM-dd:HH:mm:ss").format(objOld.gettEndDate());
Timestamp ts = Timestamp.valueOf(tsStr);
或者 用new Timestamp((new Date()).getTime()) ,這個還沒有試過。
關於為什么從數據庫里查詢的這個時間字段的類型會被Hibernate默認轉成Timestamp類型,查了不少資料,都沒有能給出讓人信服的理由的,
在查資料的時候,發現了幾篇看着挺不錯的文章,可以學習下:
java.util.Date、java.sql.Date、java.sql.Time、java.sql.Timestamp區別和總結: http://blog.csdn.net/xiancaieeee/article/details/8099184
JDK 1.4升級至JDK5 JDK6的兩個關鍵問題BigDecimal、java.sql.Date : http://shuwen.iteye.com/blog/1179826