1. 程式人生 > >mybatis set session time zone

mybatis set session time zone

最近在寫一個專案,持久層想用mybatis,但是查詢的時候如果有TimeStamp的資料則會丟擲
java.sql.SQLException: Session Time Zone not set!
的異常,經過網上的查詢,發現是由於oracle資料庫中在建表的時候TimeStamp型別的欄位加上了 WITH LOCAL TIME ZONE的條件,所以在取日期型別的值時需要設定Time Zone. 但是找了很久都沒有發現mybatis的配置中有關於Session Time Zone的配置。最終發現sessionTimeZone的設定在oracle.jdbc.OracleConnection中。於是考慮到可以將connection向下轉型成oracle.jdbc.OracleConnection。經過搜尋發現可以通過
SqlSessionFactory.getConfiguration().getEnvironment()
					.getDataSource().getConnection();

中可以拿到connection,但是最終卻發現這個connection物件是個代理物件,強制轉換成oracle.jdbc.OracleConnection時就會丟擲型別轉換的異常。如此將問題解決的物件轉移到如何拿到oracle.jdbc.OracleConnection物件,最終在網上找到一篇相關文章,可以使用org.apache.ibatis.datasource.pooled.PooledDataSource的靜態方法unwrapConnection(Connection conn)獲得real connection 物件。如此即可強制轉換成oracle.jdbc.OracleConnection之後再對sessionTimeZone進行設定。設定方式如下:

((OracleConnection) realConn).setSessionTimeZone(TimeZone
					.getDefault().getID())

但是很遺憾的是,這個靜態方法在當前mybatis最新辦3.1.1版本中還有問題存在,它返回的依然是個代理物件(詳見:http://code.google.com/p/mybatis/issues/detail?id=591)。所以也只能等以後版本的更新了。如果大家有更好的辦法set session time zone的話,希望能跟我分享一下,謝謝!!

注:在mybatis將這個bug修復前,應該可以通過connection.createStatement().getConnection()拿到real connection

今天又發現一種方式,可以使用java.sql.Connection.unwrap(Class)方法拿到real connection. 不過如果驅動包使用的是classes12.jar是不行的,估計是classes12.jar出現的時候java.sql.Connection介面中沒有unwrap方法。不過ojdbc6.jar這個驅動包是可用的,並且需要注意的是,setSessionTimeZone方法的呼叫需要在拿到mybatis的sqlSession之後再設定,在建立SqlSessionFactory之後設定是不起作用的。具體原因應該是隻有在拿SqlSession的時候才會去跟資料庫建立連線吧。而且由於配置連線池的緣故,所以每次都的手動設定,具體程式碼如下:

session.getConnection().unwrap(OracleConnection.class).setSessionTimeZone(TimeZone.getDefault().getID());