PrepareStatement sql語句in中多個參數的實現,

來源:互聯網
上載者:User

PrepareStatement sql語句in中多個參數的實現,

下邊是今天探索PrepareStatement先行編譯where條件為in的sql語句的過程,在mysql環境中只有第四種方法實現了,Oracle中可能第三種也可以不過沒有測試,如果有需要可以直接跳轉。

1.通過拼接字串設定參數×

今天在實現一個資料庫批次更新的代碼時,發現

String sql = "UPDATE t_demo SET columns='Well' WHERE column_id IN (?)";

這條語句中的參數在使用PrepareStatement來先行編譯之後,是不可以傳入一個拼接字串的,比如

String criteria="'a','b','c'";prepareStatement.setString(1,criteria);

想要達到的效果是和執行下邊一條語句一樣:

UPDATE t_demo SET columns='Well' WHERE column_id IN ('a','b','c')

但是最後發現這樣並不起作用,最後思考後恍然大悟。
因為PrepareStatement是先行編譯的,所以在編譯完sql語句後發現這個sql只有一個參數,所以在設定參數的時候會預設(’a’,’b’,’c’)為一個參數,就會去尋找column_id為“’a’,’b’,’c’”的資料,結果當然是不符合期望的。

2. 通過Vector設定參數×

這個是網上找到的一個方法,我的用法如下,但是最後使用後發現也是不起作用的,但是也沒有報錯。不知道是不是我的問題。不過還是貼上來代碼供大家研究

String arr[]={"a","b","c"};Vector v=new Vector(Arrays.asList(arr));prepareStatement.setObject(1,v);prepareStatement.executeUpdate();
3. 通過PrepareStatement的setArray()方法

這個也是在網上發現的方法,這個是不支援mysql資料庫的,在mysql環境下使用會報SQLFeatureNotSupportedException異常
可能支援Oracle(沒有測試)。
代碼如下。

String arr[]={"a","b","c"};Array v=conn.createArrayOf("VARCHAR", arr);prepareStatement.setArray(1, v);prepareStatement.executeUpdate();
4. 設定多個參數√

上邊幾個方法都在我的mysql環境中陣亡了之後,就只好使用笨方法了。那就是在in的條件中多加幾個“?”。
因為我這次任務處理的資料比較多達8w多條,所以我分批處理。代碼如下:

import java.sql.Connection;import java.sql.DriverManager;import java.sql.PreparedStatement;import java.sql.SQLException;import java.util.Date;public class Test {    static String url = ...;    static String user = ...;    static String password =...;    static String sql = "UPDATE t_demo SET columns='Well' WHERE column_id IN (_SQL)";    static int NUM=100;    public static void main(String[] args) throws SQLException {        // 下邊為條件,因為資料太多存在檔案中        // 讀取檔案然後通過字串的split方法轉為數組        // TestChange是自己寫的一個讀檔案並轉為字串的類,由於不是重點所以就不上代碼了        String content = TestChange.readString3("D:/demo.txt");        String pNo[] = content.split(",");        // 設定根據參數多少多少設定sql        setSql();        Connection conn = null;        PreparedStatement stmt=null;        try {            Class.forName("com.mysql.jdbc.Driver");            conn = DriverManager.getConnection(url, user, password);            conn.setAutoCommit(false);            stmt = conn.prepareStatement(sql);            // 分批處理數組中的資料            for (int begin = 0; begin < pNo.length; begin += NUM) {                Date beginTime=new Date();                int end=(begin>(pNo.length-NUM)?pNo.length:(begin+NUM));                String arr[]=(String[])Arrays.copyOfRange(pNo, begin, end);                // 迴圈設定參數                int flag=1;                for (String criteria: arr) {                    if(flag ==1)                        System.out.print("First:"+criteria+",");                    if(flag ==arr.length)                        System.out.println("Last:"+criteria);                    stmt.setString(flag, criteria);                    flag++;                }                int num=stmt.executeUpdate();                Date endTime=new Date();                Long usedTime=endTime.getTime()-beginTime.getTime();                System.out.println("Data to be change:"+begin+"-"+end+",changed:"+num+",used time:"+usedTime);            }            conn.commit();            System.out.println("Well Done!");        } catch (Exception e) {            e.printStackTrace();            conn.rollback();        }finally{            stmt.close();            conn.close();        }    }    // 設定SQL語句,一次處理多少條資料就設定多少個“?”    private static void setSql() {        StringBuffer sb=new StringBuffer();        for(int i=0;i<NUM;++i){            sb.append("?,");        }        sb.deleteCharAt(sb.lastIndexOf(","));        sql=sql.replace("_SQL", sb.toString());    }}

注意:上邊的代碼僅說明了這種方法的思路和大致實現,但具有漏洞,NUM在執行到最後一批時還是會為100,但可能沒有那麼多參數需要設定。
比如我有122個資料需要update,NUM設定為100。也就是第一次設定了100個?,第二次還會繼續設定100個?,但是在setString的時候後邊的78個就會因為沒有重新set而還會是原來的那幾個,因為在我的需求中沒有影響,所以沒有處理,各位大佬們在參考的時候要注意
歡迎交流mail: helloleif@foxmail.com

   
1
0
查看評論

相關文章

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.