일반적으로 프레임 워크의 소스 코드를 수정하는 것은 매우 위험하며 절대적으로 필요하지 않으면 수정하지 마십시오. 그러나 오늘 나는 Spring과 통합 된 Mybatis가 공식적으로 제공 한 sqlsessionfactorybean 클래스를 신중하게 재구성했습니다. 첫째, 시행 착오 정신이 있으며, 둘째는 현실적인 요구가 있습니다.
먼저 두 가지 요점을 설명하겠습니다.
일반적으로 리팩토링은 기능을 변경하지 않고 코드를 최적화하는 것을 말하지만이 기사에서 언급 한 리팩토링에는 기능 추가도 포함됩니다.
이 기사에 사용 된 주요 항아리 패키지 (버전) : Spring-*-4.3.3. Release.jar, Mybatis-3.4.1.jar, Mybatis-Spring-1.3.0.jar
Mybatis와 Spring의 통합부터 시작하겠습니다.
1. Mybatis와 Spring을 통합합니다
<bean id = "sqlsessionfactory"p : dataSource-Ref = "dataSource"p : configlocation = "classPath : myBatis/myBatis/myBatis-config.xml"> <property name = "mapperLocations"> <athray> <atual> classPath*: **/*. sqlmapper.xml </value> </value> </value> </value>
핵심 통합 클래스는 org.mybatis.spring.sqlsessionfactorybean입니다. 이는 mybatis Global Session Factory SqlsessionFactory (즉, 세션 공장을 생성하는 공장 Bean)를 생성하는 데 사용되는 공장 Bean입니다. SQLSESSionACTORY는 세션 SQLSESSION (SQLSESSIONET IS SQLSSESSION IS SQLSOUTORE, SQLSESSIONT)를 생성하는 데 사용됩니다. 연결에).
여기서 속성 (P 네임 스페이스 또는 속성 자식 요소를 사용하여 구성) :
DataSource는 DBCP, C3P0, DRUID, JNDI-Lookup 및 기타 방법을 사용하여 구성 할 수있는 데이터 소스입니다.
configlocation은 mybatis의 동작을 수정하는 데 사용되는 Mybatis 엔진의 글로벌 구성입니다.
mapperlocations는 mybatis가로드 해야하는 sqlmapper 스크립트 구성 파일 (모드)입니다.
물론 다른 많은 속성이 있으므로 여기서 예를 들어 보이지 않을 것입니다.
2. 왜 재구성 되는가
1. 소스 코드 최적화
sqlsessionFactoryBean의 기능은 sqlsessionFactory를 생성하는 것입니다. 이 메소드를 살펴 보겠습니다 (sqlsessionfactorybean.java line 384-538) : /*** {@code sqlsessionfactory} instance를 빌드하십시오. ** 기본 구현은 표준 myBatis {@code xmlconfigBuilder} api를 사용하여* {@code sqlsactortory}를 구축하기 위해* {@code sqlseassionfactory}를 기반으로합니다. 구성 파일없이 직접 {@link configuration} 인스턴스를 직접 지정해야합니다. (this.configuration! = null) {configuration = this.configuration; if (configuration.getVariables () == null) {configuration.setVariables (this.configurationProperties); if (this.configlocation! = null) {xmlConfigBuilder = new XmlConfigBuilder (this.configlocation.getInputStream (), null, this.configurationProperties); configuration = xmlConfigBuilder.getConfiguration (} else); {logger.debug ( "속성`configuration '또는'configlocation '); 기본 myBatis configuration을 사용하여 지정되지 않음");} configuration = new configuration (); configuration.setVariables (this.configurationProperties);} if (this.objectory! = null); (this.ObjectWrapperFactory! = null) {configuration.setObjectWrapperFactory (this.ObjectWrapperFactory);} if (this.vfs! = null) {configuration.setvfsimpl (this.vfs);} if (haslength (this.typealiasespackage)) {string [] taperealspackagagagagagagagagagaGray =. TokenizetoStringArray (this.typealiasespackage, configurableApplicationcontext.config_location_delimiters); for (string packagetoscan : inftealiaspackagearray) {configuration.getTypealiasRegistry (). RegisterAliases (packagetoscan, intaveAsessuperType == null? object.class : inveliasessuperType); if (logger.isdebugenabled ()) { " + packaget." aliases ");}}} if (! isempty (isempty (this.typealiases))) {for (class <?> this.typealiases) {configuration.gettypealiasregistry (). Registalias (infealias); if (logger.isdebugenabled ()) {logger.debug (등록자 regalias : ' + typealias :' + typealias : " '");}}} if (! isempty (isempty (this.plugins))) {for (interceptor plugin : this.plugins) {configuration.addinterceptor (플러그인); if (logger.isdebugenabled ()) {logger.debug ( "등록 된 플러그인 :'" + plugin + " '; (haslength (this.typehandlerspackage)) {string [] typehandlerspackagearray = tokenizetoStringArray (this.typehandlerspackage, configurableApplicationcontext.config_location_delimiters); for (string packagetoscan : typehandlerspackagearray) {configuration.getTypeHandlerRegistry (). register (packagetoscan); if (logger.isdebugenabled ()) { "scend Package : ' + packagetoscan +"' '}}}}}}}}}} (! isempty (this.typehandlers)) {for (typehandler <?> typehandler : this.typehandlers) {configuration.getTypeHandlerRegistry (). register (typeHandler); if (logger.isdebugenabled ()) {logger.debug ( "Registered Type Hrandler : ' + typehandler +"'); (this.databaseIdProvider! = null) {// fix #64 구문 분석 xmlstry {configuration.setdatabaseid (this.databaseidprovider.getDatabaseid (this.datasource)); (this.cache! = null) {configuration.addcache (this.cache);} if (xmlconfigBuilder! = null) {try {xmlconfigBuilder.parse (); if (logger.isdebugenabled ()) {logger.debug ( "parsed configuration + this. ' + this. " '");}} catch (예외) {Throw New NestEdioException ( "구성 리소스를 구문 분석하지 못했습니다 :" + this.configlocation, ex);} 마침내 {errorcontext.instance (). reset ();}}} if (this.transaction mactory == null) {this.transactionActory = new SpringManagedTransactionCactory ();} configuration.setenvironment (새로운 환경 (this.environment, this.transactionfactory, this.datasource)); if (! isempty (isempty (isempty (isempty) XMLMAPPERBUILDER = new XMLMAPPERBUILDER (mapperLocation.getInputStream (), configuration, mapperLocation.toString (), configuration.getSqlfragments ()); xmlMapperBuilder.parse ();} catch () {새로운 NestEdioException ( " + Mapperce에 실패했습니다. " '", e);} 마침내 {errorContext.instance (). reset ();} if (logger.isdebugenabled ()) {logger.debug ( "Parsed Mapper 파일 :'" + mapperlocation + " '");}} else {if (logger.isdebugenabled ())) {gug.debug.der.debug.1). 'MapperLocations'는 지정되지 않았거나 일치하는 리소스가 발견되지 않았거나 찾을 수 없습니다.}} reture this.sqlsessionFactoryBuilder.build (configuration);}Mybatis는 우수한 지속성 계층 프레임 워크이지만 솔직히 말하지만,이 코드는 실제로 좋지 않으며 재구성 및 최적화의 여지가 많습니다.
2. 기능적 확장
(1) 스키마를 사용하여 sqlmapper를 확인하십시오
<!-dtd 모드-> <? xml 버전 = "1.0"encoding = "utf-8"?> <! doctype mapper public "-// mybatis.org//dtd Mapper 3.0 // en" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <httd"> Mapper namespace = "org.dysd.dao.mybatis.config.iexampledao"> </mapper> <!-스키마 모드-> <? xml version = "1.0"alcoding = "utf-8"?> <mapper xsi = xsi = "http://www.w3.org/2001/xmschema-instance. xmlns = "http://dysd.org/schema/sqlmapper"xsi : schemalocation = "http://dysd.org/schema/sqlmapper http://dysd.org/schema/sqlmapper.xsd "namespace ="org.dysd.dao.mybatis.config.iexampledao "> </mapper>
언뜻보기에는 스키마 사용이 더 복잡하지만 IDE와 결합하면 스키마 사용의 자동 프롬프트가 더 친숙하고 검증 정보가 더 명확합니다. 동시에 다른 개발자가 다른 개발자가 OGNL 표현식을 사용하여 SQL 문을 구성하여 SQL 문을 구성하는 등 기존 네임 스페이스를 기반으로 네임 스페이스를 사용자 정의 할 수 있도록 창을 엽니 다.
(2) 구성을 사용자 정의합니다. SQLSESSIONFACTORYBEAN은 사용자 정의 구성을위한 더 많은 매개 변수를 제공했지만 다음과 같은보다 개인화 된 설정이 필요할 수 있습니다.
A. 기본 결과 유형을 설정합니다. resulttype 및 resultmap을 설정하지 않는 <select> 요소의 경우, 구문 분석 후 기본 리턴 유형을 매핑으로 설정하여 SQLMPAPPER의 구성을 단순화 할 수 있습니다.
<!-> <select id = "select"select "select"select "select"select "resulttype ="map "> select * from table_name where where field1 = #{field1, jdbctype = varchar} </select> <!-단순화 후-> <select *에서 table_name에서 select"where1 = {field1, jdbctype = </select} </select}.B. Mybatis의 원래 매개 변수 분석을 확장합니다. 기본 구문 분석 구현은 DefaultParameterAndler입니다. 이 구현은 상속 및 확장 될 수 있습니다. 예를 들어, Spel : Spel을 사용하여 값을 평가하는 속성 표현식의 경우 값을 평가하십시오.
(3) 기타 확장에 대해서는 Mybatis Extension에 대한 저자의 이전 블로그를 참조하십시오.
3. 재건의 타당성
(1) 코드 영향의 범위 측면에서
아래는 sqlsessionfactorybean의 상속 구조입니다
이것으로부터 우리는 sqlsessionfactorybean 상속 시스템이 복잡하지 않으며 다른 상위 클래스를 상속하지 않는다는 것을 알 수 있습니다. 봄에는 3 개의 인터페이스 만 구현합니다 (JDK의 이벤트 리스트너는 로고 일뿐입니다). 또한 SqlSessionFactoryBean은 최종 개발 사용자를 대상으로하며 서브 클래스가없고 다른 클래스를 호출하지 않으므로 코드 영향의 범위 측면에서 매우 작습니다.
(2) 재구성 구현에서 새로운 SchemasqlSessionFactoryBean을 생성 한 다음 코드는 처음에 SQLSESSIONFACTORYBEAN을 완전히 복사 한 다음 패키지 이름 및 클래스 이름을 수정 한 다음이를 재구성의 기초로 사용합니다. 이것은 비교적 간단합니다.
(3) 통합 애플리케이션에서는 통합 구성 및 스프링에서 클래스 속성 만 수정하면됩니다.
위의 것은 mybatis와 통합 된 sqlsessionfactorybean의 리팩토링 및 당신에게 소개 된 Spring입니다. 나는 그것이 당신에게 도움이되기를 바랍니다. 궁금한 점이 있으면 메시지를 남겨 주시면 편집자가 제 시간에 답장을 드리겠습니다. Wulin.com 웹 사이트를 지원해 주셔서 대단히 감사합니다!