Il existe de nombreuses limites lorsque vous utilisez MyBatis seul (comme le fait de ne pas être en mesure d'implémenter des transactions couvrant plusieurs sessions), et de nombreux systèmes commerciaux sont à l'origine des transactions gérées par Spring, donc MyBatis est mieux intégré à Spring.
Exigences de version
projet | Version | Adresse de téléchargement | illustrer |
mybatis | 3.0 et plus | https://github.com/mybatis/mybatis-3/releases | |
printemps | 3.0 et plus | http://projects.spring.io/spring-framework/ | |
mybatis-spring | 1.0 et plus | https://github.com/mybatis/spring/releases |
<! - Analyse automatique des packages commerciaux -> <contextes: composant-scan basage-package = "com.xxx.service" /> <! - Source de données -> <Jee: jndi-lookup id = "jndidatasource" jndi-name = "java: comp / env / jdbc / datasource" /> <! name = "dataSource" ref = "jndidatasource" /> </ank> <! - Configurer les choses basées sur l'annotation aop -> <tx: annotation-moteur transaction-manager = "txManager" proxy-target-class = "true" />
Intégration unique
<! - Intégration de mybatis -> <bean id = "SqlSessionFactory"> <propriété name = "dataSource" ref = "jndidatasource" /> <propriété name = "configLocation" value = "classpath: /mybatis/mybatis-config.xml" /> <! Value = "com.xxx.dto" /> </ank> <! - Créez Dao Bean (il suffit de fournir des interfaces mais pas des classes d'implémentation) -> <bean id = "userdao"> <propriété name = "MAPPERInterface" value = "com.xxx.dao.userdao" /> <propriété name = "SQLSessionfactory" Ref = "SQLSSSESSIQUE"
Nous devons non seulement comprendre comment l'utiliser, mais aussi comprendre pourquoi nous l'utilisons comme ça.
SQLSessionFactoryBean est un bean d'usine, et sa fonction consiste à analyser les configurations (source de données, alias, etc.).
MapperFactoryBean est un haricot d'usine. Dans le conteneur de printemps, les haricots d'usine ont des utilisations spéciales. Lorsque Spring injecte des haricots d'usine dans d'autres haricots, il n'injecte pas le haricot d'usine lui-même mais appelle la méthode GetObject du Bean. Jetons un coup d'œil à ce que fait cette méthode GetObject:
public t getObject () lève exception {return getSQlSession (). getMapper (this.mapperInterface); }Après avoir vu cela, vous devez comprendre que cette méthode est la même que lorsque nous avons utilisé Mybatis seul. Nous obtenons d'abord un objet SQLSession, puis obtenons l'objet de mappeur à partir de la SQLSession (contre le mappeur est un objet proxy, qui indique l'interface d'interface de mapper, et cette interface est l'interface DAO fournie par l'utilisateur). Naturellement, l'injection finale dans la couche commerciale est cet objet de mappeur.
D'une manière générale, il y a plus d'un projet. Si vous avez plusieurs projets, configurez-les en séquence en fonction de la configuration ci-dessus.
Comment utiliser les mises à jour par lots
La section précédente a expliqué comment injecter un objet mappeur dans la couche commerciale. Le comportement du mappeur dépend de la configuration. MyBatis utilise une seule mise à jour par défaut (c'est-à-dire que le parau défaut est simple au lieu d'un lot). Bien sûr, nous pouvons modifier le comportement par défaut en modifiant le fichier de configuration MyBatis, mais si nous ne voulons qu'un ou plusieurs mappeurs pour utiliser des mises à jour par lots, cela ne peut pas être fait. Pour le moment, nous devons utiliser la technologie des modèles:
<! - Personnalisez le comportement de MyBatis via des modèles-> lt; bean id = "sqlSessionTemplateImple"> <constructor-arg index = "0" ref = "sqlSessionFactory" /> <! - Mise à jour en un seul mode -> <Constructor-arg index = "1" Value = "Simple" /> </Ean> <! id = "sqlSessionTemplateBatch"> <constructor-arg index = "0" ref = "sqlSessionFactory" /> <! - Mise à jour en mode batch -> <constructor-arg index = "1" value = "batch" /> </ bean>
Ici, l'auteur définit deux objets de modèle, l'un utilisant une seule mise à jour et l'autre à l'aide de la mise à jour par lots. Après avoir le modèle, nous pouvons changer le comportement du mappeur:
<bean id = "userdao"> <propriété name = "MAPERInterface" value = "com.xxx.dao.userdao" /> <propriété name = "sqlSessionTemplate" ref = "sqlSessionTemplatebatch" /> </ bean>
Différent de la configuration du mappeur dans la section précédente, il n'est pas nécessaire de configurer la propriété SQLSessionFactory ici, il vous suffit de configurer le SQLSessionTemplate (la propriété SQLSessionFactory a été configurée dans le modèle).
Simplifiez la configuration des mappeurs avec numérisation automatique
Comme vous pouvez le voir dans le chapitre précédent, notre DAO doit être configuré un par un dans le fichier de configuration. S'il y a beaucoup de DAO, le fichier de configuration sera très grand, ce qui sera plus douloureux à gérer. Heureusement, l'équipe MyBatis a également réalisé cela. Ils ont utilisé la fonction de balayage automatique fournie par Spring pour encapsuler une classe d'outils qui scanne automatiquement, afin que nous puissions utiliser cette fonction pour simplifier la configuration:
<! - Créez du bean de mappeur à l'aide de la numérisation automatique (mode de mise à jour unique) -> <ean> <propriété name = "basepackage" value = "com.xxx.dao" /> <propriété name = "sqlSessionTemplateBeanName" value = "SqlSessionTempplateImple" /> <propriété named = "Marketerface" value = "com.xxx.dao.simpleda" / <pEAND> " <! - Créez du bean de mappeur à l'aide de la numérisation automatique (mode de mise à jour par lots) -> <ean> <propriété named = "basepackage" value = "com.xxx.dao" /> <propriété name = "SqlSessionTemplateBeAnName" Value = "SqlSessionTemplatebatch" /> <propriété name = "Marqueterface" value = "com.xxx.dao.batchda"
Je ne parlerai pas de la technologie de printemps impliquée dans MapperscannerConfigurer lui-même. Si vous êtes intéressé et avez une bonne compréhension des principes du printemps, vous pouvez vérifier son code source. Concentrons-nous sur ses trois propriétés:
En plus d'utiliser le filtrage d'interface, vous pouvez également utiliser le filtrage d'annotation:
<! - Créez du bean de mappeur à l'aide de la numérisation automatique (mode de mise à jour par lots) -> <ean> <propriété named = "basepackage" value = "com.xxx.dao" /> <propriété name = "SqlSessionPlateBame" value = "SqlSessionTemplatebatch" /> <propriété name = "AnnotationClass" value = "com.xxx.dao.bratch" / </ bean Value = "com.xxx.dao.bratch" / </ "/" / bean up
AnnotationClass: Ce n'est que lorsque l'annotation est configurée sera analysée par le scanner, et le baspackage est la fonction de la même chose.
Il convient de noter qu'une seule des deux conditions de filtre peut être appariée.
Exemple: gestion des transactions
Définir une classe d'entité: emp.java
package com.lixing.scm.entity; classe publique Emp {private String id; nom de chaîne privé; Sexe à cordes privées; Âge privé; téléphone de chaîne privé; public String getID () {return id; } public void setid (String id) {this.id = id; } public String getName () {Nom de retour; } public void setName (string name) {this.name = name; } public String getSEX () {return sexe; } public void setSex (String Sex) {this.sex = sexe; } public int getage () {return âge; } public void Setage (int Age) {this.age = age; } public String gephone () {return téléphone; } public void setphone (String Phone) {this.phone = téléphone; }} Définissez l'interface de fonctionnement interne: empmapper.java
package com.lixing.scm.test.mapper; import java.util.list; import java.util.map; import com.lixing.scm.entity.emp; interface publique empmapper {void insertemp (emp emp); List <mp> getallemp (); EMP GetById (String ID); void DeleteEmp (String ID); void updateEMP (map <string, objet> map);} Définissez le fichier de mappage pour l'interface de fonctionnement de la classe d'entité: empmapper.xml
<? xml version = "1.0" Encoding = "UTF-8"?> <! Doctype Mappep Public "- // Mybatis.org//dtd Mappen 3.0 // en" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace = "com.lixing.scm.test.mapper.empmapper"> <paramètre type = "com.lixing.scm.entity.emp" id = "paramètre" <resultmap type = "com.lixing.scm.entity.emp" id = "resultMapEmp"> <result Property = "id" colonnel = "id" /> <résultat propriété = "name" column = "name" /> <result Property = "Sex" chronn = "Sex" /> <result Property = "Agel" /> <result Property id = "insertemp" Paramettermap = "ParameTermapEmp"> Insérer dans EMP (id, nom, sexe, Âge, Âge, téléphone) VALEURS (? ,? ,? ,?) </sert> <Select id = "getAlemp" resultMap = "resultMapEMP"> WHERE id=#{value} </select> <delete id="deleteEmp" parameterType="String"> DELETE FROM emp WHERE id=#{value} </delete> <update id="updateEmp" parameterType="java.util.Map"> UPDATE emp SET name=#{name},sex=#{sex},age=#{age},phone=#{phone} WHERE id = # {id} </ update> </ mapper> spring3.0.6 Définition: applicationContext.xml <? xml version = "1.0" Encoding = "utf-8"?> <Beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://www.w3.org/2001/xmlschema-instance" xmlns: context = "http://www.springframework.org/schema/contex xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd " <Context: Annotation-Config /> <Context: Component-Scan Base-Package = "com.lixing.scm.test. *" /> <! - JDBC.Propertis Directory -> <Eban> <Property Name = "Locations" Value = "ClassPath: JDBC.Properties" /> </ Bean> <ean Id = "Mydatasource" Détrolit " name = "driverclassname" value = "$ {jdbc.DriverClassName}" /> <propriété name = "url" value = "$ {jdbc.url}" /> <propriété name = "username" value = "$ {jdbc.Username}" /> <propriété name = "passway" value = "$ {jdbc.password}" SqlSessionFactory -> <bean id = "sqlSessionFactory"> <propriété name = "dataSource" ref = "MyDataSource" /> </ Bean> <! - ScanMapperFiles -> <anEn> <propriété name = "BASEPACKAGE" Value = "com.lixing.scm.test.mapper" /> </EAND> <! - ======================================================================================================================================. name = "TransactionManager"> <propriété name = "dataSource" ref = "MyDatasource"> </ propriété> </ank> <tx: conseils id = "userXadvice" transaction-manager = "transactionManager"> <tx: attributs> <tx: méthode name = "delete *" propagation = "requis" readly = "false" rollback-for = "java. no-rollback-for = "java.lang.runtimeexception" /> <tx: méthode name = "insert *" propagation = "required" readly = "false" rollback-for = "java.lang.runtimeexception" /> <tx: méthode name = "update *" propagation = "requis" read-only = "false" rollback-art <tx: méthode name = "find *" propagation = "supports" /> <tx: méthode name = "get *" propagation = "supports" /> <tx: méthode name = "select *" propagation = "supports" /> </ tx: attributes> </ tx: conseils> <aop: config> <aop: Pointcut id = "pc" expression = "Execution (public * com.lixing.scm.test.service. *. * (..)) "/> <! - Transactions de contrôle au niveau du service -> <aop: conseiller Pointcut-ref =" pc "conseils-ref =" userXadvice "/> </ aop: config> <! - Ce qui suit est un bean personnalisé -> <Bean id =" empdao " autowire = "byname" /> </ beans> Interface DAO: empdao.java
package com.lixing.scm.test.dao; import java.util.list; import java.util.map; import com.lixing.scm.entity.emp; interface publique empdao {void insertemp (emp emp); List <mp> getallemp (); EMP GetById (String ID); void DeleteEmp (String ID); void updateEMP (map <string, objet> map);} Classe d'implémentation de l'interface DAO: empdaoimpl.java
package com.lixing.scm.test.dao.impl; import java.util.list; import java.util.map; import com.lixing.scm.entity.emp; import com.lixing.scm.test.dao.empdao; import com.lixing.scm.test.empmapper; classe publique empdaoImple its idit {private Empmapper; empmapper; // Injecte un empmapper ici // Cet empmapper est automatiquement généré par Spring // Nous n'avons pas besoin de définir manuellement @Override public void inserteMp (EMP EMP) {this.empmapper.insertemp (emp); lancer un nouveau RuntimeException ("erreur"); // Test lance RuntimeException // Exception pour voir si la base de données a des enregistrements} @Override public void DeleteEMP (String id) {this.empmapper.deleteEmp (id); } @Override Public List <Emp> getAlmp () {return this.empmapper.getallemp (); } @Override public empyid (String id) {return this.empmapper.getById (id); } @Override public void updateEMP (map <string, object> map) {this.empmapper.updateEmp (map); } public empmapper getEmpMapper () {return empmapper; } public void SetEmpMapper (empmapper empmapper) {this.empmapper = empmapper; }} Interface de couche de service: empsservice.java
package com.lixing.scm.test.service; import com.lixing.scm.entity.emp; interface publique emprService {void insertemp (emp emp);} Classe d'implémentation de l'interface de la couche de service: empsserviceimpl.java
Package com.lixing.scm.test.service.impl; import com.lixing.scm.entity.emp; import com.lixing.scm.test.dao.empdao; import com.lixing.scm.test.service.empservice; public class empsvisviceImpl implémente emptels {price empda empdao; @Override public void inserteMp (EMP EMP) {empdao.insertemp (emp); } public empdao getEmpdao () {return empdao; } public void SetEmpdao (empdao empdao) {this.empdao = empdao; }} Classe de test: testempservice.java
import org.junit.test; import org.springframework.context.applicationContext; import org.springframework.context.support.classpathxmlapplicationcontext; import com.lixing.scm.entity.emp; import com.lixing.scm.test.service.EMPSERVIC TestTrasAction () {Emp emp = new Emp (); emp.setid ("00000003"); emp.setName ("某某某"); Emp.Setage (50); Emp.setSex ("Male"); Emp.setphone ("566666"); ApplicationContext ctx = new ClassPathxmlApplicationContext ("ClassPath: ApplicationContext.xml"); EMPSERVICE Service = CTX.GetBean (empservice.class); Service.Insertemp (EMP); }}