1.表CREATE TABLE `demo` (
`id` bigint(11) NOT NULL AUTO_INCREMENT COMMENT '物理主键',
`demo_id` varchar(32) NOT NULL COMMENT '业务主键',
`demo_name` varchar(255) DEFAULT NULL COMMENT '名称',
`total_num` int(11) DEFAULT NULL COMMENT '数字',
`version` bigint(20) DEFAULT '0' COMMENT '版本号:乐观锁专用',
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `demo_id` (`demo_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 ROW_FORMAT=COMPACT COMMENT='测试专用表';
ps:version字段必不可少,我这里用的数值类型,可统计数据更新评率
2.代码
默认支持delete
deleteByPrimaryKey
updateByPrimaryKey
updateByPrimaryKeySelective
updateByExample
updateByExampleSelective
实体:@Getter
@Setter
@Table(name = "`demo`")
public class Demo extends BaseBean {
private static final long serialVersionUID = -5862829001800404154L;
/**
* 物理主键
*/
@Id
@Column(name = "`id`")
@GeneratedValue(strategy = GenerationType.IDENTITY, generator = "SELECT LAST_INSERT_ID()")
private Long id;
/**
* 业务主键
*/
@Column(name = "`demo_id`")
private String demoId;
/**
* 名称
*/
@Column(name = "`demo_name`")
private String demoName;
/**
* 数字
*/
@Column(name = "`total_num`")
private Integer totalNum;
/**
* 版本号:乐观锁专用
*/
@Column(name = "`version`")
@Version
private Long version;
/**
* 创建时间
*/
@Column(name = "`create_time`")
private Date createTime;
/**
* 更新时间
*/
@Column(name = "`update_time`")
private Date updateTime;
}
ps:以下是tk.mapper的源码,可见默认支持int和long以及时间戳类型,当然如果需要自定义,实现该接口即可// 版本字段标识的注解
@tk.mybatis.mapper.annotation.version
//实现接口
tk.mybatis.mapper.version.NextVersion
//默认实现策略
tk.mybatis.mapper.version.DefaultNextVersion
//源码例子
public class DefaultNextVersion implements NextVersion {
public DefaultNextVersion() {
}
public Object nextVersion(Object current) throws VersionException {
if (current == null) {
throw new VersionException("当前版本号为空!");
} else if (current instanceof Integer) {
return (Integer)current + 1;
} else if (current instanceof Long) {
return (Long)current + 1L;
} else if (current instanceof Timestamp) {
return new Timestamp(System.currentTimeMillis());
} else {
throw new VersionException("默认的 NextVersion 只支持 Integer, Long 和 java.sql.Timestamp 类型的版本号,如果有需要请自行扩展!");
}
}
}
3.测试@Slf4j
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = Main.class)
public class VersionTest{
@Autowired
private DemoMapper demoMapper;
@Autowired
private ThreadPoolTaskExecutor taskExecutor;
private Long id;
@Before
public void before() {
Demo demo = new Demo();
demo.setDemoId(AppUtils.getUUID19());
demo.setDemoName("测试一号");
demo.setTotalNum(RandomUtils.nextInt(0, 100000));
demoMapper.insertSelective(demo);
id = demo.getId();
}
@Test
public void insert() {
Demo demo = demoMapper.selectByPrimaryKey(id);
demo.setTotalNum(RandomUtils.nextInt(0, 100000));
demoMapper.updateByPrimaryKey(demo);
}
@Test
public void multiThread() {
for (int i = 0; i < 20; i++) {
int finalI = i;
taskExecutor.execute(() -> {
Demo demo = demoMapper.selectByPrimaryKey(id);
demo.setTotalNum(finalI);
log.info("第{}次修改结果:{}", finalI, demoMapper.updateByPrimaryKey(demo));
});
}
}
@After
public void after() throws InterruptedException {
Thread.sleep(10 * 1000);
log.info("运行结束");
}
}
测试结果:DEBUG [main] insertSelective:159- ==> Preparing: INSERT INTO `demo` ( `id`,`demo_id`,`demo_name`,`total_num` ) VALUES( ?,?,?,? )
DEBUG [main] insertSelective:159- ==> Parameters: null, HTNGBUKRSUDSJEJ5M7K(String), 测试N号(String), 68031(Integer)
DEBUG [main] insertSelective:159- <== Updates: 1
DEBUG [main] insertSelective!selectKey:159- ==> Executing: SELECT LAST_INSERT_ID()
DEBUG [main] insertSelective!selectKey:159- <== Total: 1
DEBUG [main] selectByPrimaryKey:159- ==> Preparing: SELECT `id`,`demo_id`,`demo_name`,`total_num`,`version`,`create_time`,`update_time` FROM `demo` WHERE `id` = ?
DEBUG [main] selectByPrimaryKey:159- ==> Parameters: 5(Long)
DEBUG [main] selectByPrimaryKey:159- <== Total: 1
DEBUG [main] updateByPrimaryKey:159- ==> Preparing: UPDATE `demo` SET `demo_id` = ?,`demo_name` = ?,`total_num` = ?,`version` = ?,`create_time` = ?,`update_time` = ? WHERE `id` = ? AND `version` = ?
DEBUG [main] updateByPrimaryKey:159- ==> Parameters: HTNGBUKRSUDSJEJ5M7K(String), 测试N号(String), 54481(Integer), 1(Long), 2019-08-23 09:04:39.0(Timestamp), 2019-08-23 09:04:39.0(Timestamp), 5(Long), 0(Long)
DEBUG [main] updateByPrimaryKey:159- <== Updates: 1
INFO [main] VersionTest:58- 运行结束
ps:Main类是我springboot的启动类,当然了,这里是基于springboot工程做的测试