记录一次开发中遇到的关于通用mapper批量新增问题. 在一次需求中,遇到批量新增, 因不想写复杂的xml语句, 想起曾看到过通用mapper提供了相关的接口, 所以就直接使用,然后出现了问题,如是有了这篇文章
1 问题引入
1 问题说明
需求: 业务数据批量新增, 主键非自增,而是采用uuid生成.
对于批量新增,通用mapper提供两个接口tk.mybatis.mapper.additional.insert.InsertListMapper 和 tk.mybatis.mapper.common.special.InsertListMapper . 在导入InsertMapper类时, 没注意到其区别, 导致项目中引入了后者,即tk.mybatis.mapper.common.special.InsertListMapper 类, 在后续批量新增操作中, 数据库报错, 参数id不存在.
尝试一:
在去掉数据库主键约束后, 数据成功入库,但是主键id列数据都为空.
尝试二:
在使用for循环标签语句添加数据库时, 数据没有问题.
2 问题分析
根据上述尝试操作, 问题出现在批量新增的接口,且查看批量相关的sql语句,发现没有插入id.查询了相关资料,发现通用mapper提供的两个接口具体用途不一样.
1 tk.mybatis.mapper.additional.insert.InsertListMapper
此类是不支持主键策略, 即批量插入前,需要手动添加好主键值.
@RegisterMapper
public interface InsertListMapper<T> {
@InsertProvider(type = InsertListProvider.class, method = "dynamicSQL")
int insertList(List<? extends T> recordList);
}
2 tk.mybatis.mapper.common.special.InsertListMapper
此类支持主键策略, 要求实体类中必须包含id属性且必须为自增主键.
@tk.mybatis.mapper.annotation.RegisterMapper
public interface InsertListMapper<T> {
@Options(useGeneratedKeys = true)
@InsertProvider(type = SpecialProvider.class, method = "dynamicSQL")
int insertList(List<? extends T> recordList);
}
2 问题解决
切换导入的InsertListMapper类, 使用tk.mybatis.mapper.additional.insert.InsertListMapper 类后,数据成功入库. 对于上述问题,即在使用开源的工具时,还是需要多了解其相关用法,也需要多多实践去验证.
3 通用mapper相关注解说明
1 @Table
@Table注解是表示实体类和数据库表之前的映射关系. 默认开启驼峰命名(tb_user => tbUser),也可通过name手动映射.
@Table(name = "t_user")
public class user{
}
2 @Column
@Column注解是表示实体类属性和数据库表列名的映射关系.默认开启驼峰命名(is_use => isUse),可手动映射
3 @Id
@Id 注解表示实体类该属性和数据库主键映射关系
4 @GeneratedValue
@GeneratedValue注解是通用 Mapper 在执行插入数据之后将数据库自动生成的主键值回写到实体类对象中,和@Id 注解一起使用.
5 @KeySql
@KeySql注解是主键策略注解,用于配置如何生成主键.
6 @Transient
@Transient注解, 瞬时的,不持久化的.即表示在实体类和数据库映射时忽略.
|