badqiu

          XPer
          隨筆 - 46, 文章 - 3, 評論 - 195, 引用 - 0
          數(shù)據(jù)加載中……

          動態(tài)構(gòu)造sql的利器:rapid-xsqlbuider詳細(xì)說明

          特性列表:

          1. 動態(tài)構(gòu)造sql條件語句,提供sql拼接與使用占位符兩種方式
          2. 數(shù)據(jù)類型的修飾
          3. 對SQL注入攻擊的防范

          問題:

          手工構(gòu)造SQL語句的情況

          										
          1?String?sql?=?"select?*?from?user?where?1=1?";
          2?String?user_id?=?(String)filters.get("user_id");
          3?if(?user_id?!=?null?&&?user_id.length()?>?0)?{
          4????sql?=?sql?+?"?and?user_id?=?"?+?user_id;
          5?}
          6?String?age?=?(String)filters.get("age");
          7?if(age?!=?null?&&?age.length()?>?0)?{
          8????sql?=?sql?+?"?and?age?>?"?+?age;
          9?}

          過多的if判斷導(dǎo)致sql語句不清晰,我們再來看下rapid-xsqlbuilder的做法

          rapid-xsqlbuilder構(gòu)造SQL例子

          示例:

          ?1?//?清晰的sql語句,/~?~/為一個(gè)語法塊
          ?2??String?sql=?"select?*?from?user?where?1=1?"?
          ?3??????????+?"/~?and?username?=?{username}?~/"???
          ?4??????????+?"/~?and?password?=?{password}?~/";???
          ?5??
          ?6??//?filters為參數(shù)
          ?7??Map?filters?=?new?HashMap();???
          ?8??filters.put("username",?"badqiu");?
          ?9??filters.put("sex",?"F");??
          10??
          11??XsqlFilterResult?result?=?new?XsqlBuilder().generateHql(sql,filters);
          12??
          13??assertTrue(result.getAcceptedFilters().containsKey("username"));
          14??assertFalse(result.getAcceptedFilters().containsKey("sex"));
          15??assertEquals("select?*?from?user?where?1=1??and?username?=?:username?",?result.getXsql());
          16?

          XsqlFilterResult為處理完返回的東西,包含兩個(gè)屬性xsql,acceptedFilters

          被過濾掉的東西:

          SQL過濾: /~ and password = {password} ~/
          這一段由于在filters中password不存在而沒有被構(gòu)造出來

          filters過濾: sex
          filters中由于沒有類似/~ sex={sex} ~/ 這一段,所以在過濾完的filters中不存在

          最終構(gòu)造生成的結(jié)果

          HQL: XsqlFilterResult.xsql屬性??????????
          select * from user where 1=1 and username=:username??
          ???????
          構(gòu)造后返回的Map filters: XsqlFilterResult.acceptedFilters 屬性
          username=badqiu

          語法

          語法

          /~ {key} ~/
          /~ [key] ~/
          /~ {key_1} [key_2] ... {key_3} ~/
          /~ {key?modifier} ~/
          /~ {key?modifier(arg1,arg2) ~/
          /~ {key?modifier?modifier?...?modifier} ~/

          示例:

          /~ username = {username} ~/
          /~ password like '%[password]%' ~/
          /~ birthDate > {startBirthDate} and birthDate < [endBirthDate] ~/

          數(shù)據(jù)據(jù)類型修飾

          將Map filters中的數(shù)據(jù)類型修飾為另外一種類型

          /~ {username} ~/
          /~ {age?int} ~/
          /~ {birthDate?timestamp(yyyy年MM月dd日)} ~/

          中括號[]與大括號{}的區(qū)別

          中括號會直接替換為其值,用于拼接SQL
          在XsqlFilterResult.getAcceptedFilters()中不會存在該key的值
          如 /~ username like '%[username]%' ~/,如果filters中username=badqiu
          則會生成: username like '%badqiu%'

          大拓號只是起到標(biāo)記作用,用于占位符
          原始方法是XsqlBuilder.applyFilters(sql,filters);
          如"/~ and username = {username} ~/",過濾完還是為 and username = {username}
          但在這時(shí)我們使用將{username}替換為HQL的:username或是SQL的?號

          SQL注入攻擊的防范

          問題:
          拼接的SQL如果不對單引號(有些數(shù)據(jù)庫有反斜杠)進(jìn)行過濾,則會存在SQL注入攻擊問題

          解決:
          使用SafeSqlProcesser,進(jìn)行sql過濾

          										
          1?XsqlBuilder?builder?=?new?XsqlBuilder(SafeSqlProcesserFactory.getMysql());

          SafeSqlProcesser其中的一個(gè)源碼分析

          										
          1?/**
          2??*?過濾單個(gè)單引號為雙引號的SafeSqlFilter<p>
          3??*?適用數(shù)據(jù)庫(MS?SqlServer,Oracle,DB2)
          4??*/
          5?public?String?process(String?value)?{
          6?????if(value?==?null)?return?null;
          7?????return?value.replaceAll("'",?"''");?//?Mysql還需過濾反斜框
          8?}
          9?





          最后不忘為rapid-framework宣傳一下,本工具也集成在里面
          rapid-framework簡介:
          一個(gè)類似 ruby on rails 的java web快速開發(fā)腳手架,本著不重復(fù)發(fā)明輪子的原則,框架只是將零散的struts(struts2)+spring+hibernate各個(gè)組件組裝好在一起,并對struts及struts2進(jìn)行改造,提供零配置編程,并內(nèi)置一個(gè)強(qiáng)大的代碼生成器及模板文件, 可以生成java的hibernat model,dao,manager,struts+struts2 action類,可以生成jsp的增刪改查及列表頁面

          快速演示視頻下載
          代碼生成器生成的增刪改查截圖

          posted on 2008-08-07 09:26 badqiu 閱讀(3670) 評論(12)  編輯  收藏

          評論

          # re: 動態(tài)構(gòu)造sql的利器:rapid-xsqlbuider詳細(xì)說明  回復(fù)  更多評論   

          好東西!支持!
          2008-08-07 12:41 | R_XiaoGuang

          # re: 動態(tài)構(gòu)造sql的利器:rapid-xsqlbuider詳細(xì)說明  回復(fù)  更多評論   

          where 1=1 真tmd的搞笑,這年頭居然還有這種人~
          2008-08-07 13:09 | po

          # re: 動態(tài)構(gòu)造sql的利器:rapid-xsqlbuider詳細(xì)說明[未登錄]  回復(fù)  更多評論   

          @po
          但不知你還有其它更好的辦法?
          2008-08-07 13:13 | badqiu

          # re: 動態(tài)構(gòu)造sql的利器:rapid-xsqlbuider詳細(xì)說明  回復(fù)  更多評論   

          好東西,非常感謝
          @po
          可以不同意,請不要出言不遜,這不是技術(shù)人員討論問題的方式。你可以做出更好的東西show一下啊
          2008-08-07 13:27 | xihuyu2000

          # re: 動態(tài)構(gòu)造sql的利器:rapid-xsqlbuider詳細(xì)說明  回復(fù)  更多評論   

          outputFile


          2008-08-07 14:43 | wdd

          # re: 動態(tài)構(gòu)造sql的利器:rapid-xsqlbuider詳細(xì)說明  回復(fù)  更多評論   

          @po
          where 1=1可以避免很多繁瑣的判斷,而且SQL server在優(yōu)化時(shí)會直接將這句話去掉,不會有什么性能影響。
          2008-08-07 18:59 | lijin

          # re: 動態(tài)構(gòu)造sql的利器:rapid-xsqlbuider詳細(xì)說明  回復(fù)  更多評論   

          跟ibatis比,性能優(yōu)多少?
          有測試過不?

          如果性能差距不大,我情愿選擇ibatis
          2008-08-07 20:34 | galaxystar

          # re: 動態(tài)構(gòu)造sql的利器:rapid-xsqlbuider詳細(xì)說明[未登錄]  回復(fù)  更多評論   

          十萬條下面的語句循環(huán)構(gòu)造,差不多7,8秒吧,具體可以看XsqlBuilderTest.testPerformence();
          性能問題可以忽略不計(jì)

          "select * from user where 1=1"
          +"/~ and username = {username}~/"
          +"/~ and pwd = '[password]'~/"
          +"/~ and age = {age}~/";
          2008-08-07 22:05 | badqiu

          # re: 動態(tài)構(gòu)造sql的利器:rapid-xsqlbuider詳細(xì)說明[未登錄]  回復(fù)  更多評論   

          10萬條循環(huán):
          [PerformenceTest],count:100000 costTime:2406ms
          2008-08-08 10:36 | badqiu

          # re: 動態(tài)構(gòu)造sql的利器:rapid-xsqlbuider詳細(xì)說明  回復(fù)  更多評論   

          where 1=1這句是必須的,你用過就知道了。少了有時(shí)會報(bào)錯(cuò)!
          2009-06-05 21:02 | 事實(shí)上

          # re: 動態(tài)構(gòu)造sql的利器:rapid-xsqlbuider詳細(xì)說明  回復(fù)  更多評論   

          性能問題應(yīng)該不是主要的,不必過多注意
          2011-10-17 03:41 | 注冊公司

          # re: 動態(tài)構(gòu)造sql的利器:rapid-xsqlbuider詳細(xì)說明  回復(fù)  更多評論   

          請問時(shí)間怎么查詢
          2015-10-26 23:57 | 林曉升

          只有注冊用戶登錄后才能發(fā)表評論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 盐城市| 安龙县| 厦门市| 金山区| 屯昌县| 九龙城区| 乾安县| 财经| 沁源县| 阿克陶县| 吴旗县| 桂东县| 晋中市| 威远县| 玉环县| 巨鹿县| 西畴县| 青阳县| 澎湖县| 浙江省| 台东县| 塔河县| 长武县| 石景山区| 柳江县| 毕节市| 南皮县| 辽阳县| 从江县| 碌曲县| 青河县| 伊宁市| 交口县| 奇台县| 丰原市| 犍为县| 祁东县| 福建省| 会昌县| 会宁县| 阿拉尔市|