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

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

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

    yeshucheng
    追逐自己,追逐方向,心隨悟所動
    posts - 24,comments - 24,trackbacks - 0

    在JDBC應用中,如果你已經是稍有水平開發者,你就應該始終以PreparedStatement代替Statement.也就是說,在任何時候都不要使用Statement.
    基于以下的原因:
    一.代碼的可讀性和可維護性.
    雖然用PreparedStatement來代替Statement會使代碼多出幾行,但這樣的代碼無論從可讀性還是可維護性上來說.都比直接用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();

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

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

    當然并不是所以預編譯語句都一定會被緩存,數據庫本身會用一種策略,比如使用頻度等因素來決定什么時候不再緩存已有的預編譯結果.以保存有更多的空間存儲新的預編譯語句.

    三.最重要的一點是極大地提高了安全性.

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

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

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

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

     

     

    有的新人可能此時對于用法還不太理解下面給個小例子

    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對應第一個? 2對應第二個? 同時注意你set 的類型 是int還是string  哈哈很簡單吧


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

    posted @ 2010-12-14 13:58 葉澍成| 編輯 收藏

    //ValueObject類

    public class AdEntity {
        
    private String id;
        
    private String name;
        
    private String broker;
        
    private String date;
        
    private String body;
        
    //get/set
        
        
    public String toString(){
            
    return "【編號為:"+id+",廣告名稱為:"+name+",代理商為:"+broker+",發布日期為:"+date+",內容為:"+body+"";
        }
    }

    //調用任務類

    public class AdTask implements Callable<AdEntity> {
        @Override
        
    public AdEntity call() throws Exception {
            
    // 模擬遠程調用花費的一些時間
            Thread.sleep(5*1000);
            AdEntity vo
    =new AdEntity();
            vo.setId(String.valueOf(
    new Random().nextInt(1000)));
            vo.setName(
    "Ad@內衣廣告");
            vo.setBroker(
    "CHANNEL");
            Date date
    =new Date();
            SimpleDateFormat sdf
    =new SimpleDateFormat("yyyy-MM-dd");
            String dateStr
    =sdf.format(date);
            vo.setDate(dateStr);
            vo.setBody(
    "遠端內容");
            
    return vo;
        }
    }

    //主函數

    public class TestQueryMemg {
        
        
    /**
         * 
    @param args
         * 
    @throws ExecutionException 
         * 
    @throws InterruptedException 
         
    */
        
    public static void main(String[] args) throws InterruptedException, ExecutionException {
            ExecutorService exec
    =Executors.newCachedThreadPool();
            
    //創建Future來完成網絡調用任務
            Callable<AdEntity> returnAd=new AdTask();
            Future
    <AdEntity> future=exec.submit(returnAd);
            
            
    //開始執行本地化查詢信息
            AdEntity localAd=new AdEntity();
            localAd.setId(String.valueOf(
    new Random().nextInt(1000)));
            localAd.setName(
    "Ad@食品廣告");
            localAd.setBroker(
    "蒙牛");
            SimpleDateFormat sdf
    =new SimpleDateFormat("yyyy-MM-dd");
            String dateStr
    =sdf.format(new Date());
            localAd.setDate(dateStr);
            localAd.setBody(
    "內容本地");

            System.out.println(
    "當前本地化查詢內容為:"+localAd.toString());
            System.out.println(
    "稍等片刻以獲取遠端信息");
            
            
    while(!future.isDone()){
                
    try {
                    Thread.sleep(
    1*1000);
                } 
    catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            AdEntity entityRemote
    =(AdEntity)future.get();

            System.out.println(
    "合并查詢內容為:\n"+localAd.toString()+"\n"+entityRemote.toString());
        }
    }


     

     

     

    posted @ 2010-12-12 14:44 葉澍成| 編輯 收藏

    個人賬戶類:

    public class PrivateAccount implements Callable {
        Integer total;
        
    public Object call() throws Exception {
            Thread.sleep(
    5*1000);
            total
    =new Integer(new Random().nextInt(10000));
            System.out.println(
    "您個人賬戶上還有"+total+" 存款可以支配");
            
    return total;
        }
    }

    主函數測試:

    public class SumTest {
        
    /**
         * 
    @param args
         * 
    @throws ExecutionException 
         * 
    @throws InterruptedException 
         
    */
        
    public static void main(String[] args) throws InterruptedException, ExecutionException {
            Callable privateAccount
    =new PrivateAccount();
            FutureTask task
    =new FutureTask(privateAccount);
                    
    //創建新線程獲取個人賬戶信息
            Thread thread=new Thread(task);
            thread.start();

            
    int total=new Random().nextInt(1000);
            System.out.println(
    "主線程在這工作");
            System.out.println(
    "您目前操作金額為: "+total+" .");
            System.out.println(
    "請等待計算個人賬戶的金額");
            
    while(!task.isDone()){//判斷是否已經獲取返回值
                try {
                    Thread.sleep(
    3*1000);
                } 
    catch (InterruptedException e) {
                    
    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            Integer privateSingle
    =(Integer)task.get();
            
    int post=privateSingle.intValue();
            
            System.out.println(
    "您當前賬戶共有金額為:"+(total+post)+" ¥");
        }

    }


     

     

    posted @ 2010-12-10 20:53 葉澍成| 編輯 收藏
    主站蜘蛛池模板: 亚洲精品中文字幕麻豆| 老司机亚洲精品影院在线观看| 亚洲免费视频网址| 国产精品亚洲片夜色在线| 免费无码又爽又高潮视频| 国产精品免费大片一区二区| 亚洲综合亚洲国产尤物| 国产三级免费观看| 无码人妻一区二区三区免费n鬼沢| 激情综合亚洲色婷婷五月APP| 亚洲精品色婷婷在线影院| 91久久精品国产免费一区| 国产成人亚洲综合无| 亚洲好看的理论片电影| 国产成人无码a区在线观看视频免费| 日本免费A级毛一片| 亚洲精品国产高清在线观看| 亚洲AV无码专区国产乱码电影| 在线观看免费污视频| 成人电影在线免费观看| 亚洲av日韩av永久无码电影| 亚洲成人精品久久| 深夜国产福利99亚洲视频| 最近中文字幕大全中文字幕免费| 边摸边脱吃奶边高潮视频免费| 亚洲欧洲国产精品久久| 亚洲情侣偷拍精品| 免费爱爱的视频太爽了| 91精品手机国产免费| 国产精品福利在线观看免费不卡| 亚洲国产日韩视频观看| 亚洲AV本道一区二区三区四区| gogo全球高清大胆亚洲| 亚洲一区在线免费观看| 免费av一区二区三区| 国产99久久久国产精免费| 狠狠入ady亚洲精品| 久久久久亚洲av无码专区导航| 亚洲一级特黄大片在线观看| 成年轻人网站色免费看| 日韩免费一区二区三区在线播放|