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实现逻辑删除
tk.mybatis扩展通用接口的更多相关文章
- 初识 tk.mybatis.mapper 通用mapper
在博客园发表Mybatis Dynamic Query后,一位园友问我知不知道通用mapper,仔细去找了一下,还真的有啊,比较好的就是abel533写的tk.mybatis.mapper. 本次例子 ...
- java-mybaits-015-mybatis逆向工程最佳实践【基础mybatis-generator、tk.mybatis、mubatis-plus】
一.概述 三款框架的功能对比 Mybatis-generator 通用Mapper Mybatis-Plus 代码生成器 支持自动生成Model,Mapper,Mapper XML文件 生成方式不够灵 ...
- Java EE开发平台随手记4——Mybatis扩展3
接着昨天的Mybatis扩展——IDaoTemplate接口. 扩展9:批量执行 1.明确什么是批量执行 首先说明一下,这里的批量执行不是利用<foreach>标签生成一长串的sql字符串 ...
- SpringBoot2.1整合Mybatis-Generator以及tk.mybatis
1:添加依赖 <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http ...
- 扩展mybatis和通用mapper,支持mysql的geometry类型字段
因项目中需要用到地理位置信息的存储.查询.计算等,经过研究决定使用mysql(5.7版本)数据库的geometry类型字段来保存地理位置坐标,使用虚拟列(Virtual Generated Colum ...
- SpringBoot框架之通用mapper插件(tk.mybatis)
一.Tkmybatis的好处 Tkmybatis是在mybatis框架的基础上提供了很多工具,让开发更加高效.这个插件里面封装好了我们需要用到的很多sql语句,不过这个插件是通过我们去调用它封装的各种 ...
- javaweb各种框架组合案例(九):springboot+tk.mybatis+通用service
一.项目结构 二.pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns= ...
- tk.mybatis通用插件updateByPrimaryKeySelective无法自动更新ON UPDATE CURRENT_TIMESTAMP列的解决办法
tk.mybatis是一个很好用的通用插件,把CRUD这些基本的数据操作全都用动态SQL语句自动生成了,mapper和xml里十分清爽,但是昨天发现有一个小坑,记录在此: 有一张表,结构如下(已经简化 ...
- spring-boot集成4:集成mybatis,druid和tk.mybatis
Why mybatis? mybatis提供了ORM功能,相比于其他ORM框架,其需要编写更多的sql,也给了我们编写特殊/复杂sql和进行sql优化的机会. Why druid? Druid是阿里巴 ...
随机推荐
- [1045] PDOException in Connection.php line 295
tp5实现登录功能时报错 在使用tp5框架实现登录功能的时候,点击login出现了 [1045] PDOException in Connection.php line 295 这个问题, 报错是 S ...
- CAD2014学习笔记-图层图案图块
基于 虎课网huke88.com CAD教程 对象特性 选择对象点击特性栏/或右键点击特性 颜色:color 图层 线型:线的类型,如点状线.虚线等,若不改变则默认新建的线为该类型 线型比例:不同类型 ...
- Maven(一)Maven 的概念和安装
Maven 的概念和安装 Maven 是什么 首先 Maven 肯定是一个造福人类的好东西,它可以省去我们构建项目中引入 jar 包时的麻烦,还有利于项目的模块化开发等等等好处.在如今项目中大体都是使 ...
- 洛谷P1640 [SCOI2010]连续攻击游戏 题解
题目链接: https://www.luogu.org/problemnew/show/P1640 分析: 这道题用二分图来解决即可.应该可以作为网络流中的模板题来食用, 每一个武器有两个属性,但是只 ...
- Excel催化剂开源第13波-VSTO开发之DataGridView控件几个小坑
Excel催化剂内部大量使用了DataGridView,这其中有一些小坑,花了力气才解决的,在此给广大开发者作简单分享. 为何要使用DataGridView而不是其他控件如ListBox.ListVi ...
- NameNode故障处理方法
NameNode故障处理方法 简述 NameNode故障后,可以通过下列两种方式进行恢复数据: 方法一(手动):将SecondaryNameNode文件下的数据复制到NameNode中 方法二(程序) ...
- DAX 第三篇:过滤器函数
过滤器函数允许你操纵筛选上下文以创建动态的计算. 一,筛选上下文的构成 DAX中的筛选上下文由三部分构成:交叉过滤构成的过滤,查询上下文中每行的列值构成的过滤,外部切片器构成的显式过滤. 1,交叉过滤 ...
- Hadoop学习-hdfs安装及其一些操作
hdfs:分布式文件系统 有目录结构,顶层目录是: /,存的是文件,把文件存入hdfs后,会把这个文件进行切块并且进行备份,切块大小和备份的数量有客户决定. 存文件的叫datanode,记录文件的切 ...
- 2019牛客多校第一场 E-ABBA(dp)
ABBA 题目传送门 解题思路 用dp[i][j]来表示前i+j个字符中,有i个A和j个B的合法情况个数.我们可以让前n个A作为AB的A,因为如果我们用后面的A作为AB的A,我们一定也可以让前面的A对 ...
- Android入门简介
GeoQuiz应用是由一个activity和一个布局(layout)组成. activity是Android SDK中Activity类的一个具体实例,负责管理用户与信息屏的交互. 布局定义了一系列用 ...