Preparestatement sql文inにおける複数のパラメータの実現
8483 ワード
以下は今日Preparestatementを探求してwhere条件をコンパイルしました。inのsql文の過程です。mysql環境では第4の方法しか実現していません。Oracleでは第3の方法も可能ですが、テストがなければ直接にジャンプできます。
1.文字列をつなぎ合わせてパラメータを設定する×
今日は一つのデータベースの大量更新コードを実現する時、発見しました。
2.Vectorでパラメータを設定する×
これはネットで見つけた方法です。私の使い方は以下の通りです。でも、最後に使ってみても効果がないです。私の問題かどうか分かりません。でも、コードを貼って、みんなで研究します。
これもオンラインで発見された方法です。これはmysqlデータベースをサポートしていません。mysql環境下でSQL Feature NotSupported Exceptionを使って、Oracleをサポートする可能性があります。コードは以下の通りです
上のいくつかの方法はすべて私のmysql環境の中で戦死した後に、仕方なく愚かな方法を使いました。それはinの条件に「?」をいくつか追加することです。今回の仕事で処理したデータは8 w以上もありますので、分けて処理します。コードは以下の通りです
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(u)を探しに行きます。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.PrepareStationによるsetAray()方法これもオンラインで発見された方法です。これはmysqlデータベースをサポートしていません。mysql環境下でSQL Feature NotSupported Exceptionを使って、Oracleをサポートする可能性があります。コードは以下の通りです
String arr[]={"a","b","c"};
Array v=conn.createArrayOf("VARCHAR", arr);
prepareStatement.setArray(1, v);
prepareStatement.executeUpdate();
4.複数のパラメータ√を設定する上のいくつかの方法はすべて私のmysql環境の中で戦死した後に、仕方なく愚かな方法を使いました。それはinの条件に「?」をいくつか追加することです。今回の仕事で処理したデータは8 w以上もありますので、分けて処理します。コードは以下の通りです
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"?,");
}
sb.deleteCharAt(sb.lastIndexOf(","));
sql=sql.replace("_SQL", sb.toString());
}
}
上のコードはこの方法の考えと大体の実現を説明しただけですが、穴があります。NUMは最後のバッチまで実行する時はまだ100です。しかし、そんなに多くのパラメータが必要ではないかもしれません。例えば、122個のデータを持っています。udateが必要です。NUMは100に設定されています。つまり初めて100個設置したということですか?二回目はまた100個設置しますか?でもset Stringの時に後の78個はsetがないので元のものになります。私の需要の中で影響がないので、処理していません。みなさんは参考にしてください。交流メールを歓迎します。[email protected]