tk.Mybatis 扩展通用mapper
前文提要
引言
tk.mybatis项目中提供了大量现成的方法,这些方法可以作为扩展时的参考。
例如 tk.mybatis.mapper.common.ids
包中的 批量删除接口DeleteByIdsMapper
@RegisterMapper public interface DeleteByIdsMapper<T> { @DeleteProvider( type = IdsProvider.class, method = "dynamicSQL" ) int deleteByIds(String var1); }
SQL模版生产者IdsProvider.class
的源码如下,继承了MapperTemplate
模版接口
public class IdsProvider extends MapperTemplate { public IdsProvider(Class<?> mapperClass, MapperHelper mapperHelper) { super(mapperClass, mapperHelper); } public String deleteByIds(MappedStatement ms) { Class<?> entityClass = this.getEntityClass(ms); StringBuilder sql = new StringBuilder(); sql.append(SqlHelper.deleteFromTable(entityClass, this.tableName(entityClass))); Set<EntityColumn> columnList = EntityHelper.getPKColumns(entityClass); if (columnList.size() == 1) { EntityColumn column = (EntityColumn)columnList.iterator().next(); sql.append(" where "); sql.append(column.getColumn()); sql.append(" in (${_parameter})"); return sql.toString(); } else { throw new MapperException("继承 deleteByIds 方法的实体类[" + entityClass.getCanonicalName() + "]中必须只有一个带有 @Id 注解的字段"); } } ... ... //省略
上面的代码实际上就是对sql语句的拼接,由此可得我们只需要创建一个mappr接口,然后再创建一个provider继承MapperTemplate
模版接口即可
更多template的功能可以参考这篇博客 《基于tk.mybatis扩展自己的通用mapper》
扩展通用mapper
创建自定义接口:DletetByCodesMapper
注意,这个类不能被MapperScan 扫描到,否则会报错
@RegisterMapper public interface DletetByCodesMapper<T> { @DeleteProvider( type = IdsProviderExt.class, method = "dynamicSQL" ) int deleteByCodes(String[] arr); }
创建自定义模版:IdsProviderExt
由于我的数据主键是UUID,所以依据IdsProvider进行了扩展
public class IdsProviderExt extends MapperTemplate { public IdsProviderExt(Class<?> mapperClass, MapperHelper mapperHelper) { super(mapperClass, mapperHelper); } public String deleteByCodes(MappedStatement ms) { Class<?> entityClass = this.getEntityClass(ms); StringBuilder sql = new StringBuilder(); sql.append(SqlHelper.deleteFromTable(entityClass, this.tableName(entityClass))); Set<EntityColumn> columnList = EntityHelper.getPKColumns(entityClass); if (columnList.size() == 1) { EntityColumn column = (EntityColumn)columnList.iterator().next(); sql.append(" where "); // 不指定@Parm的话,数组参数默认使用array接收 sql.append("<foreach collection='array' index='index' item='code' open='(' separator='OR' close=')'>"); sql.append(column.getColumn() + "= #{code}"); sql.append("</foreach>"); return sql.toString(); } else { throw new MapperException("继承 deleteByIds 方法的实体类[" + entityClass.getCanonicalName() + "]中必须只有一个带有 @Id 注解的字段"); } } }
创建MyMapper继承扩展模版
/** * tkMybatis 的 BaseMapper * 特别注意,该接口不能被扫描到,否则会出错 */ public interface MyMapper<T> extends Mapper<T>, MySqlMapper<T> , DeleteByIdsMapper<T>, DletetByCodesMapper<T> { }
generator逆向工程生成 TbSysUserMapper 和XML
TbSysUserMapper 继承了MyMapper接口,所以也就继承了扩展接口
public interface TbSysUserMapper extends MyMapper<TbSysUser> { }
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.funtl.itoken.common.mapper.TbSysUserMapper"> <resultMap id="BaseResultMap" type="com.funtl.itoken.common.domain.entity.TbSysUser"> <!-- WARNING - @mbg.generated --> <id column="user_code" jdbcType="VARCHAR" property="userCode" /> <result column="login_code" jdbcType="VARCHAR" property="loginCode" /> <result column="user_name" jdbcType="VARCHAR" property="userName" /> <result column="password" jdbcType="VARCHAR" property="password" /> <result column="email" jdbcType="VARCHAR" property="email" /> <result column="mobile" jdbcType="VARCHAR" property="mobile" /> <result column="phone" jdbcType="VARCHAR" property="phone" /> <!--省略-->
创建Spring Boot启动类
@MapperScan(basePackages = {"com.funtl.itoken.common.mapper","com.funtl.itoken.service.admin.mapper"})//dao路径 public class ServiceAdminApplication { public static void main(String[] args) { SpringApplication.run(ServiceAdminApplication.class,args); } }
Junit Test 测试代码
@RunWith(SpringRunner.class) @SpringBootTest(classes = ServiceAdminApplication.class) @Transactional public class MyBatisTests{ /** * 注入数据查询接口 */ @Autowired private TbSysUserMapper tbUserMapper; /** * 测试批量删除 */ @Test @Rollback public void deleteByCodes() { String[] codes = {"5bb38bf6-2378-431c-88cb-7a38b69df806","c04471e1-fa3b-4d6e-ba98-e806dc5ad07c"}; int i = tbUserMapper.deleteByCodes(codes); info("删除数量:"+i);//这个是我的自定义函数,自行打印即可 } }
结果