通过上面的代码,可以想象到mybaties plus初始化过程中肯定会调用到Insert的injectMappedStatement方法,把它对应的MapperStatement注入到mybaties容器中,然后后续通过动态代理调用BaseMapper相关方法的时候就可以根据MapperStatement对应的信息去执行对应的sql了 。
现在分析下injectMappedStatement方法是怎么被调用到的?
调用时序图如下:

文章插图
这里关注下Insert的injectMappedStatement调用流程 。
这里再重点分析MybatisMapperRegistry的addMapper代码,因为它的信息量比较大 。如下:
MybatisMapperRegistry
public <T> void addMapper(Class<T> type) {if (type.isInterface()) {if (hasMapper(type)) {// TODO 如果之前注入 直接返回return;// TODO 这里就不抛异常了//throw new BindingException("Type " + type + " is already known to the MapperRegistry.");}boolean loadCompleted = false;try {// 这里也换成 MybatisMapperProxyFactory 而不是 MapperProxyFactory// 对于mybaties plus用的MybatisMapperProxyFactory,mybaties用MapperProxyFactory// 这句代码很重要,把动态代理工厂加入到了knownMappers中,这里的type是你定义的Mapper类 。// 下面的getMapper会通过MybatisMapperProxyFactory生成对应mapper的动态代理,进而执行mapper// 的各个方法 。knownMappers.put(type, new MybatisMapperProxyFactory<>(type));// It's important that the type is added before the parser is run// otherwise the binding may automatically be attempted by the// mapper parser. If the type is already known, it won't try.// TODO 这里也换成 MybatisMapperAnnotationBuilder 而不是 MapperAnnotationBuilder// 解析Mapper定义的方法中用注解方式定义的sql 。这里最终会在你定义的Mapper类中添加mybaties plus// 为你注入的Insert,Delete ,Update,Select等方法 。其实就是把对应的MapperStatement注入到了Mybaties中 。MybatisMapperAnnotationBuilder parser = new MybatisMapperAnnotationBuilder(config, type);parser.parse();loadCompleted = true;} finally {if (!loadCompleted) {knownMappers.remove(type);}}}}@Overridepublic <T> T getMapper(Class<T> type, SqlSession sqlSession) {// TODO 这里换成 MybatisMapperProxyFactory 而不是 MapperProxyFactory// fix https://github.com/baomidou/mybatis-plus/issues/4247MybatisMapperProxyFactory<T> mapperProxyFactory = (MybatisMapperProxyFactory<T>) knownMappers.get(type);if (mapperProxyFactory == null) {// 上面addMapper会在knownMappers添加对应的FactorymapperProxyFactory = (MybatisMapperProxyFactory<T>) knownMappers.entrySet().stream().filter(t -> t.getKey().getName().equals(type.getName())).findFirst().map(Map.Entry::getValue).orElseThrow(() -> new BindingException("Type " + type + " is not known to the MybatisPlusMapperRegistry."));}try {// 生成mapper对应的动态代理对象return mapperProxyFactory.newInstance(sqlSession);} catch (Exception e) {throw new BindingException("Error getting mapper instance. Cause: " + e, e);}}答疑时刻mybatis plus定义了增删改查对应的sql注入器,在解析注册mapper的时候,会把相应的方法作为MapperStatement注入到mybaties中 。看起来没有定义对应的xml文件,其实是mybaties plus用sql注入器的方式,在代码中默认都提供了对应的sql了 。
后面当你调用Mapper对应方法的时候,会通过对应mapper的动态代理获取到方法对应的MapperStatement,进而再通过执行器进行一系列的处理,最终执行该方法对应的sql 。
推荐阅读
- 李小璐|离婚后彻底放飞自我,璐的审美,真是多年如一日的稳定!
- 秦海璐|秦海璐彻底告别大妈形象,蓝色紧身牛仔裤搭白色卫衣,女人味十足!
- 什么原因无法彻底治理沙尘暴
- 黄晓明|离婚早有征兆,杨颖想复合却被拒绝,黄晓明表示想彻底放下
- 湿疹怎么才能根除(怎么做才能彻底治愈湿疹)
- 张翰|他的口碑彻底崩了?
- 徐娇|星女郎徐娇彻底转型:开公司学设计,还连续8年推广汉服
- 张庭|张庭夫妇彻底凉了,前妻儿子发文说“开心”
- 赵丽颖|穿汉服最好看的几位明星:刘诗诗白鹿气质佳,看到赵丽颖彻底惊艳
- 章子怡|张艺谋40岁长女彻底翻身!穿红裙走红毯独当一面,红唇卷发撞脸章子怡
