当前位置: 首页 > 科技观察

说说Mybatis系列之Mapper接口

时间:2023-03-23 01:30:13 科技观察

1。上期回顾首先,我们来回顾一下上期文档的内容。先看看这个测试类,大家是不是还有印象:);SqlSessionsession=sqlSessionFactory.openSession();try{FruitMappermapper=session.getMapper(FruitMapper.class);Fruitfruit=mapper.findById(1L);System.out.println(fruit);}最后{session.close();}}}上一篇源码分析讲了mybatis一级缓存的实现原理。这次我们就来了解下mybatis接口的创建。2、mapper接口的创建过程2.1SqlSession的getMapper()首先我们看一下FruitMappermapper=session.getMapper(FruitMapper.class);这个过程有点复杂,阿粉就带大家跟着源码走:先ctrl+左键点击getMapper方法,然后进入SqlSession的getMapper()方法。然后阿芬也带大家明白了SqlSession默认的实现类是DefaultSqlSession,那我们直接看DefaultSqlSession中getMapper()的实现:@OverridepublicTgetMapper(Classtype){returnconfiguration.getMapper(type,this);}2.2Configuration的getMapper()是从配置中获取的,是全局的配置对象,也就是上下文。参数this就是当前的SqlSession对象,继续跟进看:publicTgetMapper(Classtype,SqlSessionsqlSession){returnmapperRegistry.getMapper(type,sqlSession);}2.3getMapper()mapperRegistry对象有什么作用MapperRegistry做什么?什么?继续点进去:publicTgetMapper(Classtype,SqlSessionsqlSession){finalMapperProxyFactorymapperProxyFactory=(MapperProxyFactory)knownMappers.get(type);if(mapperProxyFactory==null){thrownewBindingException("Type"+type+"isnotknowntotheMapperRegistry.");}try{returnmapperProxyFactory.newInstance(sqlSession);}catch(Exceptione){thrownewBindingException("Errorgettingmapperinstance.Cause:"+e,e);}}这里很难理解,我们需要首先看一下MapperRegistry类。下面一步步来,按照阿粉的思路:publicclassMapperRegistry{privatefinalConfigurationconfig;privatefinalMap,MapperProxyFactory>knownMappers=newHashMap<>();publicMapperRegistry(Configurationconfig){this.config=config;}...}了解一个类,首先要看成员变量和构造方法。这里的config不用多说,主要就是成员变量knownMappers。这是一个map对象,但是这个map对象的值是一个对象,所以我们又要看MapperProxyFactory对象,点进去:publicclassMapperProxyFactory{privatefinalClassmapperInterface;privatefinalMapmethodCache=newConcurrentHashMap<>();publicMapperProxyFactory(ClassmapperInterface){this.mapperInterface=mapperInterface;}...}首先单独看类名MapperProxyFactory。它是做什么用的。所以大家一看到MapperProxyFactory,首先就会想到工厂模式。工厂模式有什么作用?创建对象,创建什么对象?创建MapperProxy对象。MapperProxy也很神秘。什么是代理?看到这里,一般采用代理模式来创建代理对象。所以很明显MapperProxyFactory类是一个为映射器创建代理对象的工厂。然后这个类存放了mapper的接口和接口中的方法。最后,我们回到MapperRegistry类中的getMapper()方法。现在是不是想清楚了,通过mapper接口获取map中的工厂类MapperProxyFactory,然后通过工厂类创建我们的mapper代理对象。再看getMapper()方法中的mapperProxyFactory.newInstance(sqlSession);这段代码,继续点进去:publicTnewInstance(SqlSessionsqlSession){finalMapperProxymapperProxy=newMapperProxy<>(sqlSession,mapperInterface,methodCache);returnnewInstance(mapperProxy);}你看,阿芬猜对了,是不是MapperProxy对象出来了?然后看newInstance()方法:protectedTnewInstance(MapperProxymapperProxy){return(T)Proxy.newProxyInstance(mapperInterface.getClassLoader(),newClass[]{mapperInterface},mapperProxy);}两个newInstance()方法都在在MapperProxyFactory类中,这里很明显。典型的JDK代理对象创建。好的,这里我们得到了我们的映射器对象。大家可以想一想,为什么获取一个mapper对象这么复杂呢?或者映射器对象的功能是什么?其实就是通过mapper接口的方法获取mapper.xml中的sql。如何获得,请允许阿粉出售只是一个问题,请听阿粉下一章分解。3.总结最后,阿粉用一张时序图来结束这篇文章。喜欢的话记得点个赞哦。好的~