spring-mybatis与原生mybatis使用对比分析
原生mybatis使用方法:
Stringresource="mybatis-config.xml"; InputStreaminputStream=Resources.getResourceAsStream(resource); SqlSessionFactorysqlSessionFactory=newSqlSessionFactoryBuilder().build(inputStream); SqlSessionsession=sqlSessionFactory.openSession(); try{ Employeeemployee=newEmployee(null,"doubi","1","ddd@sys.com"); EmployeeMappermapper=session.getMapper(EmployeeMapper.class); mapper.addEmp(employee); session.commit(); }finally{ session.close(); }
spring使用方法,直接注入即可
@Autowired EmployeeMapperemployeeMapper
那么spring为我们做了什么?下面研究一下mybatis-spring.jar这个jar包
首先来看一下如何使用spring整合mybatis,下面是使用spring-mybatis的四种方法:
方法一:(使用MapperFactoryBean)
这样做的缺点是每一个mapper接口都要在xml里配置一下
方法二:采用接口org.apache.ibatis.session.SqlSession的实现类org.mybatis.spring.SqlSessionTemplate
mybatis中,sessionFactory可由SqlSessionFactoryBuilder.来创建。MyBatis-Spring中,使用了SqlSessionFactoryBean来替代。SqlSessionFactoryBean有一个必须属性dataSource,另外其还有一个通用属性configLocation(用来指定mybatis的xml配置文件路径)。
SqlSessionFactoryBean即相当于原生mybatis中的SqlSessionFactoryBuilder
//使用方法: @RepositorypublicclassUserDao{@ResourceprivateSqlSessionTemplatesqlSessionTemplate;publicUsergetUser(intid){returnsqlSessionTemplate.selectOne(this.getClass().getName()+".getUser",1);}}
为什么可以这样写,来看一下SqlSessionTemplate
publicclassSqlSessionTemplateimplementsSqlSession{privatefinalSqlSessionFactorysqlSessionFactory;privatefinalExecutorTypeexecutorType;privatefinalSqlSessionsqlSessionProxy;privatefinalPersistenceExceptionTranslatorexceptionTranslator;/***ConstructsaSpringmanagedSqlSessionwiththe{@codeSqlSessionFactory}*providedasanargument.**@paramsqlSessionFactory*/publicSqlSessionTemplate(SqlSessionFactorysqlSessionFactory){this(sqlSessionFactory,sqlSessionFactory.getConfiguration().getDefaultExecutorType());} ........省略...... publicSqlSessionTemplate(SqlSessionFactorysqlSessionFactory,ExecutorTypeexecutorType,PersistenceExceptionTranslatorexceptionTranslator){notNull(sqlSessionFactory,"Property'sqlSessionFactory'isrequired");notNull(executorType,"Property'executorType'isrequired");this.sqlSessionFactory=sqlSessionFactory;this.executorType=executorType;this.exceptionTranslator=exceptionTranslator;this.sqlSessionProxy=(SqlSession)newProxyInstance(SqlSessionFactory.class.getClassLoader(),newClass[]{SqlSession.class},newSqlSessionInterceptor());} }
如上面代码所示,SqlSessionTemplate类实现了原生Mybatis中的SqlSession接口,实际上它就是原生mybatis中的SqlSession
方法三:采用抽象类org.mybatis.spring.support.SqlSessionDaoSupport提供SqlSession
publicclassBaseDaoextendsSqlSessionDaoSupport{//使用sqlSessionFactory@AutowiredprivateSqlSessionFactorysqlSessionFactory; @AutowiredpublicvoidsetSqlSessionFactory(SqlSessionFactorysqlSessionFactory) { super.setSqlSessionFactory(sqlSessionFactory); }/***执行insert操作*@paramstatement*@return*/publicintinsert(Stringstatement){ returngetSqlSession().insert(statement);}/***执行insert操作*@paramstatement*@paramparameter*@return*/publicintinsert(Stringstatement,Objectparameter){ returngetSqlSession().insert(statement,parameter);} publicintupdate(Stringstatement) {returngetSqlSession().update(statement); } publicintupdate(Stringstatement,Objectparameter){returngetSqlSession().update(statement,parameter);} publicintdelete(Stringstatement) { returngetSqlSession().delete(statement); } publicintdelete(Stringstatement,Objectparameter){ returngetSqlSession().delete(statement,parameter);}/***获取一个list集合*@paramstatement*@return*/publicList>selectList(Stringstatement){returngetSqlSession().selectList(statement);}/***根据参数获取一个list集合*@paramstatement*@paramparameter*@return*/publicList>selectList(Stringstatement,Objectparameter){returngetSqlSession().selectList(statement,parameter);}publicMap,?>selectMap(Stringstatement,StringmapKey){returngetSqlSession().selectMap(statement,mapKey);}publicMap,?>selectMap(Stringstatement,Objectparameter,StringmapKey){returngetSqlSession().selectMap(statement,parameter,mapKey);}/***获取Object对象*@paramstatement*@return*/publicObjectselectOne(Stringstatement){returngetSqlSession().selectOne(statement);}/***获取connection,以便执行较为复杂的用法*@return*/publicConnectiongetConnection(){returngetSqlSession().getConnection();}}
如上代码,一个Dao类继承了SqlSessionDaoSupport类后,就可以在类中注入SessionFact
ory,进而通过getSqlSession()获取当前SqlSession
下面是SqlSessionDaoSupport的源码,它是一个抽象类,并拥有sqlSession属性,在setSqlSessionFactory方法中实例化了该sqlSession:
publicabstractclassSqlSessionDaoSupportextendsDaoSupport { privateSqlSessionsqlSession;privatebooleanexternalSqlSession; publicvoidsetSqlSessionFactory(SqlSessionFactorysqlSessionFactory) { if(!this.externalSqlSession){ this.sqlSession=newSqlSessionTemplate(sqlSessionFactory); } } publicvoidsetSqlSessionTemplate(SqlSessionTemplatesqlSessionTemplate) { this.sqlSession=sqlSessionTemplate;this.externalSqlSession=true; } publicSqlSessiongetSqlSession() { returnthis.sqlSession; } protectedvoidcheckDaoConfig() { notNull(this.sqlSession,"Property'sqlSessionFactory'or'sqlSessionTemplate'arerequired");}}
方法四:(也是最常见的使用方法,使用MapperScannerConfigurer,它将会查找类路径下的映射器并自动将它们创建成MapperFactoryBean)
由于直接使用MapperFactoryBean会在配置文件中配置大量mapper,因此这里使用包扫描的方式通过注解获取该bean
//使用如下代码,即可完成注入 @Resource privateUserDaouserDao;
下面看一下MapperScannerConfigurer这个类:
publicclassMapperScannerConfigurerimplementsBeanDefinitionRegistryPostProcessor,InitializingBean,ApplicationContextAware,BeanNameAware{privateStringbasePackage;privatebooleanaddToConfig=true;privateSqlSessionFactorysqlSessionFactory;privateSqlSessionTemplatesqlSessionTemplate;privateStringsqlSessionFactoryBeanName;privateStringsqlSessionTemplateBeanName;privateClassannotationClass;privateClass>markerInterface;privateApplicationContextapplicationContext;privateStringbeanName;privatebooleanprocessPropertyPlaceHolders;privateBeanNameGeneratornameGenerator; publicvoidpostProcessBeanDefinitionRegistry(BeanDefinitionRegistryregistry)throwsBeansException{if(this.processPropertyPlaceHolders){processPropertyPlaceHolders();}ClassPathMapperScannerscanner=newClassPathMapperScanner(registry);scanner.setAddToConfig(this.addToConfig);scanner.setAnnotationClass(this.annotationClass);scanner.setMarkerInterface(this.markerInterface);scanner.setSqlSessionFactory(this.sqlSessionFactory);scanner.setSqlSessionTemplate(this.sqlSessionTemplate);scanner.setSqlSessionFactoryBeanName(this.sqlSessionFactoryBeanName);scanner.setSqlSessionTemplateBeanName(this.sqlSessionTemplateBeanName);scanner.setResourceLoader(this.applicationContext);scanner.setBeanNameGenerator(this.nameGenerator);scanner.registerFilters();scanner.scan(StringUtils.tokenizeToStringArray(this.basePackage,ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS));} ClassPathMapperScanner: publicSetdoScan(String...basePackages){Set beanDefinitions=super.doScan(basePackages);if(beanDefinitions.isEmpty()){logger.warn("NoMyBatismapperwasfoundin'"+Arrays.toString(basePackages)+"'package.Pleasecheckyourconfiguration.");}else{for(BeanDefinitionHolderholder:beanDefinitions){GenericBeanDefinitiondefinition=(GenericBeanDefinition)holder.getBeanDefinition();if(logger.isDebugEnabled()){logger.debug("CreatingMapperFactoryBeanwithname'"+holder.getBeanName()+"'and'"+definition.getBeanClassName()+"'mapperInterface");}//themapperinterfaceistheoriginalclassofthebean//but,theactualclassofthebeanisMapperFactoryBeandefinition.getPropertyValues().add("mapperInterface",definition.getBeanClassName());definition.setBeanClass(MapperFactoryBean.class);definition.getPropertyValues().add("addToConfig",this.addToConfig);booleanexplicitFactoryUsed=false;if(StringUtils.hasText(this.sqlSessionFactoryBeanName)){definition.getPropertyValues().add("sqlSessionFactory",newRuntimeBeanReference(this.sqlSessionFactoryBeanName));explicitFactoryUsed=true;}elseif(this.sqlSessionFactory!=null){definition.getPropertyValues().add("sqlSessionFactory",this.sqlSessionFactory);explicitFactoryUsed=true;}if(StringUtils.hasText(this.sqlSessionTemplateBeanName)){if(explicitFactoryUsed){logger.warn("Cannotuseboth:sqlSessionTemplateandsqlSessionFactorytogether.sqlSessionFactoryisignored.");}definition.getPropertyValues().add("sqlSessionTemplate",newRuntimeBeanReference(this.sqlSessionTemplateBeanName));explicitFactoryUsed=true;}elseif(this.sqlSessionTemplate!=null){if(explicitFactoryUsed){logger.warn("Cannotuseboth:sqlSessionTemplateandsqlSessionFactorytogether.sqlSessionFactoryisignored.");}definition.getPropertyValues().add("sqlSessionTemplate",this.sqlSessionTemplate);explicitFactoryUsed=true;}if(!explicitFactoryUsed){if(logger.isDebugEnabled()){logger.debug("EnablingautowirebytypeforMapperFactoryBeanwithname'"+holder.getBeanName()+"'.");}definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);}}}returnbeanDefinitions;}
总结:spring-mybatis与原生Mybatis相比,如下概念:
1)SqlSessionFactory类在两者中都存在
2)前者用SqlSessionFactoryBean生成SqlSessionFactory,后者则使用SqlSessionFactoryBuilder;
3)前者使用SqlSessionTemplate,后者使用SqlSession,实际上前者实现了后者
4)MapperFactoryBean中实现了原生mybatis中下面的步骤,因此通过该类可以直接获取到一个mapper接口的实现对象
EmployeeMappermapper=session.getMapper(EmployeeMapper.class);
总结
以上所述是小编给大家介绍的spring-mybatis与原生mybatis使用对比分析,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!