因為種種原因例如安全(SQL Injection),效能等
所以使用JAVA的preparedstatment 方式
但是preparedstatment 很難使用動態方式
例如
select * from tablea where colb in ???
例如colb是使用者可多選擇的, 例如有b1 b2 b3 ~ bN不等
使用可以任意選擇多個,因此 colb in 就不知道要幾個了
因為preparedstatment 使用 sql 跟 參數(有順序)的方式
使得SQL很難共用
例如
1.
select * from tablea
where akey = ?
and adel is null
and amrk in ('A','B')
and adate1 between ? and ?
2.
select * from tablea
where akey = ?
and adel is null
and amrk in ('A','B')
and akind in (?,?,?,...)
上面兩個SQL很明顯的重復下面
select * from tablea
where akey = ?
and adel is null
and amrk in ('A','B')
但是如果希望可以重復使用的話,就很難整合
因為 akey=? 要怎麼整合
String basicsql = "select * from tablea where akey = ? and adel is null and amrk in ('A','B')";
List queryAdate(String akey,Date date1,Date date2){
...
sql = String.format("%s and adate1 between ? and ?",basicsql );
args = new Object[]{akey,date1,date2};
...
}
List queryAmrk(String akey,String [] mrklist){
...
sql = String.format("%s and akind in (?,?,?,...)",basicsql );
args = new Object[]{akey,mrklist....};--?這裡就???
...
}
又最常見的條件查詢
select * from tablea where atype = ? and akind in (?,?..) and aprice between ? and ? and aname like '?%'
其中 atype akind aprice aname 四個條件可以自由選擇
所以
sql = "select * from tablea where";
if StringUtils.isNotEmpty(atype ) {
sql+="and atype =?";
}
if akind .length > 0 {
sql+="and akind in (?,?..) ";
}
if aprice .length == 2 {
sql+="aprice between ? and ? ";
}
if StringUtils.isNotEmpty(aname ) {
sql+="and aname like '?%'";
}
其中要處理and 或是用很奇怪的 1=1
並且在參數方面也會不好用
因此針對preparedstatment,提出了模組化的需求
以下是測試範例
https://github.com/swpoker/sql/blob/master/sqltest/com/swpoker/util/sql/test/SQLTest.java
1.將SQL及參數封裝起來
2.提供一些方法使用
以上述的案例就會變成
void query(String atype , String [] akind ,int [] aprice ,String name)
sqlclause=SQLFactory.SQL().append("select * from tablea where")
.append(SQLFactory.WHERE()
.test(StringUtils.isNotEmpty(atype )).add("atype =?",atype )
.test(akind .length > 0 ).add(SQLFactory.IN("akind in (%?)",akind ))
.test(aprice .length == 2).add("aprice between ? and ? ",aprice[0],aprice[1] )
.test(StringUtils.isNotEmpty(aname )).add("aname like '?%'",name)
)
String sql = sqlclause.sql();
Object[] args = sqlclause.args();
此套件為
1.提供preparedstatment模組化
2.提供方便的語法
沒有留言:
張貼留言