JDBC基礎

JDBC


  • Java數據庫連接,提供了一種與平臺無關的用於執行SQL語句的標準javaAPI,可以方便實現多種關係型數據庫的統一操作
  • JDBC驅動分類
    • JDBC-ODBC橋驅動

      • ODBC是由微軟提供的編程接口,JDBC也是模仿了ODBC的設計
    • JDBC-本地驅動
      • 直接使用各個數據庫生產商提供的JDBC驅動程序,因爲只能應用在特定的數據庫上,會喪失程序的可移植性,不過性能很高。
    • JDBC-網絡驅動
      • 將JDBC轉換爲與DBMS無關的網絡協議,之後又被某個服務器轉換爲一種DBMS協議,所用的具體協議取決於提供者,最爲靈活
    • 本地協議純JDBC驅動
      • 將JDBC轉換爲DBMS所使用的網絡協議。
    • 主要操作類及接口
      • 常用的類與接口就是DriverManager、Connection、Statement、Result、PreparedStatement

  • MySQl數據庫
    • 常用命令
      • 創建數據庫:create database 數據庫名稱 ;
      • 刪除數據庫:drop database  數據庫名稱 ;       
      • 使用數據庫:use 數據庫名稱 ;
      • 創建數據庫表:create table 表名( 字段名稱1 字段類型[default 默認值] [約束], …) ;
      • 刪除數據庫表:drop table 表名 ;
      • 查看錶結構: desc  表名稱 ;   
      • 查看全部數據庫:show databases ;
      • 查看一個數據庫全部表: show tables ;

  • SQL語法基礎(Structured Query Language,結構查詢語句)強大的數據庫語言
      • DML-數據操作語言:檢索或修改數據
      • DDL-數據定義語言:定義數據的結構,創建、修改、刪除
      • DCL-數據控制語言:定義 數據庫用戶的權限
    • 數據類型
      • 整型數據
      • 時間日期類
      •  
      • 字符串類型
    • 插入數據:insert into 表名稱( 字段 )   values(值…);
    • 刪除數據:delete from 表名稱 [刪除條件] ;  若無條件則清空表,條件如 “where id =1”
    • 更新數據:update 表名稱 set 字段1 =值 1 …  [where 更新條件]
    • 查詢數據:select {*|colum alias} from 表名 [where ];  
      • 模糊搜索:select * from table where name like ‘%m%’ or password like ‘%m%’ ;搜索姓名或密碼含有m 的用戶
      • 加入limit 限制語句,limit 0,5 ; 限制從第1-5行的記錄

  •  JDBC操作步驟
    • 連接數據庫
      • 配置MySQL數據庫的驅動程序
        • 下載 mysql-connector-java-5.1.39.zip,複製到jdk的所在處
          1. public class jdbc {
          2. public static final String DRIVER="org.gjt.mm.mysql.Driver";
          3. public static void main(String[] args){
          4. try{
          5. System.out.println(Class.forName(DRIVER)) ;
          6. }catch(ClassNotFoundException e){
          7. e.printStackTrace() ;
          8. }
          9. }
          10. }          
        • 若能輸出Class名,則已配置好了
        • 爲什麼調用Class.forName(),卻沒有newInstance(); 
          • Class.forName() 加載了指定類後,若類中有靜態初始化器,JVM必然會執行該類的靜態代碼段,而JDBC的Driver類都是會有static代碼塊  

      • DriverManager
        • getConnection(String url, String user ,String password) :通過連接地址鏈接數據庫,同時輸入用戶名和密碼
        • url:  jdbc:mysql://  ip地址 : 端口號/ 數據庫名稱             
          • jdbc協議:JDBC URL中的協議總是jdbc
          • 子協議:驅動程序名或數據庫連接機制(這種機制可由一個或多個驅動程序支持)的名稱,如mysql
          • 子名稱:一種標識數據庫的方法,必須遵循”//主機名 : 端口/子協議”  的標準URL命名    約定
        • Connection接口

      • 執行數據庫的更新操作
        • Statement接口,通過Connection接口的createStatement()方法實例化,來操作數據庫
          1. public static final String DRIVER="org.gjt.mm.mysql.Driver";
          2. public static final String URL="jdbc:mysql://localhost:3306/newsql";
          3. public static final String USERNAME="root";
          4. public static void main(String[] args)throws Exception{
          5. Connection conn=null;
          6. Statement statement=null;
          7. String sql="insert into newtable(name) values('ccw')";
          8. try{
          9. Class.forName(DRIVER); //加載驅動
          10. }catch(ClassNotFoundException e){
          11. e.printStackTrace() ;
          12. }
          13. conn=DriverManager.getConnection(URL,USERNAME,USERNAME);
          14. statement=conn.createStatement();
          15. statement.executeUpdate(sql);
          16. try{
          17. statement.close();     //先開後關閉,可以只關閉connection
          18. conn.close();
          19. }catch(Exception e){
          20. e.printStackTrace();
          21. }
          22. }





  • ResultSet接口
    • 接受所查詢的記錄,並顯示內容,開發中要限制查詢數量
    • Statement接口的executeQuery() 方法,返回一個ResultSet對象
      1. ResultSet rSet=statement.executeQuery(sql);
      2. while(rSet.next()){
      3. int id=rSet.getInt("id"); //int id=rSet.getInt(1);
      4. String name=rSet.getString("name"); //String name=rSet.getString(2);
      5. String sex=rSet.getString("sex"); //....
      6. System.out.println(id+name+sex);
      7. }
    • ResultSet的所有數據都可以通過getString()方法獲得


  • PreparedStatement接口
    • 是Statement的子接口,屬於預處理操作,與直接使用Statement不同的是,是先在數據表中準備好了一條SQL語句,但是此SQL語句的具體內容暫時不設置,而是之後在進行設置,即佔住此位置等待用戶設置
      1. String sql="insert into newtable(name,sex) values(?,?)";
      2. pStatement=conn.prepareStatement(sql); //實例化
      3. pStatement.setString(1, name);
      4. pStatement.setString(2, sex);
      5. pStatement.executeUpdate();
    • 注意:開發中不建議使用Statement來操作數據庫,而是使用PreparedStatement,因爲Statement是完整的SQL語句

  • 處理大數據對象——必須使用PreparedStatement
    • CLOB:存儲海量文字
    • BLOB    存儲二進制數據
    • 寫入大對象數據——IO流的模式
    • 讀取大對象數據
      • 處理CLOB
        • 使用Clob操作比InputStream更加方便
          1. String sql="select name,note from bigtable where id =?";
          2. pStatement=conn.prepareStatement(sql);
          3. pStatement.setInt(1, 1);
          4. ResultSet rs=pStatement.executeQuery();
          5. while(rs.next()){
          6. String name=rs.getString(1);
          7. Clob clob=rs.getClob(2);
          8. String note=clob.getSubString(1, (int)clob.length());
          9. System.out.println(name+" "+note);
          10. }


      • 處理BLOB
        • 創建表:create table userBlob(id int auto_increment primary key,name char(30), photo longblob) ;
          • 存儲圖片
            1. String sql="insert into userblob(name, photo) values(?,?)";
            2. pStatement=conn.prepareStatement(sql);
            3. File file=new File("d:"+File.separator+"my.jpg");
            4. InputStream input=new FileInputStream(file);
            5. pStatement.setString(1, name);
            6. pStatement.setBinaryStream(2, input);
            7. pStatement.executeUpdate();

        • 使用BLOB方法更加方便
            1. if(rSet.next()){
            2. String name=rSet.getString(1);
            3. Blob blob=rSet.getBlob(2);
            4. FileOutputStream output=new FileOutputStream(newFile("d:"+File.separator+"you.jpg"));
            5. output.write(blob.getBytes(1,(int)blob.length()));
            6. output.close();
            7. }






  • CallableStatement接口——主要調用數據庫中的存儲過程
    • 即爲一種方法,可以調用, 傳遞參數  
      1. delimiter // //這裏是改變執行操作語句的分隔符,也就是將SQL語句的";"結尾符號改爲"//"
      2. drop procedure myproc //
      3. create procedure myproc(IN p1 int, INOUT p2 int ,OUT p3 int)
      4. begin
      5. select p1,p2,p3 ;
      6. set p1=10;
      7. set p2=20;
      8. set p3=30;
      9. end
      10. //
    • 3個類型
      • IN(默認的類型):表示只是將值傳進來
      • INOUT:表示把值傳遞到過程中,可以保留過程對此值得修改值
      • OUT:可以不傳遞內容進來,過程中對此值得操作可以返回

      1. String sql="{call myproc(?,?,?)}";
      2. CallableStatement cstmt=conn.prepareCall(sql);
      3. cstmt.setInt(1,70);
      4. cstmt.setInt(2,80);
      5. cstmt.registerOutParameter(2,Types.INTEGER);     //設置返回值類型
      6. cstmt.registerOutParameter(3,Types.INTEGER);
      7. cstmt.execute();




  • JDBC2.0
    • ResultSet的更新

      • 設置ResultSet的類型:TYPER_XXX設置類型,表示是否可以滾動以及是否可以修改數據表的內容
      • 設置CONCUR_XXX設置的都是併發性,併發性主要表示結果集是否是隻讀還是可以進行數據庫更新

    • 可滾動的結果集——現在想取結果集中任意位置的數據
        1. PreparedStatement pstmt=conn.prepareStatement(sql,ResultSet.TYPE_SCROLL SENSITIVE,ResultSet.CONCUR_READ_ONLY);                    
      • 使用結果集插入數據
          1. PreparedStatement pstmt=conn.prepareStatement(sql,ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATE);
          2. ResultSet rs=pstmt.executeQuery();
          3. rs.movetoInsertRow(); //移動到可插入的行
          4. rs.updateString("name","李華");
          5. ...
          6. rs.insertRow(); //插入數據


    • 批處理
        1. for(int i=0;i<10;i++){
        2. ps.setString(1,"ccw"+i );
        3. ps.setString(2, "nan"+i);
        4. ps.addBatch();
        5. }
        6. ps.executeBatch();  




  • 事務處理
    • 原子性:最小的單元,如果一個是失敗了,則一切的操作將全部失敗。
    • 一致性:如果事務出現錯誤,則回到最原始的狀態
    • 隔離性:多個事務之間無法訪問,只有當事務完成後纔可以看到結果
    • 持久性:當一個系統崩潰時,一個事務依然可以提交,當事務完成後,操作結果保存在磁盤中,不會被回滾
      • 數據庫把每一個連接到此數據庫上的用戶都稱爲一個session,如下是步驟
        • 取消自動提交, set autocommit=0 ,所有更新指令並不會立刻發送到數據表中,只存於當前的session
        • 開啓事務:      start transaction 或者 begin
        • 編寫數據庫更新語句(增加、刪除、修改),可以記錄事務的保存點,使用savepoint
        • 提交事務:  commit 
        • 事務回滾:  rollback 或者  rollback to savepoint     如果執行的sql語句有錯誤,則回滾





  • 使用元數據分析數據庫
    • DatabaseMetaDate
      • 得到數據庫的名稱、版本、表的信息
      • 實例化   DatabaseMetaDate dmd=connection.getMetData(); 

    • ResultSetMetaData
      • 可獲取關於ResultSet對象中列的類型和屬性信息的對象
      • 實例化: ResultSetMetaData rsmd =preparedStatement.getMetaData();



  • 使用JDBC鏈接Oracle數據庫
    • 對於每一種驅動的改動都不是很大,所以我這裏也就不簡單講了,具體的呢就可以去查查吧。



 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章