tk.mybatis扩展通用接口使用详解

 更新时间:2019年08月21日 09:18:50   作者:梦飞翔up  
这篇文章主要介绍了tk.mybatis扩展通用接口使用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

 一.tk.mybatis已经为我们封装好了许多拆箱即用的通用mapper,但在实际的项目开发中想必不少小伙伴在数据库设计中都会采用逻辑删除这种方案,再去使用通用的mapper接口就不行了。

这时候就需要我们封装一些扩展的通用Mapper接口。

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

例如 selectAll 方法。

首先定义接口:

@RegisterMapper
public interface SelectAllMapper<T> {
  /**
   * 查询全部结果
   *
   * @return
   */
  @SelectProvider(type = MySelectProvider.class, method = "dynamicSQL")
  List<T> selectAll();
}

其中 MySelectProvider 是你要实现的一个类,该类需要继承 MapperTemplate。@RegisterMapper 注解可以避免 mappers 参数配置,通用 Mapper 检测到该接口被继承时,会自动注册。

import org.apache.ibatis.mapping.MappedStatement;
import tk.mybatis.mapper.mapperhelper.MapperHelper;
import tk.mybatis.mapper.mapperhelper.MapperTemplate;
import tk.mybatis.mapper.mapperhelper.SqlHelper;
public class MySelectProvider extends MapperTemplate {
  public BaseSelectProvider(Class<?> mapperClass, MapperHelper mapperHelper) {
    super(mapperClass, mapperHelper);
  } 
  /**
   * 查询全部结果
   *
   * @param ms
   * @return
   */
  public String selectAll(MappedStatement ms) {
    final Class<?> entityClass = getEntityClass(ms);
    //修改返回值类型为实体类型
    setResultType(ms, entityClass);
    StringBuilder sql = new StringBuilder();
    sql.append(SqlHelper.selectAllColumns(entityClass));
    sql.append(SqlHelper.fromTable(entityClass, tableName(entityClass)));
    sql.append(SqlHelper.orderByDefault(entityClass));
    return sql.toString();
  }
}

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

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

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

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

setResultType(ms, entityClass);

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

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

/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));

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

三.例:根据主键查询单个实体对象(过滤掉逻辑删除的实体,注:我的数据表逻辑删除字段定义为enabled_status)

首先定义mapper

@RegisterMapper
public interface SelectByKeyAndNotDeletedMapper<T> {
  /**
   * 根据主键查询没有被逻辑删除的实体
   *
   * @return
   */
  @SelectProvider(type = SelectByKeyNotDeletedProvider.class, method = "dynamicSQL")
  T selectByKeyNotDeleted(Object key);
}

其次定义SelectByKeyNotDeletedProvider

public class SelectByKeyNotDeletedProvider extends MapperTemplate {
  public SelectByKeyNotDeletedProvider(Class<?> mapperClass, MapperHelper mapperHelper) {
    super(mapperClass, mapperHelper);
  }

  public String selectByKeyNotDeleted(MappedStatement ms) {
    final Class<?> entityClass = getEntityClass(ms);
    //将返回值修改为实体类型
    setResultType(ms, entityClass);
    StringBuilder sql = new StringBuilder();
    sql.append(SqlHelper.selectAllColumns(entityClass));
    sql.append(SqlHelper.fromTable(entityClass, tableName(entityClass)));
    sql.append(wherePKColumns(entityClass, false));
    return sql.toString();
  }
  private String wherePKColumns(Class<?> entityClass, boolean useVersion) {
    StringBuilder sql = new StringBuilder();
    sql.append("<where>");
    //获取全部列
    Set<EntityColumn> columnSet = EntityHelper.getPKColumns(entityClass);
    //当某个列有主键策略时,不需要考虑他的属性是否为空,因为如果为空,一定会根据主键策略给他生成一个值
    for (EntityColumn column : columnSet) {
      sql.append(" AND " + column.getColumnEqualsHolder());
    }
    if (useVersion) {
      sql.append(whereVersion(entityClass));
    }
    //过滤被逻辑删除的数据
    sql.append(" AND enabled_status = 1 ");
    sql.append("</where>");
    return sql.toString();
  }
}

然后定义BasicMapper,让其继承通用Mapper接口以及上面自定义的SelectByKeyAndNotDeletedMapper接口。

@tk.mybatis.mapper.annotation.RegisterMapper public interface BasicMapper<T> extends Mapper<T>, SelectByKeyAndNotDeletedMapper<T> { }

最后在通用service中引入,

@Autowired private BasicMapper<T> mapper;

自定义*.Mapper都去继承BasicMapper<T>即可

public interface UserPOMapper extends BasicMapper<UserPO> {}

注意:最新版本的tk已经支持根据注解@LogicDelete实现逻辑删除

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • java基本教程之java线程等待与java唤醒线程 java多线程教程

    java基本教程之java线程等待与java唤醒线程 java多线程教程

    这篇文章主要介绍了对线程等待/唤醒方法,文中使用了多个示例,大家参考使用吧
    2014-01-01
  • java基础知识 super和this使用解析

    java基础知识 super和this使用解析

    这篇文章主要介绍了java基础知识 super和this使用解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-11-11
  • JVM常用指令速查表

    JVM常用指令速查表

    总结了一个 JVM 常用指令速查表,今天分享给大家!,需要的朋友可以参考下
    2020-02-02
  • java绘制五子棋棋盘

    java绘制五子棋棋盘

    这篇文章主要为大家详细介绍了java绘制五子棋棋盘,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-01-01
  • SpringBoot2.x 集成 Thymeleaf的详细教程

    SpringBoot2.x 集成 Thymeleaf的详细教程

    本文主要对SpringBoot2.x集成Thymeleaf及其常用语法进行简单总结,其中SpringBoot使用的2.4.5版本。对SpringBoot2.x 集成 Thymeleaf知识感兴趣的朋友跟随小编一起看看吧
    2021-07-07
  • java实现上传文件类型检测过程解析

    java实现上传文件类型检测过程解析

    这篇文章主要介绍了java实现上传文件类型检测过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-12-12
  • 解决SpringMVC拦截器path路径的坑

    解决SpringMVC拦截器path路径的坑

    这篇文章主要介绍了解决SpringMVC拦截器path路径的坑,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-10-10
  • 基于Java编写第一个区块链项目

    基于Java编写第一个区块链项目

    区块链是分布式数据存储、点对点传输、共识机制、加密算法等计算机技术的新型应用模式,下面这篇文章主要给大家介绍了基于Java实现区块链的相关资料,需要的朋友可以参考下
    2021-08-08
  • Java 根据网址查询DNS/IP地址的方法

    Java 根据网址查询DNS/IP地址的方法

    这篇文章主要介绍了Java 根据网址查询DNS/IP地址的方法,具体实现代码,大家参考下本文
    2017-12-12
  • java教程之java注解annotation使用方法

    java教程之java注解annotation使用方法

    这篇文章主要介绍了java注解annotation使用方法,注解可以定义到方法上,类上,一个注解相当与一个类,就相当于实例了一个对象,加上了注解,就相当于加了一个标志
    2014-01-01

最新评论