前言
jpa是通过对实体上注解表名的方式来绑定对象和数据库表的关系,并进行读写的。但有时我们会需要动态的读写表,比如同一张表带日期后缀名table_yyyyMM。本文介绍如何使用拦截器来达到这一目的。
jpa拦截器
在生成jdbc语句之前,hibernate会将sql经过拦截器处理。我们可以通过实现StatementInspector
接口来自定义在拦截到sql时如何进行处理。
接下来实现接口,并做相应的表明替换:
public class MyInspector implements StatementInspector {
@Override
public String inspect(String sql) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
String formattedDate = dateFormat.format(new Date());
return sql.replace("yyyyMM", formattedDate);
}
}
这是实体类中Table注解的占位:
@Entity
@Table(name = "test_tb_yyyyMM")
@Cacheable(value = false)
public class TestTb {
// 省略实体属性
}
对应配置
通过修改yml配置来注册我们自定义的拦截器。注意,虽然session_factory
和statement_inspector
在idea中没法直接打出来,但还是能正常工作的。其中show-sql
命令会将执行的sql打印出来,方便观察效果。
spring:
jpa:
database: MySQL
show-sql: true
properties:
hibernate:
session_factory:
statement_inspector: com.example.jpademo.MyInspector
这样就通过修改sql拦截器的方式,实现了对sql中表明的动态调整。比如当前时间是202312,那么就能识别到table_202312,下个月能自动识别table_202401。