在尝试用JFinal做一个小项目,测试的时候发现对oracle时间字段有些没做转换,现在修改源代码如下所述。
1、修改core下的TypeConverter类,这个类是对前台Model的类型自动转换,而对于oracle的Date和Timestamp来说,是符合clazz == java.sql.Timestamp.class,而当界面输入日期不带时间,会转换格式错误,采用类似clazz == java.sql.Date.class的判断来做统一修改(clazz == java.sql.Time.class也顺带修改)。
else if (clazz == java.sql.Time.class) { // result = java.sql.Time.valueOf(s); result = new java.sql.Time(new SimpleDateFormat(timePattern).parse(s).getTime()); } // mysql type: timestamp, datetime else if (clazz == java.sql.Timestamp.class) { // result = java.sql.Timestamp.valueOf(s); if (s.length() >= timeStampLen) { result = new java.sql.Timestamp(new SimpleDateFormat(timeStampPattern).parse(s).getTime()); } else { result = new java.sql.Timestamp(new SimpleDateFormat(datePattern).parse(s).getTime()); } }
2、修改com.jfinal.plugin.activerecord下的TableInfoBuilder类,扫描表结构类型,这里会把oracle的timestamp类型当作string处理,在124行附件新增一条else if语句。
else if (type == Types.TIMESTAMP) { result.addInfo(colName, java.sql.Timestamp.class); }3、DbKit类新增3个方法,用来替换rs.getObject()获取结果集的值,是从spring jdbc中摘取过来的,还是蛮好用的,后面用来替换Db类等用到获取结果集值。
@SuppressWarnings("rawtypes") public static Object getResultSetValue(ResultSet rs, int index, Class requiredType) throws SQLException { if (requiredType == null) { return getResultSetValue(rs, index); } Object value = null; boolean wasNullCheck = false; // Explicitly extract typed value, as far as possible. if (String.class.equals(requiredType)) { value = rs.getString(index); } else if (boolean.class.equals(requiredType) || Boolean.class.equals(requiredType)) { value = rs.getBoolean(index); wasNullCheck = true; } else if (byte.class.equals(requiredType) || Byte.class.equals(requiredType)) { value = rs.getByte(index); wasNullCheck = true; } else if (short.class.equals(requiredType) || Short.class.equals(requiredType)) { value = rs.getShort(index); wasNullCheck = true; } else if (int.class.equals(requiredType) || Integer.class.equals(requiredType)) { value = rs.getInt(index); wasNullCheck = true; } else if (long.class.equals(requiredType) || Long.class.equals(requiredType)) { value = rs.getLong(index); wasNullCheck = true; } else if (float.class.equals(requiredType) || Float.class.equals(requiredType)) { value = rs.getFloat(index); wasNullCheck = true; } else if (double.class.equals(requiredType) || Double.class.equals(requiredType) || Number.class.equals(requiredType)) { value = rs.getDouble(index); wasNullCheck = true; } else if (byte[].class.equals(requiredType)) { value = rs.getBytes(index); } else if (java.sql.Date.class.equals(requiredType)) { value = rs.getDate(index); } else if (java.sql.Time.class.equals(requiredType)) { value = rs.getTime(index); } else if (java.sql.Timestamp.class.equals(requiredType) || java.util.Date.class.equals(requiredType)) { value = rs.getTimestamp(index); } else if (BigDecimal.class.equals(requiredType)) { value = rs.getBigDecimal(index); } else if (Blob.class.equals(requiredType)) { value = rs.getBlob(index); } else if (Clob.class.equals(requiredType)) { value = rs.getClob(index); } else { // Some unknown type desired -> rely on getObject. value = getResultSetValue(rs, index); } // Perform was-null check if demanded (for results that the // JDBC driver returns as primitives). if (wasNullCheck && value != null && rs.wasNull()) { value = null; } return value; }
public static Object getResultSetValue(ResultSet rs, int index) throws SQLException { Object obj = rs.getObject(index); String className = null; if (obj != null) { className = obj.getClass().getName(); } if (obj instanceof Blob) { obj = rs.getBytes(index); } else if (obj instanceof Clob) { obj = rs.getString(index); } else if (className != null && ("oracle.sql.TIMESTAMP".equals(className) || "oracle.sql.TIMESTAMPTZ".equals(className))) { obj = rs.getTimestamp(index); } else if (className != null && className.startsWith("oracle.sql.DATE")) { String metaDataClassName = rs.getMetaData().getColumnClassName(index); if ("java.sql.Timestamp".equals(metaDataClassName) || "oracle.sql.TIMESTAMP".equals(metaDataClassName)) { obj = rs.getTimestamp(index); } else { obj = rs.getDate(index); } } else if (obj != null && obj instanceof java.sql.Date) { if ("java.sql.Timestamp".equals(rs.getMetaData().getColumnClassName(index))) { obj = rs.getTimestamp(index); } } return obj; }
public static String lookupColumnName(ResultSetMetaData resultSetMetaData, int columnIndex) throws SQLException { String name = resultSetMetaData.getColumnLabel(columnIndex); if (name == null || name.length() < 1) { name = resultSetMetaData.getColumnName(columnIndex); } return name; }4、修改com.jfinal.plugin.activerecord下的ModelBuilder类,用上面3个方法来修改build方法,并注释掉buildLabelNamesAndTypes方法。
List<T> result = new ArrayList<T>(); ResultSetMetaData rsmd = rs.getMetaData(); int columnCount = rsmd.getColumnCount(); while (rs.next()) { Model<?> ar = modelClass.newInstance(); Map<String, Object> attrs = ar.getAttrs(); for (int i=1; i<=columnCount; i++) { Object value = DbKit.getResultSetValue(rs, i); attrs.put(DbKit.lookupColumnName(rsmd, i), value); } result.add((T)ar); }同样修改com.jfinal.plugin.activerecord下的RecordBuilder类
for (int i=1; i<=columnCount; i++) { Object value = DbKit.getResultSetValue(rs, i); columns.put(DbKit.lookupColumnName(rsmd, i), value); }5、修改Db类中为rs.getObject,并不需要每个都替换
53行:temp[i] = DbKit.getResultSetValue(rs, i + 1); 60行:result.add(DbKit.getResultSetValue(rs, 1));