D'une manière générale, la modification du code source du cadre est extrêmement risqué et ne le modifie pas à moins qu'elle ne soit absolument nécessaire. Mais aujourd'hui, j'ai soigneusement reconstruit la classe SQLSessionFactoryBean officiellement fournie par Mybatis, qui est intégrée au printemps. Premièrement, il a une mentalité d'essai et d'erreur, et deuxièmement, il a des besoins réalistes.
Permettez-moi d'expliquer en premier deux points:
De manière générale, le refactorisation fait référence à l'optimisation du code sans modifier la fonction, mais le refactorisation mentionnée dans cet article comprend également l'ajout de fonctions.
Les packages de bocaux principaux (versions) utilisés dans cet article: Spring - * - 4.3.3.release.jar, Mybatis-3.4.1.jar, Mybatis-Spring-1.3.0.jar
Commençons par l'intégration de Mybatis et du printemps.
1. Intégrer Mybatis et Spring
<bean id = "sqlSessionFactory" p: dataSource-ref = "dataSource" p: configLocation = "classpath: mybatis / mybatis-clonfig.xml"> <property name = "mapperlocations"> <array> <value> classpath *: ** / *.
La classe clé de l'intégration est org.mybatis.spring.sqlSessionFactoryBean, qui est un bean d'usine utilisé pour générer MyBatis Global Session Factory SqlSessionFactory (c'est-à-dire le bean d'usine qui génère l'usine de session), et SQLSessionFactory est utilisé pour générer un objet SQLSession (SQLSSESSIONFACTOR SQLSession est équivalente à la connexion).
Où les propriétés (configurées à l'aide de l'espace p ou de l'élément enfant de propriété):
DataSource est une source de données, qui peut être configurée à l'aide de DBCP, C3P0, Druid, Jndi-Lookup et d'autres méthodes.
La configlocation est une configuration globale du moteur MyBatis, utilisé pour modifier le comportement de MyBatis.
Mappellocations est le fichier de configuration de script SQLMapper (mode) que MyBatis doit charger.
Bien sûr, il existe de nombreux autres attributs, donc je ne donnerai pas d'exemple ici.
2. Pourquoi reconstruire
1. Optimisation du code source
La fonction de SQLSessionFactoryBean est de générer SQLSessionFactory. Jetons un coup d'œil à cette méthode (SqlSessionFactoryBean.Java Line 384-538): / *** Build A {@code sqlSessionFactory}. 1.3.0, il peut être spécifié directement une instance {@Link Configuration} (sans fichier de configuration). ** @return sqlSessionFactory * @throws ioException si le chargement du fichier de configuration a échoué * / Protected SqlSessionFactory buildsqlSessionFactory () lance ioexception {configuration; xmlconfigBuilder xmlconfigreder; (this.configuration! = null) {configuration = this.configuration; if (configuration.getVariables () == null) {configuration.setVariables (this.configurationProperties);} else if (this.configurationproperties! = null) {configuration.getVariables (). (this.configlocation! = null) {xmlconfigBuilder = new XmlConfigBuilder (this.configlocation.getInputStream (), null, this.configurationProperties); Configuration = xmlConfigBuilder.getConfiguration ();} else {if (logger.isdebugeableable ()) {Logger.debug ("propriété` configuration` ou 'configLocation' non spécifié, en utilisant la configuration de mybatis par défaut ");} configuration = new Configuration (); configuration.setVariables (this.configurationProperties);} if (this.objectfactory! = Null) {configuration.setobjectfactory (this.objectfactory); (this.objectwrapperfactory! = null) {configuration.setObjectWrapperFactory (this.objectwrapperfactory);} if (this.vfs! = null) {configuration.setvfSimpl tokenizetoStringArray (this.typealiasespackage, configurableApplicationContext.config_location_delimiters); pour (String PackageToscan: TypeALiasPackAgearRay) {configuration.getTypeALiasRegistry (). RegisterAliases (PackageToscan, tyciasesperType == null? Object.class: TypeALesUperType); if (logger.isdebugenable alias ");}}} if (! isempty (this.typealiases)) {for (class <?> typelias: this.typealiases) {configuration.getTypealiasRegistry (). RegisterAlias (tycias); if (logger.isdebugeNabled () {logger.debug (" enregistré TYP "'");}}} if (! isempty (this.plugins)) {for (interceptor plugin: this.plugins) {configuration.addinterceptor (plugin); if (logger.isdebugeNable ()) {logger.debug ("plugin enregistré:'" + plugin + "'");}}} if Ifhing:' "+" "" ");}}} si (HasLength (this.TypeHandlersPackage)) {String [] typeHandlerspackageArray = tokenizetoStringArray (this.typehandlerspackage, configurableApplicationContext.config_Location_Delimiters); for (String packagetoscan: typeHandlersPackageArray) {configuration.getTypeHandlerRegistry (). Register (packagetoscan); if (logger.isdebugeNabled ()) {logger.debug ("package scanned: '" + packagetoscan + "' pour les transporteurs de type");}}}}}}} si (! ISEMPTY (this.typeHandlers)) {for (TypeHandler <?> TypeHandler: this.typeHandlers) {configuration.getTypeHandlerRegistry (). Register (TypeHandler); if (logger.isdebugeabled ()) {Logger.Debug ("Enregistred Type Handler:" + TypeHDERLler + "" "}} (this.databaseidProvider! = null) {// Correction # 64 SET DATABASEID AVANT PARSE MAPTER XMLSTRY {Configuration.SetDatabaseID (this.databaseidProvider.getDatabaseId (this.datasource));} Catch (sqException e) {lancer newetioException ("a échoué Gett (this.cache! = null) {configuration.addcache (this.cache);} if (xmlconfigBuilder! = null) {try {xmlconfigbuilder.parse (); if (logger.isdebugeabled () {logger.debug ("Fichier de configuration parfumé: '" + ce.configor + "'");}} catch (exception ex) {throw new NetestioException ("a échoué à analyser la ressource de configuration:" + this.configlocation, ex);} enfin {errorContext.instance (). reset ();}} if (new.transactionFactory == null) {this.transactionfactory = new SpringManagedTransActionFactory ();} configuration.setenvironment (nouvel environnement (this.environment, this.transactionFactory, this.datasource)); if (! ISempty (this.mapperLocations)) {for (Resource MapperLocation: this.mapperLocations) {if (maweplocation == null) {continu;} {XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(mapperLocation.getInputStream(),configuration, mapperLocation.toString(), configuration.getSqlFragments());xmlMapperBuilder.parse();} catch (Exception e) {throw new NestedIOException("Failed to parse mapping resource: '"+ mapperlocation +"' ", e);} enfin {errorContex {Logger.debug ("propriété 'mappelocations' n'a pas été spécifié ou aucune ressource correspondante trouvée");}} return this.sqlSessionFactoryBuilder.build (configuration);}Bien que MyBatis soit un excellent cadre de couche de persistance, pour être honnête, ce code n'est en effet pas très bon et a beaucoup de place pour la reconstruction et l'optimisation.
2. Extension fonctionnelle
(1) Utiliser le schéma pour vérifier Sqlmapper
<! - Mode DTD -> <? Xml version = "1.0" Encoding = "UTF-8"?> <! Doctype Mappen Public "- // Mybatis.org//dtd Mapper 3.0 // en" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace = "org.dysd.dao.mybatis.config.iexampledao"> </ mapper> <! - Mode de schéma -> <? xml version = "1.0" Encoding = "utf-8"?> <masper 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>
À première vue, l'utilisation du schéma est plus compliquée, mais si elle est combinée avec l'IDE, les invites automatiques de l'utilisation du schéma sont plus amicales et les informations de vérification sont plus claires. Dans le même temps, il ouvre également une fenêtre pour que d'autres développeurs leur permettent de personnaliser l'espace de noms en fonction de l'espace de noms existant, tel que l'introduction de la balise <ognl>, en utilisant les expressions OGNL pour configurer les instructions SQL, etc.
(2) Personnaliser la configuration. SQLSessionFactoryBean a fourni plus de paramètres pour la configuration personnalisée, mais il est toujours possible d'exiger des paramètres plus personnalisés, tels que:
A. Définissez le type de résultat par défaut. Pour les éléments <lelect> qui ne définissent pas le résultat de résultat et le résultat, vous pouvez définir le type de retour par défaut sur map après l'analyse, simplifiant ainsi la configuration de SQLMapper.
<! - Avant simplifié -> <select id = "select" resultType = "map"> select * from Table_name où champ1 = # {field1, jdbcType = varchar} </lect> <! - après simplification -> <sélectionB. Étendez l'analyse des paramètres d'origine de MyBatis. L'implémentation d'analyse native est defaultParameterHandler. Cette implémentation peut être héritée et étendue. Par exemple, pour l'expression de propriété préfixée par Spel:, utilisez Spel pour évaluer la valeur.
(3) Pour d'autres extensions, veuillez vous référer au blog précédent de l'auteur sur l'extension MyBatis
3. Faisabilité de la reconstruction
(1) en termes de portée de l'influence du code
Vous trouverez ci-dessous la structure d'héritage de SQLSessionFactoryBean
À partir de cela, nous pouvons voir que le système d'héritage SQLSessionFactoryBean n'est pas compliqué, et il n'hérite pas d'autres classes de parents. Il n'implémente que trois interfaces dans le printemps (l'événementListener dans JDK n'est qu'un logo). De plus, SQLSessionFactoryBean est destiné à l'utilisateur de développement final, sans sous-classes ni autres classes qui l'appellent, il est donc très petit en termes de portée de l'impact du code.
(2) Dans l'implémentation de la reconstruction, vous pouvez créer un nouveau schémaSQLSessionFactoryBean, puis le code copie complètement le SQLSessionFactoryBean au début, modifiez le nom du package et le nom de la classe, puis utilisez-le comme base pour la reconstruction. C'est relativement simple.
(3) Dans les applications intégrées, il vous suffit de modifier les attributs de classe dans la configuration et le ressort intégrés.
Ce qui précède est le refactorisation du SQLSessionFactoryBean intégré à Mybatis et au printemps présentés. J'espère que cela vous sera utile. Si vous avez des questions, veuillez me laisser un message et l'éditeur vous répondra à temps. Merci beaucoup pour votre soutien au site Web Wulin.com!