将 MariaDB 时态表与 spring 数据一起使用 jpa 本机查询没有给我正确的结果
Using MariaDB temporal tables with spring data jpa native query is not giving me the correct result
public interface PeseeRepository extends JpaRepository<Pesee, Integer> {
...
@Query(value = "SELECT * FROM pesee FOR SYSTEM_TIME all WHERE id_pesage = ?1", nativeQuery = true)
List<Pesee> findAllPeseeHystoryById(Integer id);
...
}
日志:
Hibernate:
SELECT
*
FROM
pesee FOR SYSTEM_TIME all
WHERE
id_pesage = ?
我程序中本机查询的结果:
原始 sql 例子:
SELECT
*
FROM
pesee FOR SYSTEM_TIME all
WHERE
id_pesage = 1879;
原始结果 sql:
显然本机 jpa 查询 return 与标准 sql 查询的结果不同。
但正确检测到行数。
这是我的问题:如何使 mariadb table 版本控制在我的 spring 启动应用程序中工作?
目标只是return我的历史一个table.
我通过较低级别的查询找到了解决问题的方法
https://javabydeveloper.com/spring-jdbctemplate-query-examples/#preparedstatementcreator
public class PeseeMapper implements RowMapper<Pesee> {
private final OffsetDateTime odt = OffsetDateTime.now(ZoneId.systemDefault());
private final ZoneOffset zoneOffSet = ZoneOffset.of(String.valueOf(odt.getOffset()));
@Override
public Pesee mapRow(ResultSet rs, int rowNum) throws SQLException {
return new Pesee(
rs.getTimestamp("date_poids_1").toInstant().atOffset(zoneOffSet),
rs.getInt("poids_1"),
rs.getTimestamp("date_poids_2").toInstant().atOffset(zoneOffSet),
rs.getInt("poids_2"),
rs.getString("destination"),
rs.getTimestamp("date_creation").toInstant().atOffset(zoneOffSet),
rs.getTimestamp("date_modification").toInstant().atOffset(zoneOffSet),
);
}
}
public class PeseePreparedStatementCreator implements PreparedStatementCreator, SqlProvider {
private String sql;
private Integer param;
public PeseePreparedStatementCreator(String sql, Integer param) {
this.sql = sql;
this.param = param;
}
@Override
public String getSql() {
return sql;
}
@Override
public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
PreparedStatement ps = con.prepareStatement(getSql(), ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
ps.setInt(1, param);
return ps;
}
}
@Repository
public class PeseeJDBC {
@Autowired
JdbcTemplate jdbcTemplate;
public List<Pesee> findAllPeseeHystoryById(Integer id) {
String sql = "SELECT * FROM pesee FOR SYSTEM_TIME all WHERE id_pesage = ? ORDER BY date_modification DESC";
return jdbcTemplate.query(new PeseePreparedStatementCreator(sql, id), new PeseeMapper());
}
}
现在 returns 我是时间 table 的正确结果
为了恢复对象,我调用了 PeseeJDBC 中的服务并将其传输到 PeseeMapper
然后在 PeseeMapper class 中,我从传输的服务中调用了 findById。 (我没有在示例代码中添加这个,以免使最初的问题复杂化)
它在架构层面上有点不稳定,但它是实用的
public interface PeseeRepository extends JpaRepository<Pesee, Integer> {
...
@Query(value = "SELECT * FROM pesee FOR SYSTEM_TIME all WHERE id_pesage = ?1", nativeQuery = true)
List<Pesee> findAllPeseeHystoryById(Integer id);
...
}
日志:
Hibernate:
SELECT
*
FROM
pesee FOR SYSTEM_TIME all
WHERE
id_pesage = ?
我程序中本机查询的结果:
原始 sql 例子:
SELECT
*
FROM
pesee FOR SYSTEM_TIME all
WHERE
id_pesage = 1879;
原始结果 sql:
显然本机 jpa 查询 return 与标准 sql 查询的结果不同。
但正确检测到行数。
这是我的问题:如何使 mariadb table 版本控制在我的 spring 启动应用程序中工作? 目标只是return我的历史一个table.
我通过较低级别的查询找到了解决问题的方法
https://javabydeveloper.com/spring-jdbctemplate-query-examples/#preparedstatementcreator
public class PeseeMapper implements RowMapper<Pesee> {
private final OffsetDateTime odt = OffsetDateTime.now(ZoneId.systemDefault());
private final ZoneOffset zoneOffSet = ZoneOffset.of(String.valueOf(odt.getOffset()));
@Override
public Pesee mapRow(ResultSet rs, int rowNum) throws SQLException {
return new Pesee(
rs.getTimestamp("date_poids_1").toInstant().atOffset(zoneOffSet),
rs.getInt("poids_1"),
rs.getTimestamp("date_poids_2").toInstant().atOffset(zoneOffSet),
rs.getInt("poids_2"),
rs.getString("destination"),
rs.getTimestamp("date_creation").toInstant().atOffset(zoneOffSet),
rs.getTimestamp("date_modification").toInstant().atOffset(zoneOffSet),
);
}
}
public class PeseePreparedStatementCreator implements PreparedStatementCreator, SqlProvider {
private String sql;
private Integer param;
public PeseePreparedStatementCreator(String sql, Integer param) {
this.sql = sql;
this.param = param;
}
@Override
public String getSql() {
return sql;
}
@Override
public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
PreparedStatement ps = con.prepareStatement(getSql(), ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
ps.setInt(1, param);
return ps;
}
}
@Repository
public class PeseeJDBC {
@Autowired
JdbcTemplate jdbcTemplate;
public List<Pesee> findAllPeseeHystoryById(Integer id) {
String sql = "SELECT * FROM pesee FOR SYSTEM_TIME all WHERE id_pesage = ? ORDER BY date_modification DESC";
return jdbcTemplate.query(new PeseePreparedStatementCreator(sql, id), new PeseeMapper());
}
}
现在 returns 我是时间 table 的正确结果
为了恢复对象,我调用了 PeseeJDBC 中的服务并将其传输到 PeseeMapper 然后在 PeseeMapper class 中,我从传输的服务中调用了 findById。 (我没有在示例代码中添加这个,以免使最初的问题复杂化) 它在架构层面上有点不稳定,但它是实用的