Browse Source

jfinal 3.5

James 7 years ago
parent
commit
50ba6c1d0b

+ 48 - 0
src/main/java/com/jfinal/plugin/activerecord/generator/MetaBuilder.java

@@ -275,6 +275,9 @@ public class MetaBuilder {
 					typeStr = "java.lang.String";
 				}
 			}
+			
+			typeStr = handleJavaType(typeStr, rsmd, i);
+			
 			cm.javaType = typeStr;
 			
 			// 构造字段对应的属性名 attrName
@@ -288,6 +291,51 @@ public class MetaBuilder {
 	}
 	
 	/**
+	 * handleJavaType(...) 方法是用于处理 java 类型的回调方法,当 jfinal 默认
+	 * 处理规则无法满足需求时,用户可以通过继承 MetaBuilder 并覆盖此方法定制自己的
+	 * 类型转换规则
+	 * 
+	 * 当前实现只处理了 Oracle 数据库的 NUMBER 类型,根据精度与小数位数转换成 Integer、
+	 * Long、BigDecimal。其它数据库直接返回原值 typeStr
+	 * 
+	 * Oracle 数据库 number 类型对应 java 类型:
+	 *  1:如果不指定number的长度,或指定长度 n > 18
+	 *     number 对应 java.math.BigDecimal
+	 *  2:如果number的长度在10 <= n <= 18
+	 *     number(n) 对应 java.lang.Long
+	 *  3:如果number的长度在1 <= n <= 9
+	 *     number(n) 对应 java.lang.Integer 类型
+	 * 
+	 * 社区分享:《Oracle NUMBER 类型映射改进》http://www.jfinal.com/share/1145
+	 */
+	protected String handleJavaType(String typeStr, ResultSetMetaData rsmd, int column) throws SQLException {
+		// 当前实现只处理 Oracle
+		if ( ! dialect.isOracle() ) {
+			return typeStr;
+		}
+		
+		// 默认实现只处理 BigDecimal 类型
+		if ("java.math.BigDecimal".equals(typeStr)) {
+			int scale = rsmd.getScale(column);			// 小数点右边的位数,值为 0 表示整数
+			int precision = rsmd.getPrecision(column);	// 最大精度
+			if (scale == 0) {
+				if (precision <= 9) {
+					typeStr = "java.lang.Integer";
+				} else if (precision <= 18) {
+					typeStr = "java.lang.Long";
+				} else {
+					typeStr = "java.math.BigDecimal";
+				}
+			} else {
+				// 非整数都采用 BigDecimal 类型,需要转成 double 的可以覆盖并改写下面的代码
+				typeStr = "java.math.BigDecimal";
+			}
+		}
+		
+		return typeStr;
+	}
+	
+	/**
 	 * 构造 colName 所对应的 attrName,mysql 数据库建议使用小写字段名或者驼峰字段名
 	 * Oralce 反射将得到大写字段名,所以不建议使用驼峰命名,建议使用下划线分隔单词命名法
 	 */