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

网友投稿 479 2022-12-30


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

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

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

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

例如 selectAll 方法。

首先定义接口:

@RegisterMapper

public interface SelectAllMapper {

/**

* 查询全部结果

*

* @return

*/

@SelectProvider(type = MySelectProvider.class, method = "dynamicSQL")

List 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,MyBatis 会认为返回值类型为 List,这和我们想要的实体类型不一样,所以下一行代码就是设置返回值类型:

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 {

/**

* 根据主键查询没有被逻辑删除的实体

*

* @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("");

//获取全部列

Set 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("");

return sql.toString();

}

}

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

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

最后在通用service中引入,

@Autowired private BasicMapper<T> mapper;

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

public interface UserPOMapper extends BasicMapper {}

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


版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:微服务网关怎样请求服务(微服务通过网关访问)
下一篇:前端接口测试工具(接口在线测试工具)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~