Existen muchas limitaciones al usar MyBatis solo (como no poder implementar transacciones que abarcan múltiples sesiones), y muchos sistemas comerciales son originalmente transacciones administradas por Spring, por lo que MyBatis está mejor integrado con Spring.
Requisitos de la versión
proyecto | Versión | Dirección de descarga | ilustrar |
mybatis | 3.0 y superior | https://github.com/mybatis/mybatis-3/releases | |
primavera | 3.0 y superior | http://projects.spring.io/springframework/ | |
mybatis-spring | 1.0 y superior | https://github.com/mybatis/spring/releases |
< name = "DataSource" ref = "jndidataSource"/> </reme> <!-Configure las cosas basadas en anotaciones AOP-> <tx: transaccion-manager de anotación = "txmanager" proxy-target-class = "true"/>>
Integración única
< value = "com.xxx.dto" /> < /bean> <!-create dao bean (solo proporcione interfaces pero no clases de implementación)-> <bean id = "userdao"> <propiedad name = "mapperinterface" value = "com.xxx.dao.userdao" /> <Property name = "sqlSsession" Ref = "sqlsession
No solo debemos entender cómo usarlo, sino también entender por qué lo usamos así.
SQLSessionFactoryBean es un frijol de fábrica, y su función es analizar las configuraciones (fuente de datos, alias, etc.).
MapperFactoryBean es un frijol de fábrica. En el contenedor de primavera, los frijoles de fábrica tienen usos especiales. Cuando Spring inyecta frijoles de fábrica en otros frijoles, no inyecta el bean de fábrica en sí, pero llama al método GetObject del bean. Echemos un vistazo a lo que hace este método GetObject:
public t getObject () lanza la excepción {return getSqlSession (). getMapper (this.mapperterinterface); }Después de ver esto, debe comprender que este método es el mismo que cuando usamos mybatis solos. Primero obtenemos un objeto SQLSession, y luego obtenemos el objeto Mapper de la SQLSession (contra el mapeador hay un objeto proxy, que proxiona la interfaz de la interfaz mapper, y esta interfaz es la interfaz DAO proporcionada por el usuario). Naturalmente, la inyección final en la capa comercial es este objeto mapeador.
En términos generales, hay más de un proyecto. Si tiene múltiples proyectos, continúe en secuencia de acuerdo con la configuración anterior.
Cómo usar actualizaciones por lotes
La sección anterior habló sobre cómo inyectar un objeto mapeador en la capa de negocios. El comportamiento de Mapper depende de la configuración. MyBatis usa una sola actualización por defecto (es decir, el Ejecutype predeterminado es simple en lugar de lote). Por supuesto, podemos modificar el comportamiento predeterminado modificando el archivo de configuración de MyBatis, pero si solo queremos que uno o varios mapeadores usen actualizaciones por lotes, no se puede hacer. En este momento, necesitamos usar la tecnología de plantilla:
< id = "sqlsessionTemplateBatch"> <constructor-arg index = "0" ref = "sqlsessionFactory"/> <!-Actualizar en un modo por lotes-> <constructor-arg index = "1" valor = "lote"/> </bean>
Aquí, el autor define dos objetos de plantilla, uno que usa una sola actualización y la otra usando la actualización de lotes. Después de tener la plantilla, podemos cambiar la forma en que se comporta Mapper:
<bean id = "userdao"> <propiedad name = "mapperinterface" value = "com.xxx.dao.userdao" /> <propiedad name = "sqlsessionTemplate" ref = "sqlsessiontemplateBatch" /> < /bean>
A diferencia de la configuración del mapeador en la sección anterior, no es necesario configurar la propiedad SQLSessionFactory aquí, solo necesita configurar el SQLSessionTemplate (la propiedad SQLSessionFactory se ha configurado en la plantilla).
Simplifique la configuración de mapeadores con escaneo automático
Como puede ver en el capítulo anterior, nuestro DAO debe configurarse uno por uno en el archivo de configuración. Si hay muchos DAO, el archivo de configuración será muy grande, lo que será más doloroso de manejar. Afortunadamente, el equipo de MyBatis también se dio cuenta de esto. Utilizaron la función de escaneo automático proporcionada por Spring para encapsular una clase de herramienta que escanea automáticamente, para que podamos usar esta función para simplificar la configuración:
< < /bean> <!-Crear mapper bean usando escaneo automático (modo de actualización de lotes)-> <bean> <propiedad name = "basepackage" value = "com.xxx.dao" /> <propiedad name = "sqlsessionTeMplateBeanName" value = "sqlsessionTemplateBatch" /> <name de propiedad = "markerinterface" value = "com.xx.daoo /> < /bean>
No hablaré sobre la tecnología de primavera involucrada en el propio MappersCannerConfigurer. Si está interesado y comprende bien los principios de la primavera, puede verificar su código fuente. Centrémonos en sus tres propiedades:
Además de usar el filtrado de interfaz, también puede usar el filtrado de anotación:
< </bean>
anotaciónClass: solo cuando la anotación esté configurada será escaneada por el escáner, y el basepackage es la función de la misma.
Cabe señalar que solo una de las dos condiciones de filtro puede coincidir.
Ejemplo: gestión de transacciones
Definir una clase de entidad: emp.java
paquete com.lixing.scm.Entity; public class EMP {private String id; nombre de cadena privada; sexo de cuerda privada; edad privada int; Teléfono de cadena privada; public String getId () {return id; } public void setid (ID de cadena) {this.id = id; } public String getName () {nombre de retorno; } public void setName (nombre de cadena) {this.name = name; } public String getsex () {return sex; } public void setsex (sexo de cadena) {this.sex = sex; } public int getAge () {return Age; } public void setAge (int Age) {this.age = edad; } public String getPhone () {return Phone; } public void setphone (teléfono de cadena) {this.phone = phone; }} Defina la interfaz de operación interna: empmapper.java
paquete com.lixing.scm.test.mapper; import java.util.list; import java.util.map; import com.lixing.scm.entity.emp; interfaz pública empmapper {void insertemp (empt emp); Lista <EMP> getAllEmp (); EMP getByid (ID de cadena); void deleteemp (ID de cadena); Void UpdateEmp (map <string, object> map);} Defina el archivo de asignación para la interfaz de operación de la clase de entidad: empmapper.xml
<? xml versión = "1.0" encoding = "utf-8"?> <! Doctype mapper public "-// mybatis.org//dtd mapper 3.0 // en" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace = "com.lixing.scm.test.mapper.empmapper"> <parametermap type = "com.lixing.scm.entity.emp" id = "parametermapempeMp"> <parameter propiedad = "id"/> <parameter = "name"/> <parametrety = "sex"/> <parameter propiedad = "edad"/> <propiedad de parámetro = "teléfono/" name "/> <parámetro =" sexo "/> <parámetro propiedad =" edad "/> <propiedad de parámetro =" Teléfono/"name"/> <parámetro = "sexo"/> <parámetro de parámetro = "edad"/> <propiedad de parámetro = "teléfono/" teléfono "/" Propiedad de parámetro Propiedades <resultmap type = "com.lixing.scm.entity.emp" id = "resultMapemp"> <resultado propiedad = "id" columna = "id"/> <resultado propiedad = "name" column = "name"/> <resultado propiedad = "sexo" columna = "sexo"/> <resulte = "edad"/> <resultado de resultados = "edad" columna = "edad"/> <resultado propiedad = "teléfono"/> <> </> </dutado id = "insertemp" parametermap = "parametermapemp"> insertar en emp (id, nombre, sexo, edad, teléfono) valores (?,?,?,?,?) </sert> <select id = "getAllEmp" resultmap = "resultMapeMp"> seleccione * de EMP </select> <select id = "GetByid" ParameterType = "String" ResultMap = "ResultMapeMp" De SELECT * de Where * Where Where * Where Where Where * Where Where * Where Where Where * Where Where * Where Where Where * Where Where Where * Where Where Where * Where Where Where * Where Where Where * Where Where Where * Where Where Where * Where Where * Where Where WhereMp " id =#{value} </select> <deletete id = "deleteteeMp" parameterType = "string"> Eliminar de Emp Where id =#{value} </elelete> <update id = "updateMp" parametertype = "java.util.map"> Úndate empt EMPET =#}, name}, sexo =#{sexo}, edad =#{edad {edad}, teléfono##} id =#{id} </update> </mapper> spring3.0.6 Definición: applicationContext.xml <? Xml versión = "1.0" encoding = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/Beanss" xmlns: xsi = "http://www.w3.org/2001/xmlschema-instance" xmlns: context = "http://www.springframework.org/schema/context" xmlns: aop = "http://wwww.springframwork.org/schemt" xmlns: tx = "http://www.springframework.org/schema/tx" xsi: schemalocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/spring-3. 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: anotation-config /> <context: component-scan base-paackage = "com.lixing.scm.test.*" /> <!-Jdbc.propertis Directory-> <Bean> <Property Name = "ubicaciones" valor = "classpath: jdbc.Properties" /> < /bean> <bean id = "myDataSource" destruye-method = "sear name = "DriverClassName" value = "$ {jdbc.driverClassName}" /> <propiedad name = "url" value = "$ {jdbc.url}" /> <propiedad name = "username" value = "$ {jdbc.username}" /> <name de propiedad = "contraseña" valor = "$ {jdbc.portword} /> <<! SqlSessionFactory-> <bean id = "sqlSessionFactory"> <Property name = "dataSource" ref = "myDataSource" /> < /bean> <!-scanMapperfiles-> <Bean> <Property name = "basepackage" value = "com.lixing.scm.test.mapper" /> </ean> <!- ================================================================== S name = "TransActionManager"> <Property Name = "DataSource" ref = "myDataSource"> </sperty> </bean> <tx: consejo id = "usertxadvice" transaction-ganager = "transactionManager"> <tx: atributes> <tx: método name = "deliminar*" propagation = "requerido" requerido "falso" rollback-for-for = "jaxang". No-Rollback-For = "java.lang.runteException" /> <tx: método name = "insert*" propagation = "requerido" requerido a la sola <tx: método name = "find*" propagation = "admite"/> <tx: método name = "get*" propagation = "admite"/> <tx: método name = "select*" propagation = "admite"/> </tx: atributas> </tx: consejo> <aop: config> <aop: punto id = "PC" PC "Expresión =" Ejecución (pública*(pública*(pública*(pública*(pública*) com.lixing.scm.test.service.*.*(..)) " /> <!-Control Transacciones a nivel de servicio-> <aop: Advisor PointCut-REF =" PC "ASCESION-REF =" USERTXAdVice " /> < /aop: config> <!-El siguiente es un bean personalizado-> <bean id =" empada "autowire =" byname " /" /" /" EMPERIE = "EMPERIE =" EMPERIE " AUTOWIRE = "BYNAME"/> </Beans> Interfaz Dao: empdao.java
paquete com.lixing.scm.test.dao; import java.util.list; import java.util.map; import com.lixing.scm.entity.emp; interfaz pública empdao {void insertemp (empt emp); Lista <EMP> getAllEmp (); EMP getByid (ID de cadena); void deleteemp (ID de cadena); Void UpdateEmp (map <string, object> map);} Clase de implementación de la interfaz DAO: empdaoImpl.java
paquete 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.mapper Empmapper empmapper; // Inyectar un empmapper aquí // Este empmapper se genera automáticamente por Spring // No necesitamos definir manualmente @Override public void InsertEmp (EMP EMP) {this.empmapper.insertemp (EMP); tirar nueva runtimeException ("error"); // Test lanza RuntimeException // Excepción para ver si la base de datos tiene registros} @Override public void deleteemp (ID de cadena) {this.empmapper.deleteEmp (id); } @Override Public List <Emp> getAllEmp () {return this.empmapper.getAllEmp (); } @Override public emp getByid (ID de cadena) {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; }} Interfaz de capa de servicio: Empservice.java
paquete com.lixing.scm.test.service; import com.lixing.scm.entity.emp; Public Interface Empservice {void insertemp (emp);} Clase de implementación de interfaz de capa de servicio: empserviceImpl.java
paquete 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; empservice de clase pública implementa empservice {empda empdao empdao; @Override public void Insertemp (EMP EMP) {empdao.insertemp (emp); } public empdao getempdao () {return empdao; } public void setempdao (empdao empdao) {this.empdao = empdao; }} Clase de prueba: TestEmpService.java
importar 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.EmpsService; Class de clase pública; testTrasAction () {empt emp = new emp (); Emp.SetId ("00000003"); emp.setName ("某某某"); emp.setage (50); emp.setSex ("macho"); Emp.SetPhone ("566666"); ApplicationContext CTX = new ClassPathXMLApPlicationContext ("ClassPath: ApplicationContext.xml"); Servicio EmpService = CTX.GetBean (Empservice.class); servicio.insertemp (EMP); }}