Mybatis Plus 优点
-
开箱即用
-
对原生代码零入侵
-
对市面上大多数数据库均提供支持
Mybatis Plus 基本使用
使用 mybatis plus 增删改查,一般使用以下语法去继承 BaseMapper
/**
* 用户数据库操作
*/
public interface UserMapper extends BaseMapper<User> {
}
然后写一个简单的 service 服务。
public interface UserService extends IService<User> {
/**
* 用户注册
*/
long userRegister(String userAccount, String userPassword, String checkPassword);
}
最终在 UserServiceImpl
编写具体逻辑
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
....
boolean saveResult = this.save(user);
....
}
以上代码就是 mybatis plus 对自带增删改查的基本使用。
源码探析
那么我们没有写过 SQL 或者原生 XML ,是如何通过 this.save(user)
进行插入数据的呢?
使用断点调试我们会发现进入了 basemapper 的 insert 方法中
而在 BaseMapper 中并没有 insert 的具体实现
那么接下来是如何执行的呢?
答案是通过 JDK 动态代理实现的。
Mybatis Plus 在启动时,会为扫描到的每一个 mapper 接口,生成对应代理类,并交由 spring ioc 容器进行管理。
接下来进入代理类(MybatisMapperProxy)的 invoke
方法,查看是如何对 insert
方法,进行增强的。
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
return Object.class.equals(method.getDeclaringClass()) ? method.invoke(this, args) : this.cachedInvoker(method).invoke(proxy, method, args, this.sqlSession);
} catch (Throwable var5) {
throw ExceptionUtil.unwrapThrowable(var5);
}
}
这里判断了,调用的方法是否为 Object 类中的方法(比如: toString() 等等),如果成立,则直接执行方法,不做增强,如果不成立,就执行 this.cachedInvoker(method).invoke(proxy, method, args, this.sqlSession);
。
接下来就是对方法进行一个缓存(加快多次操作的速度),并且生成一个 PlainMethodInvoker
和 MybatisMapperMethod
实例,进行真正的执行。
最后调用实例的 invoke
方法,接下来调用 MybatisMapperMethod
的 execute 方法。
最终使用 sqlSession 进行插入数据,这个 sqlSession 是 sqlSessionTemplate,这个可以在上图中看出。
然后进入 SqlSessionInterceptor
内部类,对 DefaultSqlSession 进行了一个增强
创建了一个 SqlSession 后,传入 DefaultSqlSession 的 insert 操作,在执行 update 操作。
最终调用 Mybatis 执行器进行执行 SQL ,这里击中的 Mybatis 的缓存,故是 CachingExecutor 进行执行最终 SQL。
总结
以上只是 Mybatis Plus 执行 insert 操作的一部分流程,肯定有很多遗漏的地方。时间有限,能力有限,如有错误地方,欢迎指正,谢谢!