1.mybatis 码下springä»ç»ã使ç¨ãå®ç°åç
2.小白福音,Mybatis整合spring教程分享
3.关于springmvc+mybits搭建项目启动时找不到sqlsessionfactory的码下疑问。
4.MyBatis(十一):MyBatis整合Spring
mybatis 码下springä»ç»ã使ç¨ãå®ç°åç
mavenä¾èµ<dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>2.0.6</version></dependency>使ç¨
SqlSessionFactoryBean å¯ä»¥å建sqlSessionFactoryï¼dataSourceæ¯èªå·±çæ°æ®æºçbean @MapperScan注解å¯ä»¥å¸®å©æ们æMyBatisçMapper类注å为beanï¼è¿æ ·æ们就å¯ä»¥å¨ä½¿ç¨çå°æ¹éè¿@Autowired/@Resourceå¼ç¨æ¥ä½¿ç¨ã
@MapperScan("com.github.liuzhengyang")@ConfigurationpublicclassMyBatisConfig{ @Autowired@BeanpublicSqlSessionFactoryBeansqlSessionFactoryBean(DataSourcedataSource){ SqlSessionFactoryBeansqlSessionFactoryBean=newSqlSessionFactoryBean();sqlSessionFactoryBean.setDataSource(dataSource);returnsqlSessionFactoryBean;}}å®ç°åçmybatis-spring帮å©æ们ç®åçå·¥ä½ã带æ¥çä»·å¼æ¯
SqlSessionFactoryå建çå·¥ä½ï¼ä½¿ç¨åççmybatiséè¦ç¨é ç½®æ件é ç½®mybatisï¼mybais-springå¯ä»¥ç¨@Bean代ç å建ã(è½ç¶mybatisä¹è½ç¨ä»£ç æ建ï¼ä¸è¿SqlSessionFactory被spring管çäºï¼å¨ä½¿ç¨çæ¶ååªéè¦@Autowireä¼æ´æ¹ä¾¿)
ä¸åéè¦æ¯æ¬¡openSessionãcloseï¼è¿äºå·¥ä½å¨mybatis-springå é¨å®ç°äºï¼mybatis-spring帮å©æ们å¤ææ¯å¦è¦openSession
Mapperç±»åæäºbeanï¼éè¦ä½¿ç¨çæ¶åç´æ¥@Autowiredå°±å¯ä»¥
æä¾çº¿ç¨å®å ¨çSqlSessionTemplate
SqlSessionFactoryå¦ä½å建SqlSessionFactoryéè¿SqlSessionFactoryBean#buildSqlSessionFactoryæ建ï¼è°ç¨æ¶æºæ¯SqlSessionFactoryBean.afterPropertiesSetã SqlSessionFactoryæ大éå¯é 置项ï¼è¿äºé 置项æç»è½¬å为SqlSessionFactoryçæ建åæ°(Configuration)
@OverridepublicvoidafterPropertiesSet()throwsException{ notNull(dataSource,"Property'dataSource'isrequired");notNull(sqlSessionFactoryBuilder,"Property'sqlSessionFactoryBuilder'isrequired");state((configuration==null&&configLocation==null)||!(configuration!=null&&configLocation!=null),"Property'configuration'and'configLocation'cannotspecifiedwithtogether");this.sqlSessionFactory=buildSqlSessionFactory();}protectedSqlSessionFactorybuildSqlSessionFactory()throwsException{ finalConfigurationtargetConfiguration;...XMLConfigBuilderxmlConfigBuilder=null;if(this.configuration!=null){ targetConfiguration=this.configuration;if(targetConfiguration.getVariables()==null){ targetConfiguration.setVariables(this.configurationProperties);}elseif(this.configurationProperties!=null){ targetConfiguration.getVariables().putAll(this.configurationProperties);}}elseif(this.configLocation!=null){ xmlConfigBuilder=newXMLConfigBuilder(this.configLocation.getInputStream(),null,this.configurationProperties);targetConfiguration=xmlConfigBuilder.getConfiguration();}else{ LOGGER.debug(()->"Property'configuration'or'configLocation'notspecified,usingdefaultMyBatisConfiguration");targetConfiguration=newConfiguration();Optional.ofNullable(this.configurationProperties).ifPresent(targetConfiguration::setVariables);}...returnthis.sqlSessionFactoryBuilder.build(targetConfiguration);}Mapperç±»å¦ä½æ³¨åæbeanå°BeanFactoryä¸ç使ç¨äºmybatis-springï¼ä¼æ«æç¹å®çMapperç±»ï¼@MapperScan注解æ§å¶ï¼æ§å¶æ 注äºä»»æ注解çæ¥å£å¯ä»¥è¢«æ³¨åä¸ï¼è¿å¯ä»¥é ç½®æ¥å£çparentå¤æï¼ï¼ç¶åä½ä¸ºBean注åå°beanFactoryä¸ï¼ä»èè½è¢«å ¶ä»çbeanä¾èµä½¿ç¨ã
@MapperpublicinterfaceUserMapper{ UsergetUserById(longid);}è¦å®ç°è¿æ ·çscanæºå¶ï¼å°±éè¦ä¸ä¸ªscan mapperçBeanPostProcessorï¼è¿ä¸ªprocessorä¸ï¼scanå½åclasspathä¸æ»¡è¶³MapperScané ç½®çpackageè¦æ±çç±»ï¼æ¥å£ï¼ï¼å¹¶ä¸å¤ææ¯å¦æ@Mapper注解ï¼å¦æ符åï¼å建BeanDefinition注åå°BeanFactoryä¸ãå¨getBeançæ¶åï¼è°ç¨MapperFactoryBean.getObjectæ¿å°çMapper代çï¼å®ç°æ¯Configuration.getMapper(Class type, SqlSession sqlSession), SqlSessionæ¯SqlSessionTemplateèªèº«ãæåå¨afterPropertiesSetï¼ä¼æ¿å°SqlSessionFactory.getConfiguration()ï¼è°ç¨addMapper(Class type)æ·»å å°mybatisä¸
为ä»ä¹å¢å äº@MapperScan注解ï¼å°±è½æ«æ注åMapperäºå¢ãä»MapperScanç±»å¯ä»¥çå°ï¼ä¸é¢æä¸ä¸ª@Import注解ï¼importäºMapperScannerRegistrar
@Import(MapperScannerRegistrar.class)@Repeatable(MapperScans.class)public@interfaceMapperScan{ ...}springç@Import注解ä¸è¬ç¨æ¥å¼ç¨å ¶ä»çConfigurationï¼è¿å¯ä»¥å¼ç¨ ImportSelectoråImportBeanDefinitionRegistrar å®ç°æå ¶ä»çComponentç±»ã
Provides functionality equivalent to the element in Spring XML. Allows for importing @Configuration classes, ImportSelector and ImportBeanDefinitionRegistrar implementations, as well as regular component classes (as of 4.2; analogous to AnnotationConfigApplicationContext.register).
æ»ä¹ï¼çä»·äºå£°æäºä¸ä¸ªMapperScannerRegistrar Beanãæ们çä¸ä¸MapperScannerRegistrarçå®ç°ï¼MapperScannerRegistratå®ç°äºImportBeanDefinitionRegistraråResourceLoaderAwareæ¥å£ã
ImportBeanDefinitionRegistraræ¥å£ï¼ç¨æ¥å¨å¤ç@Configurationç±»çæ¶åï¼å建bean definition级å«çbeanã
Interface to be implemented by types that register additional bean definitions when processing @Configuration classes. Useful when operating at the bean definition level (as opposed to @Bean method/instance level) is desired or necessary.
å¨springçrefreshé¶æ®µï¼æä¸æ¥æ¯invokeBeanFactoryPostProcessorsï¼ä¼è°ç¨å°ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistryï¼æç»ä¼è°ç¨å°loadBeanDefinitionsFromRegistrarsï¼è°ç¨å°MapperScannerRegistrar.registerBeanDefinitions
@OverridepublicvoidpostProcessBeanDefinitionRegistry(BeanDefinitionRegistryregistry){ intregistryId=System.identityHashCode(registry);if(this.registriesPostProcessed.contains(registryId)){ thrownewIllegalStateException("postProcessBeanDefinitionRegistryalreadycalledonthispost-processoragainst"+registry);}if(this.factoriesPostProcessed.contains(registryId)){ thrownewIllegalStateException("postProcessBeanFactoryalreadycalledonthispost-processoragainst"+registry);}this.registriesPostProcessed.add(registryId);processConfigBeanDefinitions(registry);}privatevoidloadBeanDefinitionsForConfigurationClass(ConfigurationClassconfigClass,TrackedConditionEvaluatortrackedConditionEvaluator){ if(trackedConditionEvaluator.shouldSkip(configClass)){ StringbeanName=configClass.getBeanName();if(StringUtils.hasLength(beanName)&&this.registry.containsBeanDefinition(beanName)){ this.registry.removeBeanDefinition(beanName);}this.importRegistry.removeImportingClass(configClass.getMetadata().getClassName());return;}if(configClass.isImported()){ registerBeanDefinitionForImportedConfigurationClass(configClass);}for(BeanMethodbeanMethod:configClass.getBeanMethods()){ loadBeanDefinitionsForBeanMethod(beanMethod);}loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());}privatevoidloadBeanDefinitionsFromRegistrars(Map<ImportBeanDefinitionRegistrar,AnnotationMetadata>registrars){ registrars.forEach((registrar,metadata)->registrar.registerBeanDefinitions(metadata,this.registry));}åçä¸ä¸MapperScannerRegistrarçå®ç°ãregisterBeanDefinitionså建äºä¸ä¸ªBeanDefinitionï¼beanæ¯MapperScannerConfigurerï¼é ç½®äºMapperScannerConfigureréè¦çå±æ§é ç½®ï¼é ç½®æ¥æºäº@MapperScan注解)ï¼ä¾å¦annotationClass, factoryBeançã
publicclassMapperScannerRegistrarimplementsImportBeanDefinitionRegistrar,ResourceLoaderAware{ @OverridepublicvoidregisterBeanDefinitions(AnnotationMetadataimportingClassMetadata,BeanDefinitionRegistryregistry){ AnnotationAttributesmapperScanAttrs=AnnotationAttributes.fromMap(importingClassMetadata.getAnnotationAttributes(MapperScan.class.getName()));if(mapperScanAttrs!=null){ registerBeanDefinitions(importingClassMetadata,mapperScanAttrs,registry,generateBaseBeanName(importingClassMetadata,0));}}voidregisterBeanDefinitions(AnnotationMetadataannoMeta,AnnotationAttributesannoAttrs,BeanDefinitionRegistryregistry,StringbeanName){ BeanDefinitionBuilderbuilder=BeanDefinitionBuilder.genericBeanDefinition(MapperScannerConfigurer.class);builder.addPropertyValue("processPropertyPlaceHolders",true);Class<?extendsAnnotation>annotationClass=annoAttrs.getClass("annotationClass");if(!Annotation.class.equals(annotationClass)){ builder.addPropertyValue("annotationClass",annotationClass);}Class<?>markerInterface=annoAttrs.getClass("markerInterface");if(!Class.class.equals(markerInterface)){ builder.addPropertyValue("markerInterface",markerInterface);}Class<?extendsBeanNameGenerator>generatorClass=annoAttrs.getClass("nameGenerator");if(!BeanNameGenerator.class.equals(generatorClass)){ builder.addPropertyValue("nameGenerator",BeanUtils.instantiateClass(generatorClass));}Class<?extendsMapperFactoryBean>mapperFactoryBeanClass=annoAttrs.getClass("factoryBean");if(!MapperFactoryBean.class.equals(mapperFactoryBeanClass)){ builder.addPropertyValue("mapperFactoryBeanClass",mapperFactoryBeanClass);}StringsqlSessionTemplateRef=annoAttrs.getString("sqlSessionTemplateRef");if(StringUtils.hasText(sqlSessionTemplateRef)){ builder.addPropertyValue("sqlSessionTemplateBeanName",annoAttrs.getString("sqlSessionTemplateRef"));}StringsqlSessionFactoryRef=annoAttrs.getString("sqlSessionFactoryRef");if(StringUtils.hasText(sqlSessionFactoryRef)){ builder.addPropertyValue("sqlSessionFactoryBeanName",annoAttrs.getString("sqlSessionFactoryRef"));}List<String>basePackages=newArrayList<>();basePackages.addAll(Arrays.stream(annoAttrs.getStringArray("value")).filter(StringUtils::hasText).collect(Collectors.toList()));basePackages.addAll(Arrays.stream(annoAttrs.getStringArray("basePackages")).filter(StringUtils::hasText).collect(Collectors.toList()));basePackages.addAll(Arrays.stream(annoAttrs.getClassArray("basePackageClasses")).map(ClassUtils::getPackageName).collect(Collectors.toList()));if(basePackages.isEmpty()){ basePackages.add(getDefaultBasePackage(annoMeta));}StringlazyInitialization=annoAttrs.getString("lazyInitialization");if(StringUtils.hasText(lazyInitialization)){ builder.addPropertyValue("lazyInitialization",lazyInitialization);}StringdefaultScope=annoAttrs.getString("defaultScope");if(!AbstractBeanDefinition.SCOPE_DEFAULT.equals(defaultScope)){ builder.addPropertyValue("defaultScope",defaultScope);}builder.addPropertyValue("basePackage",StringUtils.collectionToCommaDelimitedString(basePackages));registry.registerBeanDefinition(beanName,builder.getBeanDefinition());}privatestaticStringgenerateBaseBeanName(AnnotationMetadataimportingClassMetadata,intindex){ returnimportingClassMetadata.getClassName()+"#"+MapperScannerRegistrar.class.g小白福音,Mybatis整合spring教程分享
Mybatis整合spring教程,码下实质上是码下SSM框架中Spring的集成。整合的码下通达sma指标源码核心在于将Mybatis的SqlSessionFactory对象以及Mapper代理对象整合到Spring的容器中,由Spring统一管理。码下具体步骤如下:首先,码下需要确保jar包的码下正确导入,包括Spring相关jar、码下Mybatis相关jar、码下Mysql驱动jar、码下数据库连接池jar等。码下在项目中加入mybatis-spring-1.2.2.jar源码,码下确保配置文件正确加载。码下
接下来,创建工程并导入jar包。在配置文件方面,分别需要mybatis的spring源码时序图配置文件SqlMapConfig.xml和Spring的配置文件applicationContext.xml。在SqlMapConfig.xml中配置数据库连接、事务管理、sqlsessionFactory对象以及mapper代理配置,将这些内容加入到applicationContext.xml中,实现与Spring的整合。
在Dao的开发中,可以采用两种方式:原始dao开发和Mapper代理形式。原始dao开发方式需要实现dao接口并继承SqlsessionDaoSupport类,创建Mapper.xml文件并配置,小账本PHP源码然后实现接口和dao实现类。Mapper代理形式则需要编写Mapper.xml文件并实现Mapper接口,使用MapperFactoryBean配置或者扫描包形式配置Mapper代理。
总体来说,Mybatis与Spring的整合需要按照以上步骤进行,确保配置文件正确无误,整合后的Dao开发可以采用原始dao开发或Mapper代理形式。通过整合,实现资源的访问域名安装源码统一管理,提高开发效率和代码维护性。
关于springmvc+mybits搭建项目启动时找不到sqlsessionfactory的疑问。
springmvc整合mybatis的时候不需要这样配置的,mybatis社区提供了一个插件用来整合spring的,里面就有factory的实现,而且mybatis的接口都是自动配置成spring的bean的。代码太多,不好打。你可以参考疯狂软件编著的hashmap底层源码分析《spring+mybatis企业应用实战》一书,里面有springmvc整合mybatis的例子,讲的很详细,并且有源代码。
MyBatis(十一):MyBatis整合Spring
为了实现MyBatis与Spring的整合,我们需要理解这两个框架的基本功能。MyBatis通过加载mybatis-configuration.xml文件生成SqlSessionFactory,进而产生sqlSession,最后通过sqlSession对数据库表映射的实体类执行增删改查操作。Spring则通过依赖注入和面向对象进行对象创建与管理,同时具备事务管理能力。整合的关键在于:
1. **配置SqlSessionFactory**:使用Spring管理单例的SqlSessionFactory,通过它创建sqlSession。
2. **管理Mapper**:将持久层的Mapper交由Spring管理。
### 创建mybatis-spring工程与导入所需jar包
- **导入依赖**:确保引入mybatis-spring、mybatis、以及相关数据库驱动jar包。
### 配置SqlSessionFactory与数据源
- **db.properties配置**:将数据库配置信息放置在classpath目录下的db.properties文件中。
- **mybatis全局配置**:在mybatis-configuration.xml文件中开启二级缓存并定义别名。
- **spring配置**:在applicationContext.xml中配置SqlSessionFactory与数据源。
### Mapper接口与开发配置
- **创建PO类**:在com.ys.po包下定义User类。
- **创建Mapper接口与xml文件**:创建UserMapper.java与UserMapper.xml,满足特定需求。
### 配置mapper
- **使用MapperFactoryBean**:配置MapperFactoryBean,指定Mapper接口全类名与SqlSessionFactory,生成代理对象。
### 测试整合
- **确认配置**:通过MapperFactoryBean产生mapper代理对象,配置mapperInterface与sqlSessionFactory。
### 高效配置多mapper
- **包扫描**:避免重复配置id属性,通过包扫描简化配置。
整合完成后,MyBatis与Spring的无缝对接实现了对象管理、事务处理与数据库操作的高效执行。通过上述步骤,我们不仅能够完成MyBatis与Spring的整合,还能构建出一个灵活、高效且易于维护的系统架构。