日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

JFinal针对ORACLE的timestamp字段解决办法

發布時間:2025/3/17 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JFinal针对ORACLE的timestamp字段解决办法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

為什么80%的碼農都做不了架構師?>>> ??

JFinal是個比較不錯的的框架,但JFinal起源時使用mysql數據庫,因此在對數據庫支持方面還沒有達到完美。

本人使用JFinal有一段時間的,由于項目的數據庫普遍采用oracle,在使用oracle過程中遇到了一些不便之處(比如ORACLE中的自動生成主鍵、oracletimestamp字段返回oracle.sql.timestamp等),幸好在@JFinal 等人的幫助下已經解決了遇到的問題,本遍就是講如何解決oracletimestamp字段返回oracle.sql.timestamp

? oracle總有些與眾不同的地方,比如它的字段默認沒有自增支持,更可惡的是它的字段返回類型與其他數據庫返回類型不一樣,比如說timestamp字段,這貨居然給我們返回了oracle.sql.Timestamp,對于oracle本身暫不作評價。

? ? 以前JFinal只用在一個小項目中,而且基本就是我個人在維護,因此碰到timestamp,只能手動的進行一些轉換。但現在JFinal用到了一個大一點的項目中,而且開發人員也不只我一個,初次大家對JFinal這種簡單的、高效的框架很喜歡,但遇到需手動處理timestamp時,對JFinal有些失望,居然只能手動轉換。為了提高大家對JFinal的信心,我就認真研究了一下JFINAL對字段的處理過程,得出結論如下:

1、????? JFinal在啟動時會將注冊的Model 與數據庫中對應的table進行一一綁定,綁定的過程主要是通過TableInfoBuilder.buildTableInfo()創建一個TableInfo對象,該對象如下:

private String tableName;private String primaryKey;private String secondaryKey = null;@SuppressWarnings("unchecked")private Map<String, Class<?>> columnTypeMap = DbKit.containerFactory.getAttrsMap(); // new HashMap<String, Class<?>>();

其實最核心的就是這個columnTypeMap對象,這個MAP記錄著table每個字段的名字及其類型。?通過跟蹤源代碼發現目前JFinal將默認將Oracle中的timestamp轉換成java.lang.String類型,具體創建TableInfo的方法如下:

private static TableInfo doBuildTableInfo(TableInfo tableInfo,Connection conn) throws SQLException {TableInfo result = tableInfo;String sql = DbKit.getDialect().forTableInfoBuilderDoBuildTableInfo(tableInfo.getTableName());Statement stm = conn.createStatement();ResultSet rs = stm.executeQuery(sql);ResultSetMetaData rsmd = rs.getMetaData();for (int i = 1; i <= rsmd.getColumnCount(); i++) {String colName = rsmd.getColumnName(i);String colClassName = rsmd.getColumnClassName(i);if ("java.lang.String".equals(colClassName)) {// varchar, char, enum, set, text, tinytext, mediumtext,// longtextresult.addInfo(colName, java.lang.String.class);} else if ("java.lang.Integer".equals(colClassName)) {// int, integer, tinyint, smallint, mediumintresult.addInfo(colName, java.lang.Integer.class);} else if ("java.lang.Long".equals(colClassName)) {// bigintresult.addInfo(colName, java.lang.Long.class);} else if ("java.sql.Date".equals(colClassName)) {// date, yearresult.addInfo(colName, java.sql.Date.class);} else if ("java.lang.Double".equals(colClassName)) {// real, doubleresult.addInfo(colName, java.lang.Double.class);} else if ("java.lang.Float".equals(colClassName)) {// floatresult.addInfo(colName, java.lang.Float.class);} else if ("java.lang.Boolean".equals(colClassName)) {// bitresult.addInfo(colName, java.lang.Boolean.class);} else if ("java.sql.Time".equals(colClassName)) {// timeresult.addInfo(colName, java.sql.Time.class);} else if ("java.sql.Timestamp".equals(colClassName)|| "oracle.sql.TIMESTAMP".equals(colClassName)) {// timestamp, datetimeresult.addInfo(colName, java.sql.Timestamp.class);} else if ("java.math.BigDecimal".equals(colClassName)) {// decimal, numericresult.addInfo(colName, java.math.BigDecimal.class);} else if ("[B".equals(colClassName)) {// binary, varbinary, tinyblob, blob, mediumblob, longblob// qjd project: print_info.content varbinary(61800);result.addInfo(colName, byte[].class);} else {int type = rsmd.getColumnType(i);if (type == Types.BLOB) {result.addInfo(colName, byte[].class);} else if (type == Types.CLOB || type == Types.NCLOB) {result.addInfo(colName, String.class);} else {result.addInfo(colName, String.class);}// core.TypeConverter// throw new RuntimeException("You've got new type to mapping.// Please add code in " + TableInfoBuilder.class.getName() + ".// The ColumnClassName can't be mapped: " + colClassName);}}rs.close();stm.close();return result;}


2、????? JFinal將數據填充到Model中時,主要執行ModelBuilder. build(ResultSet rs, Class<? extends Model> modelClass)方法,該方法實現如下:其實這個過程JFinal沒有進行干預(除了CLOB、NCLOB、BLOB),數據根據JDBC默認的方式進行返回。

@SuppressWarnings({"rawtypes", "unchecked"})public static final <T> List<T> build(ResultSet rs, Class<? extends Model> modelClass) throws SQLException, InstantiationException, IllegalAccessException {List<T> result = new ArrayList<T>();ResultSetMetaData rsmd = rs.getMetaData();int columnCount = rsmd.getColumnCount();String[] labelNames = new String[columnCount + 1];int[] types = new int[columnCount + 1];buildLabelNamesAndTypes(rsmd, labelNames, types);while (rs.next()) {Model<?> ar = modelClass.newInstance();Map<String, Object> attrs = ar.getAttrs();for (int i=1; i<=columnCount; i++) {Object value;if (types[i] < Types.BLOB)value = rs.getObject(i);else if (types[i] == Types.CLOB)value = handleClob(rs.getClob(i));else if (types[i] == Types.NCLOB)value = handleClob(rs.getNClob(i));else if (types[i] == Types.BLOB)value = handleBlob(rs.getBlob(i));elsevalue = rs.getObject(i);attrs.put(labelNames[i], value);}result.add((T)ar);}return result;}


解決思路:

?????????對數據庫的數據操作有2種,set/get,為了將oracletimestamp改造成與mysqltimestamp一樣,我們就需要在set/get時進行一些干預,以上2點分別對應set/get操作。通過修改源碼,然后經過測試是發現思路是可行的。

?1、doBuildTableInfoy()方法中在"java.sql.Timestamp".equals(colClassName)增加|| "oracle.sql.TIMESTAMP".equals(colClassName),使其可以識別oracle.sql.timestamp

} else if ("java.sql.Timestamp".equals(colClassName)|| "oracle.sql.TIMESTAMP".equals(colClassName)) {// timestamp, datetimeresult.addInfo(colName, java.sql.Timestamp.class);

????????????2、ModelBuilder.build() 中?for (int i = 1; i <= columnCount; i++) {}循環體修改如下:

for (int i = 1; i <= columnCount; i++) {Object value;if (types[i] == Types.CLOB)value = handleClob(rs.getClob(i));else if (types[i] == Types.NCLOB)value = handleClob(rs.getNClob(i));else if (types[i] == Types.BLOB)value = handleBlob(rs.getBlob(i));else if (types[i] == Types.TIMESTAMP&& DbKit.dialect.isOracle()) {// oracle.sql.timestamp --->java.sql.Timestampvalue = rs.getTimestamp(i);} else {value = rs.getObject(i);}attrs.put(labelNames[i], value);}

PS:本人文字功底差,而沒有用得順手的編輯器,大家湊合看看就行了。希望@JFinal 考慮一下是否能將代碼更新到版本庫中。

?



轉載于:https://my.oschina.net/calfer/blog/140034

新人創作打卡挑戰賽發博客就能抽獎!定制產品紅包拿不停!

總結

以上是生活随笔為你收集整理的JFinal针对ORACLE的timestamp字段解决办法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。