JFinal源碼分析------快速開發利器的那些事兒

在之前,咱們作WEB開發的時候經常會遇到這麼一個問題,就是當FORM表單進行提交咱們所填寫的數據的時候,每每會要在後臺程序中去接受前臺的各類數據。 固然 在前臺小系統或者頁面中FORM表單中須要提交的數據不多的時候,在後臺接受這些參數也無可厚非,不過等一個系統作完之後,咱們忽然發現,咱們花了不少的時間去接受參數,作的多了,就會忽然以爲 接受參數這個東西絕對是個體力活,並且格式比較固定,作多了就感受膩歪了! 因此,本着「懶人改變世界」的觀點,我準備看看JFinal的底層都作了些啥,這樣就能夠更好的瞭解這個框架,和使用這個框架,好了,廢話不說,直接開八!數據庫

這個JFinal中我以爲我用得最爽的就是這個方法: getModel(Code.class) 爲何這麼說了,由於用了這個方法之後,我就不用重複的去接受前臺傳來的參數,而後一個一個的進行賦值,有這些時間,我估計個人電影都看完了。咱們來看看這個方法裏面都作些啥!! 打開這個方法: public <T> T getModel(Class<T> modelClass) { return (T)ModelInjector.inject(modelClass, request, false); }app

能夠看到 ,他用一個ModelInjector.inject()這麼個方法,繼續走到這個方法裏面,咱們能夠看到如下的方法: public static <T> T inject(Class<?> modelClass, HttpServletRequest request, boolean skipConvertError) { String modelName = modelClass.getSimpleName(); return inject(modelClass, StringKit.firstCharToLowerCase(modelName), request, skipConvertError); }框架

在這個方法中,咱們能夠看到他作了兩個操做,一個是去傳入類名的簡單類名。一個就是返回inject的值,尚未到底,接着打開這個方法,代碼以下: public static final <T> T inject(Class<?> modelClass, String modelName, HttpServletRequest request, boolean skipConvertError) { Object model = null; try { model = modelClass.newInstance(); } catch (Exception e) { throw new ModelInjectException(e); }code

if (model instanceof Model)
		injectActiveRecordModel((Model)model, modelName, request, skipConvertError);
	else
		injectCommonModel(model, modelName, request, modelClass, skipConvertError);
	
	return (T)model;
}

你看到了什麼? 對,你忽然發現 Model是個Object,而後model是經過反射生成的,爲何要使用Object做爲最初的Model的類型,我猜測是,由於我不知道傳入的是什麼東西,爲了可以接受傳入的全部類型,他使用了一個Object,不知道這麼個猜測是否是對的,若是有錯誤,請留言更正啊!!在model被建立了之後,咱們看到了它作了一個判斷,看他是否爲Model類型的實例,因此這樣就是爲何咱們定義的類要繼承Model的緣由吧!!好了 繼續吧,重頭戲就要來了,程序運行到這裏就到了injectActiveRecordModel這個方法了,打開這個方法,咱們能夠看到以下的代碼:繼承

private static final void injectActiveRecordModel(Model<?> model, String modelName, HttpServletRequest request, boolean skipConvertError) { TableInfo tableInfo = TableInfoMapping.me().getTableInfo(model.getClass());ip

String modelNameAndDot = modelName + ".";
	
	Map<String, String[]> parasMap = request.getParameterMap();
	for (Entry<String, String[]> e : parasMap.entrySet()) {
		String paraKey = e.getKey();
		if (paraKey.startsWith(modelNameAndDot)) {
			String paraName = paraKey.substring(modelNameAndDot.length());
			Class colType = tableInfo.getColType(paraName);
			if (colType == null)
				throw new ActiveRecordException("The model attribute " + paraKey + " is not exists.");
			String[] paraValue = e.getValue();
			try {
				// Object value = Converter.convert(colType, paraValue != null ? paraValue[0] : null);
				Object value = paraValue[0] != null ? TypeConverter.convert(colType, paraValue[0]) : null;
				model.set(paraName, value);
			} catch (Exception ex) {
				if (skipConvertError == false)
					throw new ModelInjectException("Can not convert parameter: " + modelNameAndDot + paraName, ex);
			}
		}
	}
}

}開發

簡單的說下他幹了些什麼事情:字符串

一、首先將上次傳入的簡單類名進行了簡單的處理,在後面加了一個 「.」,這也就是爲何在咱們在使用getModel這個方法的時候要使用「簡單類名+.+數據庫列字段」這麼一種形式了get

二、截取字符串,就是拿到數據庫中的列字段,舉個例子,加入個人某一個表單控件中的名字是「code.name」,那麼他在截取了之後,就拿到了name這個字符串string

三、判斷再判斷拿到這個控件中的值的類型,也就是這句話的做用 Class colType = tableInfo.getColType(paraName);

四、將獲取到的值存入一個數字,而後在進行數據類型的轉換。

五、最後就循環的使用model.set(paraName, value)來賦值

這樣的話,就基本完成了接受參數,賦值的過程,固然 在數據的底層還進行了不少的操做 這個已經超出了今天討論的話題了,之後有機會再開始八!!悄悄的說一下,其實對數據庫的底層是使用PreparedStatement乾的,再結合各類字符串拼接技術實現的!!有興趣的程序猿們能夠扒開他的衣服看看他吃赤裸的肉體!!!嘿嘿 我又邪惡鳥!!!

歡迎OSC的各位大牛批評指點,言語犀利的就不要留言了 我臉皮薄 經不起狂轟濫炸!!

相關文章
相關標籤/搜索