3

私の問題の簡単な例をあげると:

//Create database table allowing nulls.
CREATE TABLE test(one int not null, two int null, three int not null);

これで、Javaには、データベースのコンテンツに一致するオブジェクトの配列があります。配列値を使用して、このデータベーステーブルの挿入/更新/削除ステートメントを作成する必要があります。

Object[] arr = { 4, null, 1 };
String sql = GenereateInsert(arr);

ただし、事前に挿入からnullフィールドを除外する必要があるため、これは困難になります。たとえば、上記の2つがnullでない場合:

 INSERT INTO test(4, 2, 1);

すべてが簡単です。しかし、それがnullの場合、次のステートメントが必要です。

 INSERT INTO test(one, three) values(4, 1);

私が扱っているテーブルは50列以上なので、手動でこれを実行したくありません。管理できなくなります。では、一般的にこの問題にどのように対処するのでしょうか。それは一般的な状況に違いありません。

PS:私は完全なORMライブラリを使いたくありません。それはやり過ぎのようです。

4

3 に答える 3

1

高レベルのアルゴリズム:

  1. 列名の配列を(入力パラメーターと同じ順序で)allColumnNamesクラスのフィールドとして格納します(これを呼び出しましょう)。
  2. メソッドが呼び出されたら、2つの新しい空List<String>のを作成します。1つは列名を表し、もう1つは値を表します。これらcolumnNamesListとを呼び出しましょうcolumnValuesList
  3. null以外の要素ごとに、入力配列を反復処理し、に追加allColumnNames[i]します。columnNamesListvalues[i]columnValuesList
  4. INSERT INTO tablename、、の各値のコンマ区切りリスト、および。の各値のコンマ区切りリストを連結して、columnNames挿入VALUESステートメントを作成しますcolumnValuesList
于 2012-09-14T18:52:04.423 に答える
1

私はこのようなものを提案します:

  1. のようなクエリを実行しますSELECT * FROM <TABLE_NAME> LIMIT 1。を使用しResultSetMetaDataて、columnNamesとそのcolumnTypeを取得します。それをHashMapに保存し、キーをArrayListに保存します

  2. PreparedStatement次に、ArrayListのキーをcolumnNamesとして使用してを作成します。それは難しいことではないと思います

  3. 配列内のデータ、つまりHashMapからのSQLタイプがわかっているので、この情報を使用して?、生成されたPreparedStatementの配列から取得した値を簡単にマップできます。

ここで問題は、どのように対処するかnullです。列のタイプを知っているので、取得する値がである場合は、それらをnullとして設定するためにnull使用できます。PreparedStatement.setNull(...)

また、このドキュメントによると、JDBCのsetXXX(...)への重要なガイドがあることを指摘したいと思います。

6.1.5INパラメータとしてJDBCNULLを送信する

setNullメソッドを使用すると、プログラマーはJDBC NULL(汎用SQL NULL)値をINパラメーターとしてデータベースに送信できます。ただし、パラメータのJDBCタイプを指定する必要があることに注意してください。

Java null値がsetXXXメソッドに渡されると(Javaオブジェクトを引数として取る場合)、JDBCNULLもデータベースに送信されます。ただし、メソッドsetObjectは、JDBCタイプが指定されている場合にのみnull値をとることができます。

これは、メソッドのパラメーターの値としてnullを送信でき、実際にはメソッドを明示的setXX(...)に呼び出す必要がないことを意味します。setNull(..)

これがあなたのために働くことを願っています!

于 2012-09-14T19:14:11.633 に答える
0

他のデータベースシステムについてはわかりませんが、postgresでは次のようにnull値を挿入できます。

CREATE TABLE test(
  id       SERIAL PRIMARY KEY,
  val1     INTEGER DEFAULT NULL,
  val2     INTEGER DEFAULT NULL,
  val3     INTEGER DEFAULT NULL
);

INSERT INTO test(val1, val2, val3) VALUES(DEFAULT, DEFAULT, DEFAULT);

同じ方法でsetステートメントを実行することもできます。

UPDATE test SET val1 = DEFAULT, val2 = 123, val3 = DEFAULT WHERE id = 3;

したがって、

Stringbuilder sqlStmt = new StringBuilder();
sqlStmt.append("INSERT INTO test(val1, val2, val3) VALUES(");
sqlStmt.append(((val1 == null) ? "DEFAULT" : val1.toString()));
sqlStmt.append(" , ");
sqlStmt.append(((val2 == null) ? "DEFAULT" : val2.toString()));
sqlStmt.append(" , ");
sqlStmt.append(((val3 == null) ? "DEFAULT" : val3.toString()));
sqlStmt.append(";");
statement.execute(sqlStmt.toString());

これらがたくさんある場合は、for-eachループでそれを行う方が理にかなっているかもしれません。

于 2012-09-14T19:36:25.580 に答える