2

レコードがmysqlテーブルに挿入または更新されるたびに作成される自動生成されたタイムスタンプがあります。キーホルダーを使用して新しく作成されたIDを返すのと同様の方法で、このタイムスタンプを返す方法はありますか?

KeyHolder keyHolder = new GeneratedKeyHolder();
JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);

//Insert Contact
jdbcTemplate.update(new PreparedStatementCreator() {
    @Override
    public PreparedStatement createPreparedStatement(Connection connection) throws SQLException {
        PreparedStatement preparedStatement = connection.prepareStatement(SQL_ADD, Statement.RETURN_GENERATED_KEYS);
        preparedStatement.setString(1, contact.getFirstName());
        preparedStatement.setString(2, contact.getLastName());
        preparedStatement.setInt(3, contact.getOrganizationId());
        preparedStatement.setString(4, contact.getType());
        preparedStatement.setInt(5, contact.getUserId());
        return preparedStatement;
        }   
}, keyHolder);
//Use keyholder to obtain newly created id
contact.setId(keyHolder.getKey().intValue());

テーブルを再クエリせずに新しいタイムスタンプを返す方法はありますか?キーホルダーのキーとしてIDと一緒に返す方法を探していましたが、キーとして返されないようです。

4

5 に答える 5

1

あまり満足のいくものではありませんが、あなたの質問に対する答えは「いいえ」だと思います。Springに関するものはどれも知りませんが、これは基本的なJDBCがラップしているためだと思います。http://docs.oracle.com/javase/6/docs/api/java/sql/Statement.html#getGeneratedKeys%28%29を参照してください

唯一のオプションは、outパラメータを持つMySQLでストアドプロシージャを作成し、それを呼び出すことです。http://dev.mysql.com/doc/refman/5.0/en/call.htmlを参照してください。

于 2012-11-02T11:59:32.730 に答える
0

変数contactは新しく挿入されたレコードのインスタンスのようです。新しく生成されたid(主キー)フィールド値が含まれているため、新しいクエリを実行して、timestampこの新しいに必要なフィールド値を返すことができますid

クエリは次のようになります。

select timestamp_field from my_table where id=?

PreparedStatement新しいid値を入力して実行し、必要なtimestampフィールド値をフェッチするために使用します。

于 2012-10-28T16:23:17.047 に答える
0

GeneratedKeyHolderまた、2つのメソッドがあります。生成されたフィールドgetKeyList()を返す方法。Map<String,Object>これにより、getKeyList()影響を受けるすべての行に対して生成されたキーのリストが生成されます。

GeneratedKeyHolderのJavadocおよび自動生成されたキーのSpringチュートリアルを参照してください

さらに、SpringのSimpleJdbcInsertには、生成されたキー検索のためのメソッドがあります。SimpleJdbcInsert#usingGeneratedKeyColumnsメソッドも参照してください。

于 2012-10-31T22:11:43.783 に答える
0

クラスには2つのメソッドがありjava.sql.Connection、PreparedStatementの実行で選択したキー列が返されます。

PreparedStatement prepareStatement(String sql,
                                   int[] columnIndexes)
                                throws SQLException

PreparedStatement prepareStatement(String sql,
                                   String[] columnNames)
                                   throws SQLException

これを行うためにSpringKeyHolderとJDBCTemplateを使用する必要はありません。
タイムスタンプ列に番号を付けたり名前を付けたりできることを願っています。ただし、javadocは、JDBC実装が非キー列を返すことができることを要求または示唆していないため、このアプローチでは運が悪いです。

指定された配列によって指定された自動生成されたキーを返すことができるデフォルトのPreparedStatementオブジェクトを作成します。この配列には、返される必要のある自動生成されたキーを含むターゲットテーブルの列の名前が含まれています。


  • 別の回答で提案されているように、必要な処理を正確に実行するストアドプロシージャに切り替えることができます(CallableStatementは、実際にはストアドプロシージャを実行するPreparedStatement、つまりサブクラスです)。

  • newを介してプリペアドステートメント内にタイムスタンプ列を設定できますがTimestamp(new Date())、さまざまなサーバー間で時刻を同期するメカニズムを導入する必要があります(これは、Windowsおよび* nix環境でよく使用されます)。トリガーは、値がまだ提供されていない場合にのみタイムスタンプを設定できます。

アプリとDBの設計の一環として、特定の操作が発生する場所の哲学にコミットする必要があります。DBが必要なデータを取得する場合、アプリはデータを更新する必要があります。個別のクエリ実行、または挿入と取得を行うストアドプロシージャの組み合わせの料金を支払う必要があります。

于 2012-11-06T07:01:36.690 に答える
0

MySQLデータベースサーバー側でこの問題を解決するためのいくつかのオプションがあります。テーブル上にを作成することから始めることができTRIGGERます。TRIGGER制限があり、データを返すことができないため、値を変数に設定できますTIMESTAMP

DEMILITER //
CREATE TRIGGER ai_tbl_name AFTER INSERT ON tbl_name
FOR EACH ROW
BEGIN

SET @TimeStamp = NEW.timestamp_column;

END;//
DELIMITER ;

このタイムスタンプ値を取得するには、次のコマンドを実行します。

SELECT @TimeStamp;

変数はメモリに保存されるため、テーブルを再度開く必要はありません。

さらに進んでください。MySQLで作成してSTORED PROCEDURE、上記のすべてを自動化することができます(テーブルの詳細がわからないため、サンプルコード)。

DELIMITER //
DROP PROCEDURE IF EXISTS sp_procedure_name //
CREATE PROCEDURE sp_procedure_name (IN col1_val VARCHAR(25),
                                    IN col2_val VARCHAR(25),
                                    IN col3_val INT)
BEGIN
    INSERT INTO tbl_name (col1, col2, col3)
    VALUES (col1_val, col2_val, col3_val);

    SELECT @TimeStamp;
END; //
DELIMITER ;

この手順は、次のコードで実行できます。

CALL sp_procedure_name(col1_val, col2_val, col3_val);

私はJavaに精通していないので、コードの側でJavaを完成させる必要があります。

于 2012-11-06T14:48:51.010 に答える