五、扩展通用接口

项目中提供了大量现成的方法,这些方法可以作为扩展时的参考。

例如 selectAll 方法。

首先定义接口:

  1. @RegisterMapper
  2. public interface SelectAllMapper<T> {
  3. /**
  4. * 查询全部结果
  5. *
  6. * @return
  7. */
  8. @SelectProvider(type = MySelectProvider.class, method = "dynamicSQL")
  9. List<T> selectAll();
  10. }

其中 MySelectProvider 是你要实现的一个类,该类需要继承 MapperTemplate

@RegisterMapper 注解可以避免 mappers 参数配置,通用 Mapper 检测到该接口被继承时,会自动注册。

  1. import org.apache.ibatis.mapping.MappedStatement;
  2. import tk.mybatis.mapper.mapperhelper.MapperHelper;
  3. import tk.mybatis.mapper.mapperhelper.MapperTemplate;
  4. import tk.mybatis.mapper.mapperhelper.SqlHelper;
  5. public class MySelectProvider extends MapperTemplate {
  6. public BaseSelectProvider(Class<?> mapperClass, MapperHelper mapperHelper) {
  7. super(mapperClass, mapperHelper);
  8. }
  9. /**
  10. * 查询全部结果
  11. *
  12. * @param ms
  13. * @return
  14. */
  15. public String selectAll(MappedStatement ms) {
  16. final Class<?> entityClass = getEntityClass(ms);
  17. //修改返回值类型为实体类型
  18. setResultType(ms, entityClass);
  19. StringBuilder sql = new StringBuilder();
  20. sql.append(SqlHelper.selectAllColumns(entityClass));
  21. sql.append(SqlHelper.fromTable(entityClass, tableName(entityClass)));
  22. sql.append(SqlHelper.orderByDefault(entityClass));
  23. return sql.toString();
  24. }
  25. }

其中 selectAll 方法名要和接口中定义的方法名一致。其次就是该方法的参数为 MappedStatement 类型。

在 selectAll 方法中,首先是获取了当前接口的实体类型:

  1. final Class<?> entityClass = getEntityClass(ms);

因为接口返回值类型为 List<T>,MyBatis 会认为返回值类型为 List<Object>,这和我们想要的实体类型不一样,所以下一行代码就是设置返回值类型:

  1. setResultType(ms, entityClass);

注意,只有返回 T 或者 List 时需要设置,返回 int 类型时不需要设置。

接下来就是纯粹的拼接 XML 形式的 SQL 了。

  1. //select col1,col2...
  2. sql.append(SqlHelper.selectAllColumns(entityClass));
  3. //from tablename - 支持动态表名
  4. sql.append(SqlHelper.fromTable(entityClass, tableName(entityClass)));
  5. //order by xxx
  6. sql.append(SqlHelper.orderByDefault(entityClass));

这是其中最简单的一个方法实现。当你想要实现某种方法时,可以从已有的例子中找一个最接近的方法,在此基础上进行修改。