java入門第三步之數據庫連接


數據庫連接可以說是學習web最基礎的部分,也是非常重要的一部分,今天我們就來介紹下數據庫的連接為下面學習真正的web打下基礎

java中連接數據庫一般有兩種方式:

1.ODBC——Open Database Connectivity(開放數據庫連接性):基於C語言的一套數據庫編程接口,主要功能是提供數據庫的訪問和操作
所有的數據庫廠商對這套接口進行實現,不同數據庫廠商提供的實現是不一樣的,也就是通常所說的第三方支持,而這套編程接口就是我們的標准

2.JDBC——Java Database Connectivity(java版的ODBC)
專門為java語言提供的一套訪問操作數據庫的編程標准,由sun公司提供,所有可以被java語言操作的數據庫廠商都對其進行了實現

我們一般都是采用JDBC,優勢:

1.效率上jdbc會相對的高一些

2.安全角度來考慮,jdbc比odbc高

3.jdbc使用非常方便,只要加入相應的驅動包就可以了,而不像odbc還需要Jdbc-odbc橋驅動

4.使用jdbc可以很方便在各類數據庫間進行更換,只要更改相應的驅動就可以了

下面列舉用jdbc連接各類數據庫的方式:

常用JDBC連接數據庫方法總結如下:

一、JDBC連接DB2
Class.forName("Com.ibm.db2.jdbc.net.DB2Driver"); 
String url="jdbc:db2://dburl:port/DBname" 
cn = DriverManager.getConnection( url, sUsr, sPwd );

二、JDBC連接Microsoft SQLServer(microsoft)
Class.forName( "com.microsoft.jdbc.sqlserver.SQLServerDriver" ); 
cn = DriverManager.getConnection( "jdbc:microsoft:sqlserver://DBServerIP:1433;databaseName=master", sUsr, sPwd ); 

三、JDBC連接Sybase(jconn2.jar)
Class.forName( "com.sybase.jdbc2.jdbc.SybDriver" ); 
cn = DriverManager.getConnection( "jdbc:sybase:Tds:DBServerIP:2638", sUsr, sPwd ); 

四、JDBC連接MySQL(mm.mysql-3.0.2-bin.jar)
Class.forName( "org.gjt.mm.mysql.Driver" ); 
cn = DriverManager.getConnection( "jdbc:mysql://DBServerIP:3306/myDatabaseName", sUsr, sPwd ); 

五、JDBC連接PostgreSQL(pgjdbc2.jar)
Class.forName( "org.postgresql.Driver" ); 
cn = DriverManager.getConnection( "jdbc:postgresql://DBServerIP/myDatabaseName", sUsr, sPwd ); 

六、JDBC連接Oracle(classes12.jar)
Class.forName( "oracle.jdbc.driver.OracleDriver" ); 
cn = DriverManager.getConnection( "jdbc:oracle:thin:@MyDbComputerNameOrIP:1521:ORCL", sUsr, sPwd ); 

七、JDBC連接ODBC 
Class.forName( "sun.jdbc.odbc.JdbcOdbcDriver" ); 
Connection cn = DriverManager.getConnection( "jdbc:odbc:" + sDsn, sUsr, sPwd ); 

下面我以Microsoft SQLServer 2000為例進行數據庫連接的講解,我們在連接前先將jar包放到項目的lib目錄下,這里我們只需jtds-1.2.5.jar

下面我們先來看一段完整連接數據庫代碼:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

public class JdbcTest {
    //數據庫的連接驅動,一般是不需要變的
    private static final String DRIVER="com.microsoft.jdbc.sqlserver.SQLServerDriver";
    //數據庫連接的URL,1433為默認的數據庫端口號,test為當前你要操作的數據庫名
    private static final String URL="jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=test";
    //登錄賬戶
    private static final String DBNAME="sa";
    //登錄的密碼
    private static final String DBPASS="123";

    public void test(){
     Connection con=null;    
     PreparedStatement psm=null;
     ResultSet rs=null;
     try{    
         Class.forName(DRIVER);
         con = DriverManager.getConnection(URL,DBNAME,DBPASS);
         String sql="select* from admin where id=1";
         psm=con.prepareStatement(sql);
         rs=psm.executeQuery();
         while(rs.next()){
            System.out.println(rs.getString("aPassword"));
         }
     }catch(Exception e){
         con.close();
         rs.close();
         psm.close();
         e.printStackTrace();
     }finally{
            if(rs!=null){
              rs.close();
            }
            if(psm==null){
            psm.close();
            }
            if(con!=null){
                  con.close();
            }
    }
  }

}

 

對於上面的數據庫連接查詢,我們分6步來進行分析:
a.加載JDBC驅動程序:

在連接數據庫之前,首先要加載想要連接的數據庫的驅動到JVM(Java虛擬機),這通過java.lang.Class類的靜態方法forName(String  className)實現。  

如上面代碼:Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");  我們在單獨進行連接時一般要在進行異常的捕獲,即加上try..catch

try{

  Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");   

}catch(ClassNotFoundException e){  

  System.out.println("找不到驅動程序類 ,加載驅動失敗!");  

  e.printStackTrace() ;  

}  

成功加載后,會將Driver類的實例注冊到DriverManager類中。

 

b.提供JDBC連接的URL並進行連接 :

如上面的代碼:(也進行異常的捕獲)

private static final String URL="jdbc:microsoft:sqlserver://localhost:1433;DatabaseName=test";
private static final String DBNAME="sa";
private static final String DBPASS="123";

try{

  con = DriverManager.getConnection(URL,DBNAME,DBPASS);

}catch{
  System.out.println("數據庫連接失敗");

  e.printStackTrace() ;  

}

 

c.創建一個Statement  

  •要執行SQL語句,必須獲得java.sql.Statement實例,Statement實例分為以下3種類型:  

  1.執行靜態SQL語句。通常通過Statement實例實現。  

  2.執行動態SQL語句。通常通過PreparedStatement實例實現。  

  3.執行數據庫存儲過程。通常通過CallableStatement實例實現。  

  具體的實現方式:  

  1.Statement stmt = con.createStatement() ;  

  2.如上代碼:PreparedStatement psm = con.prepareStatement(sql) ;  

  3.CallableStatement cstmt = con.prepareCall("{CALL demoSp(? , ?)}") ;  

 

d.執行SQL語句  

  Statement接口提供了三種執行SQL語句的方法:executeQuery 、executeUpdate  和execute  

  1.ResultSet executeQuery(String sqlString):執行查詢數據庫的SQL語句 ,返回一個結果集(ResultSet)對象。  

  2.int executeUpdate(String sqlString):用於執行INSERT、UPDATE或DELETE語句以及SQL DDL語句,如:CREATE TABLE和DROP TABLE等  

  3.execute(sqlString):用於執行返回多個結果集、多個更新計數或二者組合的語句。  

  具體實現的代碼:   

  ResultSet rs = stmt.executeQuery("SELECT * FROM ...") ;  

  int rows = stmt.executeUpdate("INSERT INTO ...") ;  

  boolean flag = stmt.execute(String sql) ; 

 

 

e.處理結果  

  兩種情況:  

  1.執行更新返回的是本次操作影響到的記錄數。  

  2.執行查詢返回的結果是一個ResultSet對象。  

  • ResultSet包含符合SQL語句中條件的所有行,並且它通過一套get方法提供了對這些行中數據的訪問。  

  • 使用結果集(ResultSet)對象的訪問方法獲取數據:  

  如上例:

    while(rs.next()){
       System.out.println(rs.getString("aPassword"));
      }

  處理結果集還有種方式就是:根據數據庫表列的編號(從左到右,第一列為1)如rs.getString(1)表示獲取對應表中第一列的數據 

 

 

f.關閉JDBC對象   

   操作完成以后要把所有使用的JDBC對象全都關閉,以釋放JDBC資源,關閉順序和聲明順序相反:  

  1.關閉記錄集  

   if(rs!=null){
       rs.close();
     }

  2.關閉聲明  

  if(psm==null){
     psm.close();
     }

  3.關閉連接對象  

  if(con!=null){
        con.close();
     }

 

連接數據庫基本結束,里面包含的有些基礎方面的知識大家自己回去看看書吧,我這里還提供一個封裝好了的數據庫連接操作,只需要調用即可

http://www.cnblogs.com/shenliang123/archive/2012/04/19/2456665.html

下次我們將進行數據庫操作的實戰

 注:

java中PreparedStatement和Statement區別

第一:     
    數據庫在執行sql語句的時候如果使用PreparedStatement語句會有一點優勢:因為數據庫會preparedStatement 
語句進行預編譯,下次執行相同的sql語句時,數據庫端不會再進行預編譯了,而直接用數據庫的緩沖區,提高數據訪問的效率(但盡量盡量采用使用?號的方式傳遞參數),如果sql語句只執行一次,以后不再復用. 
第二: 
   在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,;等做費盡心機的判斷和過慮.

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM