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

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

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

    【永恒的瞬間】
    ?Give me hapy ?

    簡介:JDBC 中的語句處理

    在 JDBC 應用程序中,JDBC 語句對象用于將 SQL 語句發送到數據庫服務器。一個語句對象與一個連接相關聯,應用程序與數據庫服務器之間的通信由語句對象來處理。

    JDBC 中有三種類型的語句對象:

    1. 常規語句(General statement)
    2. 預置語句(Prepared statement)
    3. 可調用語句(Callable statement)

    語句對象與一個連接相關聯,所以要創建一個語句對象,首先應該建立一個數據庫連接。

    創建連接

    清單 1 中的代碼示例演示了如何創建連接:


    清單 1.裝載 Informix 驅動程序并創建一個連接的代碼示例
                Connection con = null;
                try {
                Class.forName("com.informix.jdbc.IfxDriver");
                String url = "jdbc:informix-sqli://hostname:port_number/dbname:
                informixserver=servername; userid=userid;password=pwd;";
                con = DriverManager.getConnection(url);
                }
                

    現在逐個考察這三種類型的語句對象。






    常規語句

    可以使用連接的 createStatement 方法創建這種語句。這種語句專用于不需要傳遞任何值作為參數的 SQL 語句。


    清單 2. 演示創建語句的示例代碼
                Statement stmt = con.createStatement();
                cmd = "create database testDB;";
                rc = stmt.executeUpdate(cmd);
                stmt.close();
                






    預置語句

    預置語句是 statement 類的一個子類。預置語句與 statement 類的主要區別在于,前者可以只編譯和優化一次,然后通過設置不同的參數值多次使用。所以,如果想多次執行一條語句,那么預置語句是更好的選擇。由于已經預先編譯好,所以減少了執行時間。因此,預置語句的優點是,它不僅包含一條 SQL 語句,而且還是一條預先編譯好的 SQL 語句。另一個區別是,SQL 語句在創建后就被提供給預置語句。


    清單 3. 解釋預置語句的示例代碼
                PreparedStatement pstmt = con.prepareStatement("UPDATE tab1 "+
                "set col1 = ? where key = 1");
                pstmt.setShort(1, (short)2);
                int rowcount = pstmt.executeUpdate();
                

    在此,同一個預置語句可用于不同的 col1 值。參數一旦設定,它的值將保持不變,直到被重新設置或者 clearParameters 被調用。這項特性使得預置語句可以用于批量處理 INSERT/UPDATE

    批量更新

    通過設置多個值,批量更新特性提高了需要多次執行的語句的性能。這樣可以將多個更新操作提交到一個數據源并進行一次性處理。語句對象也可以使用批量更新。但語句對象提交不同的 SQL 語句進行批處理,而預置語句提交的是一組參數。

    清單 4 顯示了如何使用預置語句進行批量插入:


    清單 4. 演示批量更新的示例代碼
                PreparedStatement pst = conn.prepareStatement("insert into tab1 values (?)");
                for loop....
                {
                pst.setInt (1, i);
                pst.addBatch();
                }
                pst.executeBatch();
                

    addBatch 方法將語句添加到一個緩存中,然后使用 executeBatch() 方法轉儲到數據庫中。所以它節省了語句的編譯/優化,因為它只編譯一次(對于預置語句),而且還節省了與服務器之間的往返,因為它一次性發送了批量插入。





    可調用語句

    這是調用 SQL 語句的第三種方法,它提供了一種從 Java™ 程序中調用服務器上的存儲過程的方式。可調用語句也需要先作準備,然后使用 set 方法設置它們的參數。可以通過以下兩種方式設置參數值:

    1. 順序位置
    2. 命名參數

    順序位置是傳統的參數設置方式,它根據參數在 CallableStatements 中的位置來設置參數。但是,命名參數則提供了更大的靈活性,它允許根據名稱而不是順序位置來設置參數。在調用例程時,必須以名稱或順序格式指定 CallableStatement 的參數。例如,如果對一個參數使用了參數名稱,那么對所有其他參數也必須使用參數名稱。

    在調用具有許多參數,而且其中一些參數有默認值的存儲過程時,命名參數特別有用。如果過程是惟一的,那么可以省略有默認值的參數,并且可以按任意順序輸入參數。命名參數使應用程序更加健壯,所以,即使存儲過程中參數的順序發生了改變,也不必修改應用程序。

    JDBC 驅動程序提供了 DatabaseMetaData.supportsNamedParameters() 方法來確認驅動程序和 RDMS 是否支持 CallableStatement 中的命名參數。如果支持命名參數,則系統返回 true。例如:


    清單 5. supportsNamedParameters() 的使用
                Connection myConn = . . .   // connection to the RDBMS for Database
                DatabaseMetaData dbmd = myConn.getMetaData();
                if (dbmd.supportsNamedParameters() == true)
                {
                System.out.println("NAMED PARAMETERS FOR CALLABLE"
                + "STATEMENTS IS SUPPORTED");
                }
                

    獲取存儲過程的參數名稱

    可以使用 DatabaseMetaDatagetprocedureColumns 獲取存儲過程的參數名稱,該方法的定義如清單 6 所示:


    清單 6. getProcedureColumn() 方法的使用
                Connection myConn = . . .   // connection to the RDBMS for Database
                . .
                DatabaseMetaData dbmd = myConn.getMetaData();
                ResultSet rs = dbmd.getProcedureColumns(
                "myDB", schemaPattern, procedureNamePattern, columnNamePattern);
                rs.next() {
                String parameterName = rs.getString(4);
                - - - or - - -
                String parameterName = rs.getString("COLUMN_NAME");
                - - -
                System.out.println("Column Name: " + parameterName);
                

    getProcedureColumns() 方法的參數相匹配的所有列的名稱都將被顯示。

    清單 7 顯示了 CallableStatements 中的命名參數的使用。

    創建存儲過程


    清單 7. 可調用 OUT 參數的使用
                create procedure createProductDef(productname   varchar(64),
                productdesc  varchar(64),
                listprice    float,
                minprice     float,
                out prod_id      float);
                . . .
                let prod_id="value for prod_id";
                end procedure;
                

    清單 8 中的 Java 代碼首先創建一個有 5 個參數的 CallableStatement,這 5 個參數與存儲過程中的參數相對應。JDBC 調用的括號中的問號字符 (?) 對參數進行引用。設置或注冊所有的參數。使用格式 cstmt.setString("arg", name); 命名參數,其中 arg 是相應的存儲過程中的參數名稱。這里不需要按照存儲過程中的參數順序來命名參數。


    清單 8. 可調用命名參數的使用
                String sqlCall = "{call CreateProductDef(?,?,?,?,?)}";
                CallableStatement cstmt = conn.prepareCall(sqlCall);
                cstmt.setString("productname", name);     // Set Product Name.
                cstmt.setString("productdesc", desc);     // Set Product Description.
                cstmt.setFloat("listprice", listprice);   // Set Product ListPrice.
                cstmt.setFloat("minprice", minprice);     // Set Product MinPrice.
                // Register out parameter which should return the product is created.
                cstmt.registerOutParameter("prod_id", Types.FLOAT);
                // Execute the call.
                cstmt.execute();
                // Get the value of the id from the OUT parameter: prod_id
                float id = cstmt.getFloat("prod_id");
                

    如果 CallableStatement 中的參數數量少于存儲過程中的參數數量,那么剩下的參數必須有默認值。不需要為有默認值的參數設置值,因為服務器會自動使用默認值。例如,如果一個存儲過程有 10 個參數,其中 4 個參數沒有默認值,6 個參數有默認值,那么在 CallableStatement 中必須至少有 4 個問號。也可以使用 5 個、6 個或至多 10 個問號。在下面這個惟一的存儲過程中,參數 listpriceminprice 有默認值:


    清單 9. 創建包括具有默認值的參數的過程
                create procedure createProductDef(productname   varchar(64),
                productdesc  varchar(64),
                listprice    float default 100.00,
                minprice     float default  90.00,
                out prod_id      float);
                . . .
                let prod_id = value for prod_id;
                end procedure;

    清單 10 中的 Java 代碼使用少于存儲過程中參數數量的參數(存儲過程中有 5 個參數,而代碼中只使用 4 個參數)調用存儲過程。由于 listprice 有一個默認值,因此可以在 CallableStatement 中省略它。


    清單 10. 默認參數的使用
                String sqlCall = "{call CreateProductDef(?,?,?,?)}";
                // 4 params for 5 args
                CallableStatement cstmt = conn.prepareCall(sqlCall);
                cstmt.setString("productname", name);   // Set Product Name.
                cstmt.setString("productdesc", desc);   // Set Product Description.
                cstmt.setFloat("minprice", minprice);   // Set Product MinPrice.
                // Register out parameter which should return the product id created.
                cstmt.registerOutParameter("prod_id", Types.FLOAT);
                // Execute the call.
                cstmt.execute();
                // Get the value of the id from the OUT parameter: prod_id
                float id = cstmt.getFloat("prod_id");
                

    如果可調用語句包含 OUTINOUT 參數,那么需要使用 CallableStatement 的 registerOutParameter 注冊這些參數。清單 11 使用 out 參數 prod_id 創建一個具有 OUT 參數的存儲過程。類似地,可以使用關鍵字 INOUT 創建 INOUT 參數。


    清單 11. INOUT 和 OUT 參數的使用
                create procedure createProductDef(productname   varchar(64),
                productdesc  varchar(64),
                inout    listprice    float default 100.00,
                minprice     float default  90.00,
                out prod_id      float);     

    清單 12 使用 CallableStatements registerOutparameter 方法注冊 CallableStatement 的 out 參數。


    清單 12. 使用 CallableStatement 注冊 OUT 參數
                cstmt.registerOutParameter("prod_id", Types.FLOAT);
                

    清單 13 將使用命名參數特性的所有語句合并在一起:


    清單 13. 演示命名參數功能的程序
                package Callable;
                import java.sql.CallableStatement;
                import java.sql.Connection;
                import java.sql.DriverManager;
                import java.sql.ResultSet;
                import java.sql.SQLException;
                import java.sql.Statement;
                import java.sql.Types;
                public class out1 {
                static Connection conn;
                public static void main(String[] args) {
                getConnect();
                System.out.println("Connection Established");
                createProc();
                runthis();
                System.out.println("\n=============Finished=============");
                System.exit(0);
                }
                private static void getConnect() {
                try
                {
                Class.forName("com.informix.jdbc.IfxDriver");
                String url = "jdbc:informix-sqli://host name or ip :porn number/database
                name:informixserver=dbservername;";
                System.out.println("URL: "+url);
                conn = DriverManager.getConnection(url);
                }
                catch( Exception e )
                {
                e.printStackTrace();
                System.exit(1);
                }
                }
                private static void createProc() {
                String str=null;
                Statement stmt = null;
                try
                {
                stmt = conn.createStatement();
                }
                catch (SQLException e2)
                {
                e2.printStackTrace();
                }
                str="drop function c_out_proc";
                try
                {
                stmt.executeUpdate (str);
                }
                catch (SQLException e1)
                {	}
                str = "create function  c_out_proc ( i int, OUT d varchar(20) ) \n" +
                "returning float; \n" +
                "define f float; \n" +
                "let d= \"Hello OUT\"; \n" +
                "let f=i*2; \n" +
                "return f; \n" +
                "end function; \n";
                try
                {
                stmt.executeUpdate (str);
                System.out.println("Function created \n");
                }
                catch (SQLException e)
                {
                System.out.println("Error on creating function: " + e.toString());
                System.exit(1);
                }
                }
                private static void runthis()
                {
                CallableStatement cstmt = null;
                String command = "{? = call c_out_proc(?, ?)}  ";
                try
                {
                cstmt = conn.prepareCall (command);
                cstmt.setInt(1, 2);
                cstmt.registerOutParameter(2, Types.VARCHAR);
                ResultSet rs = cstmt.executeQuery();
                if (rs == null)
                {
                System.out.println("rs is null *** this is BAD.");
                System.exit(0);
                }
                else
                {
                rs.next();
                System.out.println(rs.getFloat(1));
                System.out.println(cstmt.getString(2));
                }
                }
                catch (SQLException e)
                {
                e.printStackTrace();
                }
                }
                }


    posted on 2008-05-29 13:45 ???MengChuChen 閱讀(1593) 評論(0)  編輯  收藏 所屬分類: JAVAEE
    主站蜘蛛池模板: 亚洲成人一级电影| 亚洲国产精品成人精品无码区在线| 亚洲一区二区中文| 日本视频在线观看永久免费| 亚洲一区二区三区乱码A| 国产成人亚洲综合无| 国产成人3p视频免费观看| 在线观看亚洲免费| 免费萌白酱国产一区二区| 成人久久久观看免费毛片| 国产亚洲人成A在线V网站| a级大片免费观看| 亚洲国产精久久久久久久| 在线观看免费中文视频| 精品亚洲国产成人| 日韩免费高清视频| 野花视频在线官网免费1| 亚洲高清视频一视频二视频三| 国产成人无码精品久久久免费| 亚洲国产AV无码专区亚洲AV| 97公开免费视频| 亚洲国产系列一区二区三区| 免费国产人做人视频在线观看| 一级午夜免费视频| 亚洲伦理一区二区| 91情侣在线精品国产免费| MM1313亚洲国产精品| 亚洲小说区图片区另类春色| 37pao成人国产永久免费视频| 国产成人精品亚洲2020| 免费在线观看亚洲| 黄页免费在线观看| 中文字幕在线日亚洲9| 亚洲Av无码国产情品久久 | 一二三四免费观看在线视频中文版| 亚洲色大18成人网站WWW在线播放 亚洲色大成WWW亚洲女子 | 久久国产成人亚洲精品影院| 久久99免费视频| 亚洲中文字幕乱码熟女在线| 国产偷国产偷亚洲高清日韩| 亚洲人成免费电影|