天天看点

MyBatis-Plus 分表实践

前两天遇到一个分表存储的场景,受网上的一点启发,最终实践成功。

场景

库里有个日志表做了分表,主要存储用户在前端操作的日志记录。

MyBatis-Plus 分表实践

我看了下项目中已有的做法

我搜索了一下项目,发现项目中已经有实现这种场景的业务了。但是做法让我很不喜欢。

service 层定义了 10 个mapper,然后通过计算得出存储到第几个表,接着用switch case 判断来存储到不同的表中。

// 定义了 10 个mapper
@Autowired
private LogCzrz0Mapper czrzMapper0;
@Autowired
private LogCzrz1Mapper czrzMapper1;
...
@Autowired
private LogCzrz9Mapper czrzMapper9;

public void save() {
	// 通过计算得出num,表示存储到哪个表
	int num = calculate();
	switch (num) {
		case 0:
		czrzMapper0.save();
		break;
		case 1:
		czrzMapper1.save();
		break;
		...
		case 9:
		czrzMapper9.save();
		break;
	}
}
           

上面写了一段伪代码,计算出 num,再存储到相对应的表中。

受网上启发

在 mapper.xml 定义 sql 的时候是可以将分表后面的 num 作为一个变量。

那话不多说,赶紧行动起来。

// 我在LogCzrz0Mapper.xml定义一段 insert sql
<insert id="insertMoreTable" parameterType="map">
    	INSERT INTO log_system_xtrz${num} (logoid, param_new, createtime, createuserid, updatetime, updateuserid) 
    	VALUES (#{logoid}, #{paramNew},  #{createtime}, #{createuserid}, #{logoiupdatetimed}, #{updateuserid}); 
</insert>

// service 层
@Autowired
private LogCzrz0Mapper czrzMapper0;

public void save() {
	// 通过计算得出num,表示存储到哪个表
	int num = calculate();
	Map<String,Object> map = new HashMap<>();
	map.put("num",num);
	czrzMapper0.insertMoreTable(map);
}

运行结果:
Preparing: INSERT INTO log_system_czrz3 (logoid, fjm, ywcode, ip, user_type, user_name, czsj, ywlx, czlx, accessfrom, bz, workerid, datacenterid, createtime, createuserid, updatetime, updateuserid) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?); 
Parameters: 578222033083564032(Long), JJJ(String), 259710392215870323(String), 127.0.0.1(String), 10(String), liujian(String), 2019-05-15 14:07:55.533(Timestamp), test(String), test(String), test(String), null, 0(String), 0(String), 2019-05-15 14:07:55.533(Timestamp), null, null, null
Updates: 1
           

我把 num,以及需要存储的字段和值放到 map 中,传入到 insert 语句中,最终保存成功。

${num} 和 #{num} 的区别

这个问题网上有很多详细的解答,我在此就简略的说一下。

我一开始用 #{num},控制台报错的,原因是会将 #{num} 这个变量变成 ?,进行了预处理。结果就是 log_system_czrz?,执行这条 sql 的时候就会报错。

而 ${num} 不会进行预处理,直接将此变量赋值,就是 log_system_czrz3 这样一种效果。

结语

虽然可能不是很难的一个东西,但是就作为一个记录,或许能够帮助到有遇到相同情况的人。