如果我使用Hibernate / JPA,我会使用@PrePersist和@PreUpdate(或@PostPersist和@PostUpdate)在每次更新/插入之前(或之后)将数据放入审核列。但是,仅使用Spring JdbcTemplate,实现此目的的最佳方法是什么?
答案 0 :(得分:0)
据我所知,JdbcTemplate没有附加生命周期机制(这实际上是有意义的,因为该类只是一个简化Jdbc工作流的实用程序)。
如果您使用JdbcTemplate,则必须手动执行审核操作
答案 1 :(得分:0)
使用AOP并将@Before建议添加到持久化或更新数据的方法中。
答案 2 :(得分:0)
感谢您的想法。特别是对于Oracle,我能够通过从初始插入(使用Spring的KeyHolder)返回一个键或者使用表示受影响的行的初始更新(使用Oracle的RETURNING INTO子句),然后执行后续查询来更新审计列来实现这一点。 。代码位于抽象基础DAO中,由需要此功能的DAO子类化。
@Inject
private NamedParameterJdbcTemplate namedJdbc;
public Long insert(String sql, Map<String, Object> params, String table, String keyColumn) {
SqlParameterSource paramSource = new MapSqlParameterSource(params);
KeyHolder keyHolder = new GeneratedKeyHolder();
int numberOfAffectedRows = namedJdbc.update(sql, paramSource, keyHolder, new String[]{keyColumn});
Long key = (numberOfAffectedRows == 1) ? keyHolder.getKey().longValue() : -1L;
if (key != -1) {
updateAuditColumns(table, keyColumn, key.toString(), true);
}
return key;
}
public void insert(String sql, Map<String, Object> params, String table) {
SqlParameterSource paramSource = new MapSqlParameterSource(params);
KeyHolder keyHolder = new GeneratedKeyHolder();
int numberOfAffectedRows = namedJdbc.update(sql, paramSource, keyHolder);
ROWID rowId = (numberOfAffectedRows == 1) ? (ROWID) keyHolder.getKeys().get("ROWID") : null;
if (rowId != null) {
updateAuditColumns(table, "ROWID", rowId.stringValue(), true);
}
}
public void update(String sql, Map<String, Object> params, String table) {
sql += " returning ROWID into ?";//Oracle specific
final String finalSql = sql;
final Map<String, Object> finalParams = params;
String rowId = namedJdbc.getJdbcOperations().execute(new PreparedStatementCreator() {
@Override
public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
OraclePreparedStatement stmt = (OraclePreparedStatement) con.prepareStatement(finalSql);
for (Map.Entry<String, Object> entry : finalParams.entrySet()) {
stmt.setObjectAtName(entry.getKey(), entry.getValue());//jdbc driver will choose type
}
stmt.registerReturnParameter(finalParams.entrySet().size()+1, OracleTypes.VARCHAR);
return stmt;
}
}, new PreparedStatementCallback<String>() {
@Override
public String doInPreparedStatement(PreparedStatement s) throws SQLException, DataAccessException {
OraclePreparedStatement stmt = (OraclePreparedStatement) s;
stmt.executeUpdate();
ResultSet rs = stmt.getReturnResultSet();
try {
if (rs.next()) {
return rs.getString(1);
}
throw new IllegalStateException("ROWID not returned");
} finally {
rs.close();
}
}
});
if (rowId != null) {
updateAuditColumns(table, "ROWID", rowId, false);
}
}