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是阿里巴 ...
随机推荐
- 一秒完成springboot与logback配置
1. 一秒配置与效果 1.1 一秒配置 spring boot中无须添加任何依赖,直接在resources文件夹下面新建logback.xml文件,将以下代码复制过去,配置完成,可以使用了. &l ...
- 硬件笔记之Thinkpad T470P更换2K屏幕
0x00 前言 手上的Thinkpad T470P屏幕是1920x1080的屏幕,色域范围NTSC 45%,作为一块办公用屏是正常配置,但是考虑到色彩显示和色域范围,计划升级到2K屏幕. 2k屏幕参数 ...
- 关于Linux服务器配置java环境遇到的问题
关于Linux服务器配置java环境遇到的问题 将下载好的JDK安装包解压到/etc/local/路径下,安装完后用vim/etc/profile文件,在文件末尾添加 export JAVA_HOME ...
- 获取文件版本(IE)
GetFileInfoCUIAction::GetFileVersion2GetSystemDirectory WCHAR szConfigFile[MAX_PATH + 1]; ::G ...
- 默认文档接卸--手机web app开发笔记(二)
首先我们启动HBuilderX2.0 ,界面如图2-1所示 图2-1 软件开发界面 单击“文件—新建—项目”,弹出新建项目管理界面,我们在里面进行了项目类型选择“5+APP”.项目名称填写“编程之路” ...
- idea的安装与配置及基本用法
Intellij IDEA 确实使用更加方便,由于目前只用到maven项目,所以此处只记录maven项目的配置. 一.配置idea前准备: 1.下载idea安装包.jdk安装包.maven安装包.gi ...
- SpringMvc返回JSON出现"$.result.currentLevel"
"$.result.currentLevel" 问题描述 使用SpringMvc返回一个json数据的时候,会在产生的结果中出现如下的问题:"$.result.curre ...
- 关于Redis的几件小事 | 高并发和高可用
如果你用redis缓存技术的话,肯定要考虑如何用redis来加多台机器,保证redis是高并发的,还有就是如何让Redis保证自己不是挂掉以后就直接死掉了. redis高并发:主从架构,一主多从,一般 ...
- [opengl] 画一个可移动的自行车 二维几何变换(平移、旋转、缩放)
#include <cmath> #include "glut.h" #include "iostream" using namespace std ...
- C#中的Contains与IndexOf的区别
C#中要判断一个字符串是否包含另一个字符串,常用的两种方法是 str.Contains和str.IndexOf 这两个方法的区别是: Contains是找指定字符串是否包含一个字串,返回值的bo ...