1.1 需求和大致思路
??要求把mysql的数据定时同步到另一个schema下,并清理数据,不同的表有不同的策略,如sys_operation_log表每个月调度一次备份数据并清理半年前的数据: ??采用springboot schedule定时任务动态(从数据库读取)读取执行
create table if not exists ddh_sbztjk_prod.dump_del
(
id int not null
primary key,
originTable varchar(100) not null,
desTable varchar(100) not null,
primaryCol varchar(100) not null,
delWhere varchar(100) not null,
cron varchar(100) not null
);
<select id="getMax" resultType="java.lang.Long" statementType="STATEMENT">
select max(${col}) from ${des}.${desTable}
</select>
<insert id="insertToAnotherTable" statementType="STATEMENT">
insert into ${des}.${desTable} select * from ${origin}.${originTable}
<where>
<if test="colNum != null">
${col} > ${colNum}
</if>
</where>
</insert>
<delete id="del" statementType="STATEMENT">
delete from ${origin}.${originTable} ${delWhere}
</delete>
1.2 mybatis动态传入表名
在动态sql解析过程,#{}与${}的效果是不一样的:#{} 占位符 ?? ${} 拼接符 ?? #{ } 解析为一个 JDBC 预编译语句(prepared statement)的参数标记符,变量替换后,#{} 对应的变量自动加上单引号 ‘’
?? ${ } 仅仅为一个纯粹的 string 替换,在动态 SQL 解析阶段将会进行变量替换,变量替换后, ${} 对应的变量不会加上单引号
注:
?? ${}在预编译之前已经被变量替换了,这会存在sql注入风险 如
select * from ${tableName} where name = ${name}
如果传入的参数tableName为user; delete user; --,那么sql动态解析之后,预编译之前的sql将变为:
select * from user; delete user;
所以
${}一般用于传输数据库的表名、字段名等,能用
1.3 springboot schedule定时任务动态(从数据库读取)读取执行
mybatisplus反向工程生成实体类DumpDel,以及mapper service
@Data
@EqualsAndHashCode(callSuper = false)
@ApiModel(value="DumpDel对象", description="")
public class DumpDel implements Serializable {
private static final long serialVersionUID=1L;
private Integer id;
@TableField("originTable")
private String originTable;
@TableField("desTable")
private String desTable;
@TableField("primaryCol")
private String primaryCol;
@TableField("delWhere")
private String delWhere;
private String cron;
}
自定义实体类实现接口SchedulingConfigurer 重写configureTasks方法,向scheduledTaskRegistrar中添加任务,每个任务需要Runnable和Trigger Runnable对应调度任务
Trigger对应cron表达式
@Component
public class DataRemoveSchedule implements SchedulingConfigurer {
@Autowired
private IDumpDelService dumpDelService;
@Autowired
private MyService myService;
@Override
public void configureTasks(ScheduledTaskRegistrar scheduledTaskRegistrar) {
List<DumpDel> scheduleList = dumpDelService.list();
for (DumpDel s : scheduleList) {
scheduledTaskRegistrar.addTriggerTask(getRunnable(s), getTrigger(s));
}
}
private Runnable getRunnable(DumpDel scheduleConfig) {
return new Runnable() {
@Override
public void run() {
myService.insertToAnotherTableAndDel(scheduleConfig.getOriginTable(), scheduleConfig.getDesTable(), scheduleConfig.getPrimaryCol(), scheduleConfig.getDelWhere());
}
};
}
private Trigger getTrigger(DumpDel scheduleConfig) {
return new Trigger() {
@Override
public Date nextExecutionTime(TriggerContext triggerContext) {
CronTrigger trigger = new CronTrigger(scheduleConfig.getCron());
Date nextExec = trigger.nextExecutionTime(triggerContext);
return nextExec;
}
};
}
}
|