扩展通用Mapper
在生产环境中,很多表的数据原则上是不能直接删除的,而是使用逻辑删除操作。
准备
修改原来的 User 表,添加 is_delete 列,1 表示已删除,0表示有效记录
CREATE TABLE `user` (
`id` bigint(11) unsigned NOT NULL COMMENT '主键',
`username` varchar(32) NOT NULL COMMENT '用户名',
`passwd` varchar(64) NOT NULL COMMENT '密码',
`sex` tinyint(2) unsigned NOT NULL DEFAULT '0' COMMENT '性别,0保密1男2女',
`birthday` date NOT NULL DEFAULT '0000-00-00' COMMENT '生日',
`is_delete` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '是否删除,0否1是',
PRIMARY KEY (`id`),
KEY `username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='会员';
操作步骤
一、创建 model 类基类,所有需要逻辑删除的 model 继承该类
public class GenericModel {
@Column
private boolean isDelete;
}
二、修改 UserModel,继承 GenericModel 类
@Getter
@Setter
@EqualsAndHashCode(callSuper = true)
public class User extends GenericModel {
@Id
private Long id;
@Column
private String username;
@Column(name = "passwd")
private String password;
@Column
private int sex;
@Column
private LocalDateTime birthday;
}
三、实现自定义 mapper 接口
类上必须加上 @RegisterMapper 注解,用于自动注册。
逻辑删除,实际上是一个修改操作,所以使用 @UpdateProvider。
真正实现 SQL 语句组装是在 DisableProvider 类中进行的。
@RegisterMapper
public interface DisableMapper<T> {
@UpdateProvider(type = DisableProvider.class, method = "dynamicSQL")
int disable(T value);
@UpdateProvider(type = DisableProvider.class, method = "dynamicSQL")
int enable(T value);
}
四、实现自定义 Provider
DisableProvider 需要继承自 MapperTemplate。
public class DisableProvider extends MapperTemplate {
public DisableProvider(Class<?> mapperClass, MapperHelper mapperHelper) {
super(mapperClass, mapperHelper);
}
public String disable(MappedStatement ms) {
Class<?> entityClass = getEntityClass(ms);
StringBuilder sql = new StringBuilder();
sql.append(SqlHelper.updateTable(entityClass, tableName(entityClass)));
sql.append("is_delete").append(" = ").append("1");
sql.append(SqlHelper.wherePKColumns(entityClass, true));
return sql.toString();
}
public String enable(MappedStatement ms) {
Class<?> entityClass = getEntityClass(ms);
StringBuilder sql = new StringBuilder();
sql.append(SqlHelper.updateTable(entityClass, tableName(entityClass)));
sql.append("is_delete").append(" = ").append("0");
sql.append(SqlHelper.wherePKColumns(entityClass, true));
return sql.toString();
}
}
五、通用 Mapper 实现自定义 Mapper
通用 Mapper 在实现 Mapper 及 MySqlMapper 的同时也实现了自定义的 DisableMapper 接口,拥有了 disable 以及 enable 操作。
public interface BaseRepository<T> extends Mapper<T>, MySqlMapper<T>, DisableMapper<T> {}
//—
SqlHelper中提供了大量方法用于组装SQL
获取当前操作的数据对象
Class<?> entityClass = getEntityClass(ms)
如果是查询语句,返回的是一个对象,则需要设置返回类型
setResultType(ms, entityClass);
组装一个查询语句
// select col1,col2...
sql.append(SqlHelper.selectAllColumns(entityClass));
// from tablename - 支持动态表名
sql.append(SqlHelper.fromTable(entityClass, tableName(entityClass)));
// order by xxx
sql.append(SqlHelper.orderByDefault(entityClass));
组装一个修改语句
// update tablename
sql.append(SqlHelper.updateTable(entityClass, tableName(entityClass)));
// set col1=col1,col2=col2...
sql.append(SqlHelper.updateSetColumns(entityClass, null, false, false));
// where pk=xxx
sql.append(SqlHelper.wherePKColumns(entityClass, true));