動態組裝SQL是實際應用中的一個常見問題,我發現在很多論壇中的解決方案都不干淨,下面是我在很多項目中使用的方案,簡洁有效.
基本概念如下:
1. 使用模板技術,如Velocity,FreeMarker;
2. 在SQL中不要使用?,使用自己的place holder ,such as #{variableName};
象下面的SQL語句
select firstName 
      ,lastName 
from users u
where  u.userId= #{userId}
#if($companyId)
  and u.companyId=#{companyId}
#end 
處理過程如下:
1.將所有變量放進一個MAP中;
2.用VELOCITY進行MERGE,將得到以下的SQL,假定companyId 不為空;
  select firstName 
      ,lastName 
from users u
where  u.userId= #{userId}
  and u.companyId=#{companyId}
3.再將上面的SQL進一步處理,根據SQL語句中的placeHolder順序和MAP中的變量,生成一個變量的LIST,同時將變量的placeHolder轉換成?;
4.將變量LIST的數值依次注入到preparedStatement中;
		
				
						  Tips:
				這里還可生成一個完全可執行的
				SQL
				語句輸出到
				LOG
				中
				,
				以便進行除錯;
5.執行SQL, 用reflection技術將ResultSet轉換成voList;
		
				
						 
		
		
				將上面的過程封裝成一個
				Class , 
				只需將
				sqlName,parameterMap,voClass
				傳入便可返回一個
				voList
				或數組
				. 
				此舉將大大減化
				DAO
				的代碼
				,
				根據我的經驗
				,
				代碼最起碼減少
				70%,
				更為重要的是查詢非常容易維護
				, 
				極大地減少了出錯的概率
				,SQL
				語句清晰易懂
				,
				不再是醜陋的
				criteria,
				也不再是將一個個的分散的
				SQL
				片斷
				,
				我們的程序員將會有更多的時間來寫
				SQL,
				而不是做其它讓人厭煩的工作
				,
				排錯也變得异常簡單
				,
				唯一可能出錯的地方只能在
				SQL
				上
				, 
				只要將
				LOG
				輸出的完整可執行
				SQL
				放在
				database client
				中執行一下
				,
				問題在哪兒
				,
				一目了然
				.
		
		
				我相信此方法
				
				
				比起
				iBatis, Spring
				的
				jdbcTemplate,Hibernate 
				的
				Criteria
				要容易使用得多
				.
				其實
				Hibernate
				的
				HQL,
				也可以用此方法來動態生成
				HQL.