En términos generales, modificar el código fuente del marco es extremadamente riesgoso y no lo modifica a menos que sea absolutamente necesario. Pero hoy reconstruí cuidadosamente la clase SQLSessionFactoryBean proporcionada oficialmente por MyBatis, que está integrada con la primavera. Primero, tiene una mentalidad de prueba y error, y segundo, tiene necesidades realistas.
Permítanme explicar dos puntos primero:
En términos generales, la refactorización se refiere a optimizar el código sin cambiar la función, pero la refactorización mencionada en este artículo también incluye agregar funciones.
Los principales paquetes de jar (versiones) utilizados en este artículo: Spring-*-4.3.3.release.jar, mybatis-3.4.1.jar, mybatis-spring-1.3.0.jar
Comencemos con la integración de MyBatis y Spring.
1. Integrar mybatis y primavera
<bean id = "sqlSessionFactory" p: dataSource-ref = "dataSource" p: configLocation = "classpath: myBatis/mybatis-config.xml"> <Property name = "mappLocations"> <RARAY> <VALE> ClassPath*: **/*. sqlmapper.xml </value> </arrebey </arrey
La clase clave de integración es org.mybatis.spring.sqlsessionFactoryBean, que es una franja de fábrica utilizada para generar mybatis global session fábrica sqlsessionFactory (es decir, el bean de fábrica que genera la fábrica de sesión), y sqlsession se usa para generar session sqlsession objects (sqlsession factyor equivalente a la conexión).
Donde las propiedades (configuradas usando el espacio de nombres P o el elemento infantil de la propiedad):
DataSource es una fuente de datos, que se puede configurar utilizando DBCP, C3P0, Druid, JNDI-Seokup y otros métodos.
configlocation es una configuración global del motor mybatis, utilizado para modificar el comportamiento de mybatis.
MapperLocations es el archivo de configuración de script sqlmapper (modo) que MyBatis necesita cargar.
Por supuesto, hay muchos otros atributos, por lo que no daré un ejemplo aquí.
2. Por qué reconstruir
1. Optimización del código fuente
La función de SQLSessionFactoryBean es generar SQLSessionFactory. Echemos un vistazo a este método (SQLSessionFactoryBean.Java Line 384-538): /*** Build a {@code sqlsessionFactory} instancia. ** La implementación predeterminada usa la instancia estándar myBatis {@code xmlconfigBuilder} API para construir una* {@@code sqlsession} basado en una lectura} basada en una lectura. especificada una instancia {@link Configuration} directamente (sin archivo de configuración). ** @return sqlsessionFactory* @throws ioexception Si cargando el archivo de configuración fallido*/protegido sqlsessionFactory builtsqlSessionFactory () lanza ioexception {configuración configuración; xmlconfigbuRIder xmlconfigbuilder {configuración = this.configuration; if (configuration.getVariables () == null) {configuration.setVariables (this.configurationProperties);} else if (this.ConfigurationProperties! = NULL) {configuración.getVariables (). {xmlconfigBuilder = new xmlConfigBuilder (this.configLocation.getInputStream (), null, this.ConfigurationProperties); configuración = xmlconfigBuBuilder.getConfiguration ();} else {if (logger.isDebugenabled ()) {logger.deBug ("" OtRenturation `` if (if (logger no especificado, utilizando la configuración predeterminada de MyBatis ");} configuration = new Configuration (); Configuration.SetVariables (this.ConfigurationProperties);} if (this.ObjectFactory! = NULL) {Configuration.SetObjectFactory (this.ObjectFactory);} if (this.ObjectWrapPerFactory! = NULL) {Configuration.SetObjectWrapperFactory (this.ObjectWrapperFactory);} if (this.vfs! = null) {configuration.setvfsImpl (this.vfs);} if (hasLength (this.typealiasespackage)) {string [] typealIspackagearRay = = Tokenizetostringarray (this.TypealIasSespackage, configuableApplicationContext.Config_Location_Delimiters); para (String PackageToScan: TypealiaSpackAGearray) {Configuration.GetTypealiasRegistry (). RegisterAliases (PackageToScan, typealiasessupertype == null? Object.class: typealessuperType); if (logger.isdebugenableBiled aliases ");}}} if (! IsEmpty (this.typealiases)) {for (class <?> typealias: this.typealiases) {configuration.gettypealiasregistry (). registertalias (typealias); if (logger.isdebugenable ()) {logger.debug (" Aliias registradas: '' '' " +" + "" + " +" " +" "" " "'");}}} if (! IsEmpty (this.plugins)) {for (Interceptor Plugin: this.plugins) {Configuration.addinterceptore (plugin); if (logger.isdebugenabled ()) {logger.debug ("plugin registrado:" + plugin + "");}}}}}} (HasLength (this.TypeEnHandLersPackage)) {String [] typeHandLersPackAGearray = tokenizeToStrinGarray (this.TypeHandLersPackage, configurureableApplicationContext.Config_Location_Delimiters); for (String PackageToScan: TypeHandlersPackAGearray) {Configuration.GetTypeHandlerRegistry (). Registro (PackageTosCan); if (logger.ISDEBUGEnabled ()) {logger.deBug ("paquete ranurado:" " + packageToscan +" para los manejadores de type ");}}}} if (((paquete scanned (" + packageScan + "para los manejadores de type");}}}} if ((("! IEMPEDLEMENTOS (TITHYLERS) {for (typeHandler <?> typeHandler: this.typeHandlers) {configuration.gettypeHandlerRegyry (). Registro (typeHandler); if (logger.isdeBugenable ()) {logger.debug ("controlador de tipo registrado: '" + typehler + "'" ");}} if (this.DatabaseIdPraveler #64 Establecer DatabaseId antes de Parse Mapper xmlstry {Configuration.SetDatabaseId (this.DatabaseIdProvider.getDatabaseId (this.DataSource));} Catch (Sqlexception e) {tire nuevo NestedioException ("falló en obtener una base de datos", e);}} if (this.cache! = Nulo) {configuration.addcache (this.cache);} if (xmlconfigBuilder! = null) {try {xmlconfigBuUder.parse (); if (logger.isdeBugenable ()) {logger.debug ("ACTIVO DE CONFIGURACIÓN: '" + this.configlation + ");}} Catch (excepción (excepción) NestedioException ("Falling to Hagne Config Resource:" + this.configlocation, ex);} finalmente {errorContext.Instance (). Reset ();}} if (this.transactionFactory == null) {this.transactionFactory = new SpringManEdgactory ();} Configuración.setenviron (new entorno (this. this.dataSource)); if (! isEmpty (this.mapperLocations)) {for (recurse mapperLocation: this.mapperlocations) {if (mapperLocation == null) {continúa;} try {xmlMapperBuilder xmlMapPerBuilder = new XmlMapPerBuilder (mapeador. mApperLocation.ToString (), configuration.getSqlFragments ()); xmlMapperBuilder.Parse ();} Catch (Exception e) {Throw NewDioException ("Falling to Parse de asignación de Parse: '" + mapperLocation + "", e);} finalmente {errorcontext.instance (). Reset ();};} (Logger.isdeBugeNabled ()) {logger.debug ("archivo mapper parsed: '" + mapperLocation + "'");}}} else {if (logger.isdebugenabled ()) {logger.debug ("propiedad 'mappLocations' no se especificó o no se encontró recursos de igualación");}}} this.sqlSessionFactoryBuilder.Build (Configuración);}Aunque MyBatis es un excelente marco de capa de persistencia, para ser honesto, este código no es muy bueno y tiene mucho espacio para la reconstrucción y la optimización.
2. Expansión funcional
(1) Use esquema para verificar SQLMapper
< namespace = "org.dysd.dao.mybatis.config.iexaMpledao"> </mapper> <!-Modo de esquema-> <? Xml versión = "1.0" encoding = "utf-8"?> <mapper xmlns: xsi = "http://www.w3.org/2001/xmlschema" 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>
A primera vista, el uso del esquema es más complicado, pero si se combina con el IDE, las indicaciones automáticas del uso del esquema son más amigables y la información de verificación es más clara. Al mismo tiempo, también abre una ventana para que otros desarrolladores les permitan personalizar el espacio de nombres en función del espacio de nombres existente, como introducir la etiqueta <Ognl>, utilizando expresiones OGNL para configurar las declaraciones SQL, etc.
(2) Personalizar la configuración. SQLSessionFactoryBean ha proporcionado más parámetros para la configuración personalizada, pero aún es posible requerir configuraciones más personalizadas, como:
A. Establezca el tipo de resultado predeterminado. Para elementos <select> que no establecen resultados de resultados y resultados de resultados, puede establecer el tipo de retorno predeterminado en el mapa después del análisis, simplificando así la configuración de SQLMapper.
<
B. Extienda el análisis de parámetros original de MyBatis. La implementación de análisis nativo es predeterminado ParameterHandler. Esta implementación puede ser heredada y extendida. Por ejemplo, para la expresión de propiedad prefijo por Spel:, use Spel para evaluar el valor.
(3) Para otras extensiones, consulte el blog anterior del autor sobre MyBatis Extension
3. Viabilidad de la reconstrucción
(1) En términos del alcance de la influencia del código
A continuación se muestra la estructura de herencia de SQLSessionFactoryBean
A partir de esto, podemos ver que el sistema de herencia SQLSessionFactoryBean no es complicado, y no hereda otras clases de padres. Solo implementa tres interfaces en Spring (el EventListener en JDK es solo un logotipo). Además, SQLSessionFactoryBean está dirigido al usuario de desarrollo final, sin subclases y ninguna otra clase que lo llame, por lo que es muy pequeño en términos del alcance del impacto del código.
(2) En la implementación de reconstrucción, puede crear un nuevo schemasqlSessionFactoryBean, y luego el código copiar completamente el SQLSessionFactoryBean al principio, modificar el nombre del paquete y el nombre de clase, y luego usar esto como base para la reconstrucción. Esto es relativamente simple.
(3) En aplicaciones integradas, solo necesita modificar los atributos de clase en la configuración integrada y el resorte.
Lo anterior es la refactorización del SQLSessionFactoryBean integrado con MyBatis y Spring presentada a usted. Espero que te sea útil. Si tiene alguna pregunta, déjame un mensaje y el editor le responderá a tiempo. ¡Muchas gracias por su apoyo al sitio web de Wulin.com!