久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

JDBC中Statement和PrepareStatement的區(qū)別及特性

 昵稱35402089 2016-08-04

主要區(qū)別:

    Statement執(zhí)行一條sql就得編譯一次,PrepareStatement只編譯一次,;常用后者原因在于參數(shù)設(shè)置非常方便,;執(zhí)行一條sql就得編譯一次,后者只編譯一次,;還有就是sql放置的位置不同; 常用后者原因在于參數(shù)設(shè)置非常方便,;


特性:

    jdbc的api中的主要的四個(gè)類之一的java.sql.statement要求開發(fā)者付出大量的時(shí)間和精力,。在使用statement獲取jdbc訪問時(shí)所具有的一個(gè)共通的問題是輸入適當(dāng)格式的日期和時(shí)間戳:2002-02-05 20:56 或者 02/05/02 8:56 pm。

    通過使用java.sql.preparedstatement,,這個(gè)問題可以自動(dòng)解決,。一個(gè)preparedstatement是從 java.sql.connection對象和所提供的sql字符串得到的,sql字符串中包含問號(?),,這些問號標(biāo)明變量的位置,,然后提供變量的值, 最后執(zhí)行語句,,例如: 

stringsql = 'select * from people p where p.id = ? and p.name = ?';

preparedstatement ps = connection.preparestatement(sql);

ps.setint(1,id);

ps.setstring(2,name);

resultset rs = ps.executequery();

 
   使用preparedstatement的另一個(gè)優(yōu)點(diǎn)是字符串不是動(dòng)態(tài)創(chuàng)建的,。下面是一個(gè)動(dòng)態(tài)創(chuàng)建字符串的例子: 

  stringsql = 'select * from people p where p.i = '+id; 

  preparedstatement也提供數(shù)據(jù)庫無關(guān)性。當(dāng)顯示聲明的sql越少,,那么潛在的sql語句的數(shù)據(jù)庫依賴性就越小,。

  由于preparedstatement具備很多優(yōu)點(diǎn),開發(fā)者可能通常都使用它,,只有在完全是因?yàn)樾阅茉蚧蛘呤窃谝恍衧ql語句中沒有變量的時(shí)候才使用通常的statement,。

一個(gè)完整的preparedstatement的例子:

package jstarproject;
import java.sql.*;

public class mypreparedstatement {

private final string db_driver='com.microsoft.jdbc.sqlserver.sqlserverdriver';
private final string url = 'jdbc:microsoft:sqlserver://127.0.0.1:1433;databasename=pubs';

  public mypreparedstatement() 
  {
  }
  public void query() throws sqlexception{
    connection conn = this.getconnection();
    string strsql = 'select emp_id from employee where emp_id = ?';
    preparedstatement pstmt = conn.preparestatement(strsql);
    pstmt.setstring(1,'pma42628m');
    resultset rs = pstmt.executequery();


    while(rs.next()){
       string fname = rs.getstring('emp_id');
       system.out.println('the fname is ' + fname);
    }
    rs.close();
    pstmt.close();
    conn.close();

  }
  private connection getconnection() throws sqlexception{
//    class.
    connection conn = null;
    try {
      class.forname(db_driver);
      conn = drivermanager.getconnection(url,'sa','sa');
    }
    catch (classnotfoundexception ex) {}
    return conn;
  }
  //main
  public static void main(string[] args) throws sqlexception {
    mypreparedstatement jdbctest1 = new mypreparedstatement();
    jdbctest1.query();
  }
}



為什么要始終使用PreparedStatement代替Statement?為什么要始終使用PreparedStatement代替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();


二.PreparedStatement盡最大可能提高性能.


    每一種數(shù)據(jù)庫都會(huì)盡最大努力對預(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ù)編譯語句被緩存,而是對于整個(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ì)對普通語句編譯后的執(zhí)行代碼緩存.

    當(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)系.只要全使用預(yù)編譯語句,你就用不著對傳入的數(shù)據(jù)做任何過慮.而如果使用普通的statement,有可能要對drop,;等做費(fèi)盡心機(jī)的判斷和過慮.


 

    本站是提供個(gè)人知識管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn),。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多