<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    yeshucheng
    追逐自己,追逐方向,心隨悟所動(dòng)
    posts - 24,comments - 24,trackbacks - 0

    在JDBC應(yīng)用中,如果你已經(jīng)是稍有水平開發(fā)者,你就應(yīng)該始終以PreparedStatement代替Statement.也就是說,在任何時(shí)候都不要使用Statement.
    基于以下的原因:
    一.代碼的可讀性和可維護(hù)性.
    雖然用PreparedStatement來代替Statement會(huì)使代碼多出幾行,但這樣的代碼無論從可讀性還是可維護(hù)性上來說.都比直接用Statement的代碼高很多檔次:

    stmt.executeUpdate("insert into tb_name (col1,col2,col2,col4) values ('"+var1+"','"+var2+"',"+var3+",'"+var4+"')");

    perstmt = con.prepareStatement("insert into tb_name (col1,col2,col2,col4) values (?,?,?,?)");
    perstmt.setString(1,var1);
    perstmt.setString(2,var2);
    perstmt.setString(3,var3);
    perstmt.setString(4,var4);
    perstmt.executeUpdate();

    不用我多說,對(duì)于第一種方法.別說其他人去讀你的代碼,就是你自己過一段時(shí)間再去讀,都會(huì)覺得傷心.

    二.PreparedStatement盡最大可能提高性能.
    每一種數(shù)據(jù)庫都會(huì)盡最大努力對(duì)預(yù)編譯語句提供最大的性能優(yōu)化.因?yàn)轭A(yù)編譯語句有可能被重復(fù)調(diào)用.所以語句在被DB的編譯器編譯后的執(zhí)行代碼被緩存下來,那么下次調(diào)用時(shí)只要是相同的預(yù)編譯語句就不需要編譯,只要將參數(shù)直接傳入編譯過的語句執(zhí)行代碼中(相當(dāng)于一個(gè)涵數(shù))就會(huì)得到執(zhí)行.這并不是說只有一個(gè) Connection中多次執(zhí)行的預(yù)編譯語句被緩存,而是對(duì)于整個(gè)DB中,只要預(yù)編譯的語句語法和緩存中匹配.那么在任何時(shí)候就可以不需要再次編譯而可以直接執(zhí)行.而statement的語句中,即使是相同一操作,而由于每次操作的數(shù)據(jù)不同所以使整個(gè)語句相匹配的機(jī)會(huì)極小,幾乎不太可能匹配.比如:
    insert into tb_name (col1,col2) values ('11','22');
    insert into tb_name (col1,col2) values ('11','23');
    即使是相同操作但因?yàn)閿?shù)據(jù)內(nèi)容不一樣,所以整個(gè)個(gè)語句本身不能匹配,沒有緩存語句的意義.事實(shí)是沒有數(shù)據(jù)庫會(huì)對(duì)普通語句編譯后的執(zhí)行代碼緩存.這樣每執(zhí)行一次都要對(duì)傳入的語句編譯一次.

    當(dāng)然并不是所以預(yù)編譯語句都一定會(huì)被緩存,數(shù)據(jù)庫本身會(huì)用一種策略,比如使用頻度等因素來決定什么時(shí)候不再緩存已有的預(yù)編譯結(jié)果.以保存有更多的空間存儲(chǔ)新的預(yù)編譯語句.

    三.最重要的一點(diǎn)是極大地提高了安全性.

    即使到目前為止,仍有一些人連基本的惡義SQL語法都不知道.
    String sql = "select * from tb_name where name= '"+varname+"' and passwd='"+varpasswd+"'";
    如果我們把[' or '1' = '1]作為varpasswd傳入進(jìn)來.用戶名隨意,看看會(huì)成為什么?

    select * from tb_name = '隨意' and passwd = '' or '1' = '1';
    因?yàn)?1'='1'肯定成立,所以可以任何通過驗(yàn)證.更有甚者:
    把[';drop table tb_name;]作為varpasswd傳入進(jìn)來,則:
    select * from tb_name = '隨意' and passwd = '';drop table tb_name;有些數(shù)據(jù)庫是不會(huì)讓你成功的,但也有很多數(shù)據(jù)庫就可以使這些語句得到執(zhí)行.

    而如果你使用預(yù)編譯語句.你傳入的任何內(nèi)容就不會(huì)和原來的語句發(fā)生任何匹配的關(guān)系.(前提是數(shù)據(jù)庫本身支持預(yù)編譯,但上前可能沒有什么服務(wù)端數(shù)據(jù)庫不支持編譯了,只有少數(shù)的桌面數(shù)據(jù)庫,就是直接文件訪問的那些)只要全使用預(yù)編譯語句,你就用不著對(duì)傳入的數(shù)據(jù)做任何過慮.而如果使用普通的statement, 有可能要對(duì)drop,;等做費(fèi)盡心機(jī)的判斷和過慮.

    上面的幾個(gè)原因,還不足讓你在任何時(shí)候都使用PreparedStatement嗎?

     

     

    有的新人可能此時(shí)對(duì)于用法還不太理解下面給個(gè)小例子

    Code Fragment 1:

    String updateString = "UPDATE COFFEES SET SALES = 75 " + "WHERE COF_NAME LIKE ′Colombian′"; 
    stmt.executeUpdate(updateString);

    Code Fragment 2:

    PreparedStatement updateSales = con.prepareStatement("UPDATE COFFEES SET SALES = ? WHERE COF_NAME LIKE ? "); 
    updateSales.setInt(1, 75); 
    updateSales.setString(2, "Colombian"); 
    updateSales.executeUpdate();

    set中的1對(duì)應(yīng)第一個(gè)? 2對(duì)應(yīng)第二個(gè)? 同時(shí)注意你set 的類型 是int還是string  哈哈很簡單吧


    原文出處:http://blog.csdn.net/spcusa/archive/2009/05/09/4164076.aspx

    posted on 2010-12-14 13:58 葉澍成 閱讀(520) 評(píng)論(0)  編輯  收藏 所屬分類: 數(shù)據(jù)庫
    主站蜘蛛池模板: yellow免费网站| 最近中文字幕mv免费高清电影 | 无码国产精品一区二区免费式直播 | 182tv免费视频在线观看| 国产精品久免费的黄网站| 又长又大又粗又硬3p免费视频| 精品国产麻豆免费网站| 国产成人无码免费看片软件| 久久久无码精品亚洲日韩按摩| 手机在线毛片免费播放| 99精品免费视品| 亚洲资源最新版在线观看| 国产精品亚洲αv天堂无码| 99re免费99re在线视频手机版| 亚洲午夜无码久久| 亚洲av午夜福利精品一区人妖| 成年女人视频网站免费m| 91免费国产视频| 狠狠综合亚洲综合亚洲色| 亚洲国产精品一区二区久久| 国产免费怕怕免费视频观看| 亚洲爆乳无码精品AAA片蜜桃| 日韩免费高清视频网站| 精品免费视在线观看| 国产产在线精品亚洲AAVV| 亚洲AV无码一区二区三区在线观看 | 日韩va亚洲va欧洲va国产| 国产精品成人免费综合| 91制片厂制作传媒免费版樱花| 曰批全过程免费视频免费看 | 国产一级淫片免费播放| 亚洲视频免费播放| 久久精品国产亚洲AV久| 免费看污成人午夜网站| 国产精品偷伦视频免费观看了| 亚洲色大情网站www| 亚洲人色大成年网站在线观看| 亚洲AV无码第一区二区三区| 亚洲成a人片在线观看日本麻豆 | 毛色毛片免费观看| 99久久久国产精品免费蜜臀|