diff --git a/pom.xml b/pom.xml
index 324a223af5..fa2f1b36f6 100644
--- a/pom.xml
+++ b/pom.xml
@@ -330,6 +330,8 @@
maven-site-pluginen,es,zh_CN,ja,ko
+
+ ${project.build.directory}/site-src
@@ -346,6 +348,12 @@
${project.basedir}/src/main/resources
+
+
+ ${project.basedir}/src/site
+ ${project.build.directory}/site-src
+ true
+
diff --git a/src/site/es/markdown/README.md b/src/site/es/markdown/README.md
new file mode 100644
index 0000000000..a3abaf2e40
--- /dev/null
+++ b/src/site/es/markdown/README.md
@@ -0,0 +1,18 @@
+# Tabla de contenido
+
+Esta página es para representar el índice en GitHub.
+
+> **NOTE:**
+>
+> Dado que el destino del enlace se especifica asumiendo que se convierte a html con maven-site-plugin, hay un ancla que se rompe en el renderizado en GitHub.
+
+* [Introducción](./index.md)
+* [Primeros pasos](./getting-started.md)
+* [SqlSessionFactoryBean](./factorybean.md)
+* [Transactions](./transactions.md)
+* [Uso de SqlSession](./sqlsession.md)
+* [Inyección de Mappers](./mappers.md)
+* [Spring Boot](./boot.md)
+* [Uso del API de MyBatis](./using-api.md)
+* [Spring Batch](./batch.md)
+* [Código de ejemplo](./sample.md)
diff --git a/src/site/es/markdown/batch.md b/src/site/es/markdown/batch.md
new file mode 100644
index 0000000000..1578477f98
--- /dev/null
+++ b/src/site/es/markdown/batch.md
@@ -0,0 +1,351 @@
+
+# Spring Batch
+
+Desde la versión 1.1.0 MyBatis-Spring proporciona dos beans para construir aplicaciones Spring Batch: `MyBatisPagingItemReader` y `MyBatisCursorItemReader` y `MyBatisBatchItemWriter`.
+Also, As of version 2.0.0 provides three builder classes for supporting the Java Configuration: the `MyBatisPagingItemReaderBuilder`, the `MyBatisCursorItemReaderBuilder` and the `MyBatisBatchItemWriterBuilder`.
+
+NOTA
+Esta sección se refiere a [Spring Batch](http://static.springsource.org/spring-batch/) y no a sesiones batch de MyBatis. Para obtener información sobre las sesiones batch ve a la sección [Usnado un SqlSession](sqlsession.html).
+
+## MyBatisPagingItemReader
+
+Este bean es un `ItemReader` que lee registros de una base de datos usando paginación.
+
+Ejecuta la sentencia especificada mediante la propiedad `setQueryId` para obtener los datos. La sentencia se ejecuta usando peticiones paginadas del tamaño indicando en la propiedad `setPageSize`.
+Al llamar al método `read()` éste devuelve el objeto que corresponde a la posición actual y solicita más páginas si es necesario.
+
+El reader recibe algunos parametros estándar y la SQL deberá hacer uso de algunos de ellos para construir un resultset del tamaño requerido. Los parametros son:
+
+* `_page`: el número de página a leer (comenzando en 0)
+* `_pagesize`: el tamaño de la página, es decir, el número de filas a devolver
+* `_skiprows`: el producto de `_page` por `_pagesize`
+
+Se pueden mapear en un statement de tipo select de la siguiente forma:
+
+```xml
+
+```
+
+A continuación se muestra un ejemplo de configuración:
+
+```xml
+
+
+
+
+```
+```java
+@Configuration
+public class BatchAppConfig {
+ @Bean
+ public MyBatisPagingItemReader reader() {
+ return new MyBatisPagingItemReaderBuilder()
+ .sqlSessionFactory(sqlSessionFactory())
+ .queryId("com.my.name.space.batch.EmployeeMapper.getEmployee")
+ .build();
+ }
+}
+```
+
+**Veamos un ejemplo más complejo:**
+
+```xml
+
+```
+```xml
+
+
+
+
+
+
+```
+
+```java
+@Configuration
+public class BatchAppConfig {
+ @StepScope
+ @Bean
+ public MyBatisPagingItemReader dateBasedCriteriaReader(
+ @Value("#{@datesParameters}") Map datesParameters) throws Exception {
+ return new MyBatisPagingItemReaderBuilder()
+ .sqlSessionFactory(batchReadingSessionFactory())
+ .queryId("com.my.name.space.batch.ExampleMapper.queryUserInteractionsOnSpecificTimeSlot")
+ .parameterValues(datesParameters)
+ .pageSize(200)
+ .build();
+ }
+
+ @StepScope
+ @Bean
+ public Map datesParameters(
+ @Value("#{jobExecutionContext['EXTRACTION_START_DATE']}") LocalDate yesterday,
+ @Value("#{jobExecutionContext['TODAY_DATE']}") LocalDate today,
+ @Value("#{jobExecutionContext['FIRST_DAY_OF_THE_MONTH_DATE']}") LocalDate firstDayOfTheMonth,
+ @Value("#{jobExecutionContext['FIRST_DAY_OF_THE_PREVIOUS_MONTH_DATE']}") LocalDate firstDayOfThePreviousMonth) {
+ Map map = new HashMap<>();
+ map.put("yesterday", yesterday);
+ map.put("today", today);
+ map.put("first_day_of_the_month", firstDayOfTheMonth);
+ map.put("first_day_of_the_previous_month", firstDayOfThePreviousMonth);
+ return map;
+ }
+}
+```
+
+El ejemplo anterior hace uso de tres cosas distintas:
+
+* `sqlSessionFactory`: Puedes tu propio sessionFactory, podría ser útil si quires leer de varias bases de datos.
+* `queryId`: Si el código accede a varias tablas, y tienes distintas sentencias de consulta, puede ser interesante usar ficheros de mapeo distintos con namespaces distintos.
+ En este caso, al referirte a la query, no olvides incluir el namespace correspondiente.
+* `parameterValues`: Puedes pasar parametros adicionales en este mapa, el ejemplo de arriba usa un mapa que se construye usando una expresion SpEL y obteniendo valores del jobExecutionContext.
+ Las claves del mapa puede usarse en el fichero mapper de MyBatis (por ejemplo: *yesterday* se puede usar como `#{yesterday,jdbcType=TIMESTAMP}`).
+ Observa que el mapa y el reader se consutruyen en un solo `step` para que sea posible usar la expresión SpEL con el `jobExecutionContext`.
+ Adicionalmente si los type handlers de MyBatis están configurados correctamente puedes pasar instancias personalizadas como los parametros del ejemplo que son fechas JodaTime.
+* `pageSize`: Si le flujo batch está configurado con un tamaño de bloque (chunk size), es importante pasar esta información al reader, y eso se hace mediante esta propiedad.
+
+## MyBatisCursorItemReader
+
+Este bean es un `ItemReader` que lee registros de la base de datos usando un cursor.
+
+NOTA
+Para usar este bean necesitas al menos MyBatis 3.4.0 o superior.
+
+Ejecuta la sentencia especificada mediante la propiedad `setQueryId` para obtener los datos usando el método `selectCursor()`.
+Al llamar al método `read()` se devolverá el siguiente elemento del cursor hasta que no quede ninguno por devolver.
+
+El reader usa una conexión separada para que la sentencia no participe en ninguna transacción creada como parte del proceso del step.
+
+Cuando se usar un cursor puedes usar una sentencia convencional:
+
+```xml
+
+```
+
+A continuación se muestra un ejemplo de configuración:
+
+```xml
+
+
+
+
+```
+```java
+@Configuration
+public class BatchAppConfig {
+ @Bean
+ public MyBatisCursorItemReader reader() {
+ return new MyBatisCursorItemReaderBuilder()
+ .sqlSessionFactory(sqlSessionFactory())
+ .queryId("com.my.name.space.batch.EmployeeMapper.getEmployee")
+ .build();
+ }
+}
+```
+
+## MyBatisBatchItemWriter
+
+Es un `ItemWriter` que usa las capacidades de batch de `SqlSessionTemplate` para ejecutar sentencias batch para todos los elementos (items) proporcionados.
+El `SqlSessionFactory` debe configurarse con un executor de tipo `BATCH`.
+
+Ejecuta la sentencia indicada en la propiedad `statementId` cuando se invoca a `write()`. Se supone que `write()` se invoca dentro de una transacción.
+
+A continuación se muestra un ejemplo de configuración:
+
+```xml
+
+
+
+
+```
+
+```java
+@Configuration
+public class BatchAppConfig {
+ @Bean
+ public MyBatisBatchItemWriter writer() {
+ return new MyBatisBatchItemWriterBuilder()
+ .sqlSessionFactory(sqlSessionFactory())
+ .statementId("com.my.name.space.batch.EmployeeMapper.updateEmployee")
+ .build();
+ }
+}
+```
+
+**Converting a item that read using ItemReader to an any parameter object:**
+
+By default behavior, the `MyBatisBatchItemWriter` passes a item that read using `ItemReader` (or convert by `ItemProcessor`) to the MyBatis(`SqlSession#update()`) as the parameter object.
+If you want to customize a parameter object that passes to the MyBatis, you can realize to use the `itemToParameterConverter` option. For example using `itemToParameterConverter` option, you can passes any objects other than the item object to the MyBatis.
+Follows below a sample:
+
+At first, you create a custom converter class (or factory method). The following sample uses a factory method.
+
+```java
+public class ItemToParameterMapConverters {
+ public static Converter> createItemToParameterMapConverter(String operationBy, LocalDateTime operationAt) {
+ return item -> {
+ Map parameter = new HashMap<>();
+ parameter.put("item", item);
+ parameter.put("operationBy", operationBy);
+ parameter.put("operationAt", operationAt);
+ return parameter;
+ };
+ }
+}
+```
+
+At next, you write a sql mapping.
+
+```xml
+
+```
+
+At last, you configure the `MyBatisBatchItemWriter`.
+
+```java
+@Configuration
+public class BatchAppConfig {
+ @Bean
+ public MyBatisBatchItemWriter writer() throws Exception {
+ return new MyBatisBatchItemWriterBuilder()
+ .sqlSessionFactory(sqlSessionFactory())
+ .statementId("org.mybatis.spring.sample.mapper.PersonMapper.createPerson")
+ .itemToParameterConverter(createItemToParameterMapConverter("batch_java_config_user", LocalDateTime.now()))
+ .build();
+ }
+}
+```
+
+```xml
+
+
+
+
+
+
+
+
+
+
+```
+
+**Escribiendo en distintas tablas usando composite writers (con algunos condicionantes):**
+
+Esta técnica sólo puede usarse con MyBatis 3.2+, por que había un [error](http://code.google.com/p/mybatis/issues/detail?id=741) en las versiones anteriores que hacían que el writer funcionara de forma incorrecta.
+
+Si el batch necesita escribir datos complejos, como registros con asociaciones, o en distintas bases de datos, entonces es necesario sortear el problema de que los insert statements solo pueden escribir en una tabla.
+Para conseguir esto debes preparar un Item para que sea escrito por el writer. Sin embargo, dependiendo de las circunstancias puede ser interesante usar la siguiente técnica.
+El truco siguiente funciona con items con asociaciones simples o con tablas no relacionadas.
+
+Elabora el `item` de forma que *contenta* todos los resgistros distintos. Supon que para cada `item` hay una *Interaction* que tiene una asociación *InteractionMetadata* y dos filas no asociadas *VisitorInteraction* and *CustomerInteraction*.
+El objeto contenedor será de la siguiente forma:
+
+```java
+public class InteractionRecordToWriteInMultipleTables {
+ private final VisitorInteraction visitorInteraction;
+ private final CustomerInteraction customerInteraction;
+ private final Interaction interaction;
+ // ...
+}
+```
+```java
+public class Interaction {
+ private final InteractionMetadata interactionMetadata;
+}
+```
+
+Entonces en la configuración de spring habrá un `CompositeItemWriter` que usará writers delegados configurados especificamente para cada tipo de registro.
+Fijate que el *InteractionMetadata* es una asociacióin en el ejemplo por lo que debe ser escrita antes para que la Interaction pueda recibir la clave generada.
+
+```xml
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```java
+@Configuration
+public class BatchAppConfig {
+ @Bean
+ public CompositeItemWriter> interactionsItemWriter() {
+ CompositeItemWriter compositeItemWriter = new CompositeItemWriter();
+ List> writers = new ArrayList<>(4);
+ writers.add(visitorInteractionsWriter());
+ writers.add(customerInteractionsWriter());
+ writers.add(interactionMetadataWriter());
+ writers.add(interactionWriter());
+ compositeItemWriter.setDelegates(writers);
+ return compositeItemWriter;
+ }
+}
+```
+
+Cada writer delegados se configura como sea necesario, por ejemplo para *Interaction* y *InteractionMetadata*:
+
+```xml
+
+```
+```xml
+
+```
+
+Al igual que con el reader el `statementId` puede hacer referencia al statement con un namespace como prefijo.
+
+Ahora es debe elaborarse el fichero de mapeo para cada tipo de registro, de la siguiente forma:
+
+```xml
+
+
+
+```
+```xml
+
+
+
+```
+
+Lo que sucede es que primeramente se llamará a `insertInteractionMetadata`, y la sentencia de update está configurada para devolver las claves autogeneradas (`keyProperty` y `keyColumn`).
+Una vez que el `InteractionMetadata` se ha almacenado por esta sentencia se puede ejecutar la siguiente para escribir el objeto padre `Interaction` mediante `insertInteraction`.
+
+***Sin embargo, ten en cuenta que los drivers JDBC se comportan distinto en este aspecto. A la fecha en la que se escribe esto
+el driver H2 1.3.168 solo devuelve el último ID incluso en modo BATCH (see `org.h2.jdbc.JdbcStatement#getGeneratedKeys`),
+mientras que el driver JDBC de MySQL se comporta como es de esperar y devuelve todos los IDs.***
diff --git a/src/site/es/markdown/boot.md b/src/site/es/markdown/boot.md
new file mode 100644
index 0000000000..cda8eb3a3d
--- /dev/null
+++ b/src/site/es/markdown/boot.md
@@ -0,0 +1,4 @@
+
+# Using Spring Boot
+
+Please see the [MyBatis Spring-boot-starter](http://www.mybatis.org/spring-boot-starter/mybatis-spring-boot-autoconfigure) sub project docs for details.
diff --git a/src/site/es/markdown/factorybean.md b/src/site/es/markdown/factorybean.md
new file mode 100644
index 0000000000..598f28aef3
--- /dev/null
+++ b/src/site/es/markdown/factorybean.md
@@ -0,0 +1,100 @@
+
+# SqlSessionFactoryBean
+
+En MyBatis una `SqlSessionFactory` se crea mediante la clase `SqlSessionFactoryBuilder`. En MyBatis-Spring se usa la clase `SqlSessionFactoryBean` en su lugar.
+
+## Configuración
+
+Para crear un factory bean, pon lo siguiente en el fichero XML de configuración de Spring:
+
+```xml
+
+
+
+```
+
+La clase `SqlSessionFactoryBean` implementa el interfaz `FactoryBean` (see [the Spring documentation(Core Technologies -Customizing instantiation logic with a FactoryBean-](https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#beans-factory-extension-factorybean)).
+Lo cual significa que el bean que crea Spring en última instancia **no** es un `SqlSessionFactoryBean` en si mismo, sino el objeto que la factoria devuelve como resultado de la llamada al método `getObject()`.
+En este caso, Spring creará un bean `SqlSessionFactory` durante el arranque de la aplicación y lo guardará bajo el nombre `sqlSessionFactory`. En Java, el código equivalente sería:
+
+```java
+@Configuration
+public class MyBatisConfig {
+ @Bean
+ public SqlSessionFactory sqlSessionFactory() {
+ SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
+ factoryBean.setDataSource(dataSource());
+ return factoryBean.getObject();
+ }
+}
+```
+
+Normalmente no necesitarás utilizar directamente un `SqlSessionFactoryBean` o su correspondiente `SqlSessionFactory` directly.
+En su lugar, la factoría se utilizará para ser inyectada en `MapperFactoryBean`s o DAOs que extiendan de `SqlSessionDaoSupport`.
+
+## Properties
+
+La clase `SqlSessionFactory` solo tiene una propiedad obligatoria, un `DataSource`.
+Puede ser cualquier `DataSource` y se puede configurar como cualquier otra conexión a base de daots de Spring.
+
+Una propiedad muy común es la `configLocation` que se utiliza para indicar la localización del fichero de configuración XML de MyBatis.
+Normalmente solo es necesario dicho fichero si se requiere cambiar los valores por defecto de las secciones `` o ``.
+
+Es importante saber que este fichero de configuración **no** tiene por qué ser un fichero de configuración de MyBatis completo.
+Concretamente, los environments, dataSources y transactionManagers serán **ignorados**.
+`SqlSessionFactoryBean` crea su propio `Environment` de MyBatis con los valores configurados tal y como se requieren.
+
+Otro motivo para necesitar un fichero de configuración es que los ficheros de mapeo XML no estén en el mismo lugar del classpath que los mapper interfaces.
+En este caso hay dos opciones. La primera es especificar manualmente el classpath de los ficheros XML usando la sección `` del fichero de configuración de MyBatis.
+La segunda opción es usar la propiedad `mapperLocations` del factory bean.
+
+La propiedad `mapperLocations` recibe una lista de localizaciones de recursos. Se utiliza para indicar la ubicación de los ficheros de mapeo XML de MyBatis.
+El valor puede contener un patron tipo Ant para cargar todos los ficheros de un directorio o buscar de forma recursiva en todos los paths desde una localización base. Por ejemplo:
+
+```xml
+
+
+
+
+```
+
+Esto cargaría todos los ficheros de mapeo XML en el paquete sample.config.mappers y sus subpaquetes.
+
+Otra propiedad que puede ser necesaria en un entorno con transacciones gestionadas por contenedor es la `transactionFactoryClass`. Lee la sección de transacciones para obtener más detalles.
+
+En caso de usar la característica multi-db necesitarás informar la propiedad `databaseIdProvider` de la siguiente forma:
+
+```xml
+
+
+
+ sqlserver
+ db2
+ oracle
+ mysql
+
+
+
+```
+```xml
+
+
+
+
+
+```
+
+NOTE
+Since 1.3.0, `configuration` property has been added. It can be specified a `Configuration` instance directly without MyBatis XML configuration file.
+For example:
+
+```xml
+
+
+
+
+
+
+
+
+```
diff --git a/src/site/es/markdown/getting-started.md b/src/site/es/markdown/getting-started.md
new file mode 100644
index 0000000000..fdaedcaa30
--- /dev/null
+++ b/src/site/es/markdown/getting-started.md
@@ -0,0 +1,99 @@
+
+# Primeros pasos
+
+Este capítulo te mostrará en pocos pasos cómo instalar y configurar MyBatis-Spring y cómo construir
+una pequeña aplicación transaccional.
+
+## Instalación
+
+Para usar el módulo MyBatis-Spring, debes incluir el fichero `mybatis-spring-${project.version}.jar` y sus dependencias en el classpath.
+
+Si usas Maven simplemente añade la siguiente dependencia a tu pom.xml:
+
+```xml
+
+ org.mybatis
+ mybatis-spring
+ ${project.version}
+
+```
+
+## Configuración rápida
+
+Para usar MyBatis con Spring necesitas definir al menos dos cosas en tu contexto Spring: una `SqlSessionFactory` y al menos un mapper interface.
+
+En MyBatis-Spring se usa un `SqlSessionFactoryBean` para crear una `SqlSessionFactory`. Para configurar la factory bean pon lo siguiente en tu fichero de configuración de Spring:
+
+```xml
+
+
+
+```
+
+```java
+@Configuration
+public class MyBatisConfig {
+ @Bean
+ public SqlSessionFactory sqlSessionFactory() throws Exception {
+ SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
+ factoryBean.setDataSource(dataSource());
+ return factoryBean.getObject();
+ }
+}
+```
+
+Observa que la `SqlSessionFactory` requiere un `DataSource`. Éste puede ser cualquier `DataSource` y debe configurarse como cualquier otra conexión a base de datos de Spring.
+
+Asumamos que tienes un mapper interface definido de la siguiente forma:
+
+```java
+public interface UserMapper {
+ @Select("SELECT * FROM users WHERE id = #{userId}")
+ User getUser(@Param("userId") String userId);
+}
+```
+
+Este interface se añade a Spring usando un `MapperFactoryBean` de la siguiente forma:
+
+```xml
+
+
+
+
+```
+
+Observa que la clase del mapper indicada **debe** ser un interface, no una implementación. En este ejemplo se usan anotaciones para especificar la SQL, pero también es posible usar un fichero de mapeo XML.
+
+Una vez configurado, puedes inyectar mappers directamente en tus beans de servicio/negocio de la misma forma que inyectarías cualquier otro bean en Spring.
+La clase `MapperFactoryBean` se encargará de obtener una `SqlSession` y de cerrarla. Si hay una transación Spring en curso, la sesión se comitará o se hará rollback cuando la transacción finalice.
+Finalmente, cualquier excepción será traducida a una excepión `DataAccessException`s de Spring.
+
+If you use the Java Configuration:
+
+```java
+@Configuration
+public class MyBatisConfig {
+ @Bean
+ public UserMapper userMapper() throws Exception {
+ SqlSessionTemplate sqlSessionTemplate = new SqlSessionTemplate(sqlSessionFactory());
+ return sqlSessionTemplate.getMapper(UserMapper.class);
+ }
+}
+```
+
+Invocar a MyBatis es sólo una línea de código:
+
+```java
+public class FooServiceImpl implements FooService {
+
+ private final UserMapper userMapper;
+
+ public FooServiceImpl(UserMapper userMapper) {
+ this.userMapper = userMapper;
+ }
+
+ public User doSomeBusinessStuff(String userId) {
+ return this.userMapper.getUser(userId);
+ }
+}
+```
diff --git a/src/site/es/markdown/index.md b/src/site/es/markdown/index.md
new file mode 100644
index 0000000000..ed37f9ad8c
--- /dev/null
+++ b/src/site/es/markdown/index.md
@@ -0,0 +1,55 @@
+
+# Introduction
+
+## ¿Qué es MyBatis-Spring?
+
+MyBatis-Spring permite integrar MyBatis con Spring. Esta librería permite que MyBatis participe en trasacciones Spring,
+se encarga de constuir mappers y `SqlSession`s e inyectarlos en otros beans, traduce excepciones de MyBatis en excepcines `DataAccessException`s de Spring y finalmente, permite construir aplicaciones libres de dependencias de MyBatis, Spring y MyBatis-Spring.
+
+## Motivación
+
+Spring version 2 sólo soporta iBATIS version 2. See hizo un intento de incluir el soporte de MyBatis 3 en Spring 3 (ver el [issue Jira](https://jira.springsource.org/browse/SPR-5991)).
+Pero desafortunadamente, el desarrollo de Spring 3 finalizó antes de que MyBatis 3 fuera liberado oficialmente.
+Dado que el equipo de Spring no quería liberar una versión basada en un producto no terminado el soporte de oficial tenía que esperar.
+Dado el interés de la comunidad en el soporte de MyBatis, la comunidad de MyBatis decidió que era el momento de unificar a los colaboradores interesados y proporcionar la integración con Spring como un sub-projecto de MyBatis en su lugar.
+
+## Requisitos
+
+Antes de comenzar con MyBatis-Spring, es muy importante que estés familiarizado con la terminología tanto de MyBatis como de Spring.
+Este documento no pretende proporcionar información de configuración básica de MyBatis o Spring.
+
+MyBatis-Spring requires following versions:
+
+| MyBatis-Spring | MyBatis | Spring Framework | Spring Batch | Java |
+| --- | --- | --- | --- | --- |
+| **2.0** | 3.5+ | 5.0+ | 4.0+ | Java 8+ |
+| **1.3** | 3.4+ | 3.2.2+ | 2.1+ | Java 6+ |
+
+## Agradecimientos
+
+Queremos agradecer a la todos los que han hecho de este proyecto una realidad (en orden alfabético):
+Eduardo Macarron, Hunter Presnall y Putthiphong Boonphong por la codificación, pruebas y documentación;
+a Andrius Juozapaitis, Giovanni Cuccu, Mike Lanyon, Raj Nagappan y Tomas Pinos por sus contribuciones;
+y a Simone Tripodi por encontrarlos a todos y traerlos al proyecto MyBatis ;) Sin ellos este proyecto no existiría.
+
+## Colabora en mejorar esta documentación...
+
+Si ves que hay alguna carencia en esta documentación, o que falta alguna característica por documentar, te animamos a que lo investigues y la documentes tu mismo!
+
+Las fuentes de este manual están disponibles en formato xdoc en el [Git del proyecto](https://github.com/mybatis/mybatis-3/tree/master/src/site). Haz un fork, cambialas y envía un pull request.
+
+Eres el mejor candidato para documentar porque los lectores de esta documentación son gente como tú!
+
+## Translations
+
+Users can read about MyBatis-Spring in the following translations:
+
+
+
+Do you want to read about MyBatis in your own native language? Fill an issue providing patches with your mother tongue documentation!
diff --git a/src/site/es/markdown/mappers.md b/src/site/es/markdown/mappers.md
new file mode 100644
index 0000000000..51dd4293d8
--- /dev/null
+++ b/src/site/es/markdown/mappers.md
@@ -0,0 +1,185 @@
+
+# Inyectar mappers
+
+En lugar de codificar DAOs (data access objects) manualmente usando la clase `SqlSessionDaoSupport` o `SqlSessionTemplate`, Mybatis-Spring puede crear un mapper thread-safe que puedes inyectar directamente en otros beans.
+
+```xml
+
+
+
+```
+
+ Una vez inyectado, el mapper está listo para se usado en la lógica de aplicación:
+
+```java
+public class FooServiceImpl implements FooService {
+
+ private final UserMapper userMapper;
+
+ public FooServiceImpl(UserMapper userMapper) {
+ this.userMapper = userMapper;
+ }
+
+ public User doSomeBusinessStuff(String userId) {
+ return this.userMapper.getUser(userId);
+ }
+}
+```
+
+Observa que no se usa la `SqlSession` ni ninguna otra referencia a MyBatis en este código. No es necesario ni siquiera crear o cerrar la sesión, MyBatis-Spring se encarga de ello.
+
+
+## Registrar un mapper
+
+La forma de registrar un mapper varía según si quieres usar la configuración XML clásica o la nueva Java Config de Spring 3.0+ (También conocida como `@Configuration`).
+
+### Con confiugración XML
+
+Un mapper se registra en Spring incluyendo un `MapperFactoryBean` en tu fichero de configuración XML, de la siguiente forma:
+
+```xml
+
+
+
+
+```
+
+Si el mapper UserMapper tiene un fichero XML de mapeo asociado el `MapperFactoryBean` lo cargará automáticamente.
+Por lo tanto no es necesario especificar dicho mapper en el fichero de configuración de MyBatis a no ser que los ficheros XML estén en una lugar distinto del classpath.
+Ver la sección de `SqlSessionFactoryBean` y la propiedad [`configLocation`](factorybean.html) para más información.
+
+El `MapperFactoryBean` requiere o un `SqlSessionFactory` o un `SqlSessionTemplate`.
+Ambos se pueden informar usando sendas propiedades `sqlSessionFactory` y `sqlSessionTemplate`.
+Si ambas propiedades han sdo informadas la `SqlSessionFactory` se ignora.
+Dado que un `SqlSessionTemplate` debe tener un session factory dicho factory se usará por el `MapperFactoryBean`.
+
+### Con Java Config
+
+```java
+@Configuration
+public class MyBatisConfig {
+ @Bean
+ public MapperFactoryBean userMapper() throws Exception {
+ MapperFactoryBean factoryBean = new MapperFactoryBean<>(UserMapper.class);
+ factoryBean.setSqlSessionFactory(sqlSessionFactory());
+ return factoryBean;
+ }
+}
+```
+
+
+## Escanear mappers
+
+No es necesario registrar los mappers uno por uno en el fichero XML de Spring. En lugar de esto, puede dejar que MyBatis-Spring los busque en tu classpath.
+
+Hay tres formas distintas de hacerlo:
+
+* Usando el elemneto ``.
+* Usando la anotación `@MapperScan`
+* Usando un fichero clásico XML de configuración de Spring y añadiendo el bean `MapperScannerConfigurer`
+
+Tango `` como `@MapperScan` son características añadidas en MyBatis-Spring 1.2.0. `@MapperScan` requiere Spring 3.1+.
+
+Since 2.0.2, mapper scanning feature support a option (`lazy-initialization`) that control lazy initialization enabled/disabled of mapper bean.
+The motivation for adding this option is supporting a lazy initialization control feature supported by Spring Boot 2.2.
+The default of this option is `false` (= not use lazy initialization).
+If developer want to use lazy initialization for mapper bean, it should be set to the `true` expressly.
+
+IMPORTANT
+If use the lazy initialization feature, the developer need to understand following limitations.
+If any of following conditions are matches, usually the lazy initialization feature cannot use on your application.
+
+* When refers to the statement of **other mapper** using ``(`@One`) and ``(`@Many`)
+* When includes to the fragment of **other mapper** using ``
+* When refers to the cache of **other mapper** using ``(`@CacheNamespaceRef`)
+* When refers to the result mapping of **other mapper** using `]]>
-
-
A continuación se muestra un ejemplo de configuración:
- El ejemplo anterior hace uso de tres cosas distintas:
-
-
-
-
sqlSessionFactory: Puedes tu propio sessionFactory, podría ser útil si quires leer de
- varias bases de datos.
-
queryId: Si el código accede a varias tablas, y tienes distintas sentencias de consulta,
- puede ser interesante usar ficheros de mapeo distintos con namespaces distintos.
- En este caso, al referirte a la query, no olvides incluir el namespace correspondiente.
-
parameterValues: Puedes pasar parametros adicionales en este mapa, el ejemplo de arriba
- usa un mapa que se construye usando una expresion SpEL y obteniendo valores del jobExecutionContext.
- Las claves del mapa puede usarse en el fichero mapper de MyBatis (por ejemplo:
- yesterday se puede usar como #{yesterday,jdbcType=TIMESTAMP}).
- Observa que el mapa y el reader se consutruyen en un solo step para que sea posible usar la expresión
- SpEL con el jobExecutionContext. Adicionalmente si los type handlers de MyBatis
- están configurados correctamente puedes pasar instancias personalizadas como los parametros del ejemplo que son
- fechas JodaTime.
-
pageSize: Si le flujo batch está configurado con un tamaño de bloque (chunk size),
- es importante pasar esta información al reader, y eso se hace mediante esta propiedad.
-
-
-
-
-
-
- Este bean es un ItemReader que lee registros de la base de datos usando un cursor.
-
-
-
- NOTA Para usar este bean necesitas al menos MyBatis 3.4.0 o superior.
-
-
-
- Ejecuta la sentencia especificada mediante la propiedad setQueryId para obtener los datos
- usando el método selectCursor().
- Al llamar al método read() se devolverá el siguiente elemento del cursor
- hasta que no quede ninguno por devolver.
-
-
-
- El reader usa una conexión separada para que la sentencia no participe en ninguna transacción creada como parte
- del proceso del step.
-
-
-
Cuando se usar un cursor puedes usar una sentencia convencional:
-
- SELECT id, name, job FROM employees ORDER BY id ASC
-]]>
-
-
A continuación se muestra un ejemplo de configuración:
- Es un ItemWriter que usa las capacidades de batch de SqlSessionTemplate para
- ejecutar sentencias batch para todos los elementos (items) proporcionados.
- El SqlSessionFactory debe configurarse con un executor de tipo BATCH.
-
-
-
- Ejecuta la sentencia indicada en la propiedad statementId cuando se invoca a write().
- Se supone que write() se invoca dentro de una transacción.
-
-
-
A continuación se muestra un ejemplo de configuración:
Converting a item that read using ItemReader to an any parameter object:
-
-
- By default behavior, the MyBatisBatchItemWriter passes a item that read using ItemReader
- (or convert by ItemProcessor) to the MyBatis(SqlSession#update()) as the parameter object.
- If you want to customize a parameter object that passes to the MyBatis, you can realize to use the itemToParameterConverter option.
- For example using itemToParameterConverter option, you can passes any objects other than the item object to the MyBatis.
- Follows below a sample:
-
-
-
- At first, you create a custom converter class (or factory method). The following sample uses a factory method.
-
Escribiendo en distintas tablas usando composite writers (con algunos condicionantes):
-
-
Esta técnica sólo puede usarse con MyBatis 3.2+, por que había un
- error
- en las versiones anteriores que hacían que el writer funcionara de forma incorrecta.
-
-
-
Si el batch necesita escribir datos complejos, como registros con asociaciones, o en distintas bases de datos,
- entonces es necesario sortear el problema de que los insert statements solo pueden escribir en una tabla.
- Para conseguir esto debes preparar un Item para que sea escrito por el writer. Sin embargo,
- dependiendo de las circunstancias puede ser interesante usar la siguiente técnica.
- El truco siguiente funciona con items con asociaciones simples o con tablas no relacionadas.
-
-
-
- Elabora el item de forma que contenta todos los resgistros distintos.
- Supon que para cada item hay una Interaction que tiene una asociación
- InteractionMetadata y dos filas no asociadas VisitorInteraction and
- CustomerInteraction. El objeto contenedor será de la siguiente forma:
-
-
-
-
-
- Entonces en la configuración de spring habrá un CompositeItemWriter que usará writers
- delegados configurados especificamente para cada tipo de registro. Fijate que el InteractionMetadata
- es una asociacióin en el ejemplo por lo que debe ser escrita antes para que la Interaction pueda recibir la clave
- generada.
-
Cada writer delegados se configura como sea necesario, por ejemplo para Interaction y
- InteractionMetadata:
-
-
-
-]]>
-
-
Al igual que con el reader el statementId puede hacer referencia al statement con un namespace como prefijo.
-
-
Ahora es debe elaborarse el fichero de mapeo para cada tipo de registro, de la siguiente forma:
-
-
-
-
-
-
-]]>
-
-
- Lo que sucede es que primeramente se llamará a insertInteractionMetadata, y la sentencia de update
- está configurada para devolver las claves autogeneradas (keyProperty y keyColumn).
- Una vez que el InteractionMetadata se ha almacenado por esta sentencia se puede ejecutar la siguiente para
- escribir el objeto padre Interaction mediante insertInteraction.
-
-
-
- Sin embargo, ten en cuenta que los drivers JDBC se comportan distinto en este aspecto. A la fecha en la que se escribe esto
- el driver H2 1.3.168 solo devuelve el último ID incluso en modo BATCH (see org.h2.jdbc.JdbcStatement#getGeneratedKeys),
- mientras que el driver JDBC de MySQL se comporta como es de esperar y devuelve todos los IDs.
-
- En MyBatis una SqlSessionFactory se crea mediante la clase
- SqlSessionFactoryBuilder. En MyBatis-Spring se usa la clase
- SqlSessionFactoryBean en su lugar.
-
-
-
-
- Para crear un factory bean, pon lo siguiente en el fichero XML de configuración de Spring:
-
-
-
-]]>
-
- La clase SqlSessionFactoryBean implementa el interfaz FactoryBean
- (see the Spring documentation(Core Technologies -Customizing instantiation logic with a FactoryBean-)).
- Lo cual significa que el bean que crea Spring
- en última instancia no es un SqlSessionFactoryBean en si mismo, sino el
- objeto que la factoria devuelve como resultado de la llamada al método
- getObject(). En este caso, Spring creará un bean
- SqlSessionFactory durante el arranque de la aplicación y lo guardará bajo el nombre
- sqlSessionFactory. En Java, el código equivalente sería:
-
-
-
-
-
- Normalmente no necesitarás utilizar directamente un SqlSessionFactoryBean
- o su correspondiente SqlSessionFactory directly.
- En su lugar, la factoría se utilizará para ser inyectada en MapperFactoryBeans o
- DAOs que extiendan de SqlSessionDaoSupport.
-
-
-
-
-
-
- La clase SqlSessionFactory solo tiene una propiedad obligatoria, un DataSource.
- Puede ser cualquier DataSource y se puede configurar como cualquier otra conexión a base de daots de Spring.
-
-
-
- Una propiedad muy común es la configLocation que se utiliza para indicar la localización del fichero de configuración
- XML de MyBatis. Normalmente solo es necesario dicho fichero si se requiere cambiar los valores por defecto de las secciones
- <settings> o <typeAliases>.
-
-
-
- Es importante saber que este fichero de configuración no tiene por qué ser un fichero de configuración de MyBatis completo.
- Concretamente, los environments, dataSources y transactionManagers serán ignorados.
- SqlSessionFactoryBean crea su propio Environment de MyBatis con los valores configurados tal y como se requieren.
-
-
-
- Otro motivo para necesitar un fichero de configuración es que los ficheros de mapeo XML no estén en el mismo lugar del classpath
- que los mapper interfaces. En este caso hay dos opciones. La primera es especificar manualmente el classpath de los ficheros XML
- usando la sección <mappers> del fichero de configuración de MyBatis. La segunda opción es usar la propiedad
- mapperLocations del factory bean.
-
-
-
- La propiedad mapperLocations recibe una lista de localizaciones de recursos. Se utiliza para indicar la ubicación de los
- ficheros de mapeo XML de MyBatis. El valor puede contener un patron tipo Ant para cargar todos los ficheros de un directorio o
- buscar de forma recursiva en todos los paths desde una localización base. Por ejemplo:
-
-
-
-
-
-]]>
-
-
- Esto cargaría todos los ficheros de mapeo XML en el paquete sample.config.mappers y sus subpaquetes.
-
-
-
- Otra propiedad que puede ser necesaria en un entorno con transacciones gestionadas por contenedor es la
- transactionFactoryClass. Lee la sección de transacciones para obtener más detalles.
-
-
-
- En caso de usar la característica multi-db necesitarás informar la propiedad databaseIdProvider
- de la siguiente forma:
-
- NOTE
- Since 1.3.0, configuration property has been added.
- It can be specified a Configuration instance directly without MyBatis XML configuration file.
- For example:
-
- Para usar MyBatis con Spring necesitas definir al menos dos cosas en tu contexto Spring: una
- SqlSessionFactory y al menos un mapper interface.
-
-
-
- En MyBatis-Spring se usa un
- SqlSessionFactoryBean
- para crear una
- SqlSessionFactory
- . Para configurar la factory bean pon lo siguiente en tu
- fichero de configuración de Spring:
-
-
-
-
-]]>
-
-
-
-
- Observa que la SqlSessionFactory
- requiere un
- DataSource
- . Éste puede ser cualquier
- DataSource
- y debe configurarse como cualquier otra conexión a base de datos
- de Spring.
-
-
-
- Asumamos que tienes un mapper interface definido de la siguiente forma:
-
-
-
-
- Este interface se añade a Spring usando un
- MapperFactoryBean
- de la siguiente forma:
-
-
-
-
-]]>
-
-
- Observa que la clase del mapper indicada
- debe
- ser un interface, no una implementación. En este ejemplo se usan
- anotaciones para especificar la SQL, pero también es posible
- usar un fichero de mapeo XML.
-
-
-
- Una vez configurado, puedes inyectar mappers directamente en tus
- beans de servicio/negocio de la misma forma que inyectarías cualquier
- otro bean en Spring.
- La clase MapperFactoryBean se encargará de obtener
- una SqlSession y de cerrarla. Si hay una transación Spring
- en curso, la sesión se comitará o se hará rollback cuando la transacción
- finalice. Finalmente, cualquier excepción será traducida a una excepión
- DataAccessExceptions de Spring.
-
-
-
- If you use the Java Configuration:
-
-
-
-
-
- Invocar a MyBatis es sólo una línea de código:
-
- MyBatis-Spring permite integrar MyBatis con Spring.
- Esta librería permite que MyBatis participe en trasacciones Spring, se encarga de constuir
- mappers y SqlSessions e inyectarlos en otros beans, traduce excepciones
- de MyBatis en excepcines DataAccessExceptions de Spring y finalmente,
- permite construir aplicaciones libres de dependencias de MyBatis, Spring y MyBatis-Spring.
-
-
-
-
-
- Spring version 2 sólo soporta iBATIS version 2. See hizo un intento de incluir el soporte
- de MyBatis 3 en Spring 3 (ver el issue Jira).
- Pero desafortunadamente, el desarrollo de Spring 3 finalizó antes de que MyBatis 3 fuera liberado oficialmente.
- Dado que el equipo de Spring no quería liberar una versión basada en un producto no terminado el soporte de
- oficial tenía que esperar. Dado el interés de la comunidad en el soporte de MyBatis,
- la comunidad de MyBatis decidió que era el momento de unificar a los colaboradores interesados
- y proporcionar la integración con Spring como un sub-projecto de MyBatis en su lugar.
-
-
-
-
-
- Antes de comenzar con MyBatis-Spring, es muy importante que estés familiarizado con la terminología tanto de
- MyBatis como de Spring. Este documento no pretende proporcionar información de configuración básica de
- MyBatis o Spring.
-
-
- MyBatis-Spring requires following versions:
-
-
-
-
-
- MyBatis-Spring
-
-
- MyBatis
-
-
- Spring Framework
-
-
- Spring Batch
-
-
- Java
-
-
-
-
-
-
- 2.0
-
-
- 3.5+
-
-
- 5.0+
-
-
- 4.0+
-
-
- Java 8+
-
-
-
-
- 1.3
-
-
- 3.4+
-
-
- 3.2.2+
-
-
- 2.1+
-
-
- Java 6+
-
-
-
-
-
-
-
-
- Queremos agradecer a la todos los que han hecho de este proyecto una realidad (en orden alfabético):
- Eduardo Macarron, Hunter Presnall y Putthiphong Boonphong por la codificación, pruebas y documentación;
- a Andrius Juozapaitis, Giovanni Cuccu, Mike Lanyon, Raj Nagappan y Tomas Pinos
- por sus contribuciones; y a Simone Tripodi por encontrarlos a todos y traerlos al proyecto MyBatis ;)
- Sin ellos este proyecto no existiría.
-
-
-
-
-
- Si ves que hay alguna carencia en esta documentación, o que falta alguna característica por documentar,
- te animamos a que lo investigues y la documentes tu mismo!
-
-
- Las fuentes de este manual están disponibles en formato xdoc en el
- Git del proyecto.
- Haz un fork, cambialas y envía un pull request.
-
-
- Eres el mejor candidato para documentar porque los lectores de esta documentación son gente como tú!
-
-
-
-
Users can read about MyBatis-Spring in the following translations:
- En lugar de codificar DAOs (data access objects) manualmente usando la clase
- SqlSessionDaoSupport o SqlSessionTemplate, Mybatis-Spring
- puede crear un mapper thread-safe que puedes inyectar directamente en otros beans.
-
-
-
-
-]]>
-
-
- Una vez inyectado, el mapper está listo para se usado en la lógica de aplicación:
-
-
-
- Observa que no se usa la SqlSession ni ninguna otra referencia a MyBatis en este código.
- No es necesario ni siquiera crear o cerrar la sesión, MyBatis-Spring se encarga de ello.
-
-
-
-
-
- La forma de registrar un mapper varía según si quieres usar la configuración XML clásica o la nueva Java Config de Spring 3.0+
- (También conocida como @Configuration).
-
-
Con confiugración XML
-
-
- Un mapper se registra en Spring incluyendo un MapperFactoryBean en tu fichero de configuración XML, de la siguiente forma:
-
-
-
-
-]]>
-
-
- Si el mapper UserMapper tiene un fichero XML de mapeo asociado el MapperFactoryBean
- lo cargará automáticamente. Por lo tanto no es necesario especificar dicho mapper en el fichero
- de configuración de MyBatis a no ser que los ficheros XML estén en una lugar distinto del classpath.
- Ver la sección de SqlSessionFactoryBean y la propiedad
- configLocation
- para más información.
-
-
-
- El MapperFactoryBean requiere o un
- SqlSessionFactory o un SqlSessionTemplate.
- Ambos se pueden informar usando sendas propiedades sqlSessionFactory y
- sqlSessionTemplate.
- Si ambas propiedades han sdo informadas la SqlSessionFactory se ignora.
- Dado que un SqlSessionTemplate debe tener un session factory
- dicho factory se usará por el MapperFactoryBean.
-
- No es necesario registrar los mappers uno por uno en el fichero XML de Spring.
- En lugar de esto, puede dejar que MyBatis-Spring los busque en tu classpath.
-
-
-
- Hay tres formas distintas de hacerlo:
-
-
-
Usando el elemneto <mybatis:scan/>.
-
Usando la anotación @MapperScan
-
Usando un fichero clásico XML de configuración de Spring y añadiendo el bean MapperScannerConfigurer
-
-
-
Tango <mybatis:scan/> como @MapperScan son características añadidas en MyBatis-Spring 1.2.0.
- @MapperScan requiere Spring 3.1+.
-
-
- Since 2.0.2, mapper scanning feature support a option (lazy-initialization)
- that control lazy initialization enabled/disabled of mapper bean.
- The motivation for adding this option is supporting a lazy initialization control feature supported by Spring Boot 2.2.
- The default of this option is false (= not use lazy initialization).
- If developer want to use lazy initialization for mapper bean, it should be set to the true expressly.
-
-
- IMPORTANT If use the lazy initialization feature,
- the developer need to understand following limitations. If any of following conditions are matches,
- usually the lazy initialization feature cannot use on your application.
-
-
-
When refers to the statement of other mapper using ]]>(@One) and ]]>(@Many)
-
When includes to the fragment of other mapper using ]]>
-
When refers to the cache of other mapper using ]]>(@CacheNamespaceRef)
-
When refers to the result mapping of other mapper using ]]>(@ResultMap)
-
-
-
- NOTE However, It become possible to use it by simultaneously initializing dependent beans using @DependsOn(Spring's feature) as follow:
-
-
-
-
-
- Since 2.0.6, the develop become can specified scope of mapper using mapper scanning feature option(default-scope)
- and scope annotation(@Scope, @RefreshScope, etc ...).
- The motivation for adding this option is supporting the refresh scope provided by the Spring Cloud.
- The default of this option is empty (= equiv to specify the singleton scope).
- The default-scope apply to the mapper bean(MapperFactoryBean) when scope of scanned bean definition
- is singleton(default scope) and create a scoped proxy bean for scanned mapper when final scope is not singleton.
-
-
-
<mybatis:scan/>
-
-
- El elemento XML <mybatis:scan/> busca mappers de una forma muy similar a cómo
- <context:component-scan/> busca beans.
-
-
-
A continuación se muestra un fichero XML de configuración:
-
-
-
-
-
-
-
-]]>
-
-
- La propiedad basePackage te permite indicar el paquete base donde residen tus mappers.
- Puedes indicar más de un paquete usando un punto y coma o una coma como separador. Los mappers serán buscados
- de forma recursiva comenzando en el/los paquetes especificados.
-
-
-
- Fíjate que no es necesario indicar una SqlSessionFactory o
- SqlSessionTemplate porque el <mybatis:scan/>
- creará MapperFactoryBeans que pueden ser autowired. Pero si usas más de un DataSource
- el autowire puede que no te funcione. En este caso puedes usar las propiedades factory-ref or
- template-ref para indicar los beans correctos a utilizar.
-
-
-
- <mybatis:scan/> soporta el filtrado de mappers mediante una interfaz marcador o una anotación.
- La propiedad annotation especifica la anotación que se debe buscar.
- La propiedad marker-interface especifica la interfaz a buscar.
- Si se indican ambas se añadirán todos los mappers que cumplan cualquier criterio.
- Por defecto ambas propiedades son null asi que todos los interfaces de los paquetes base serán cargados como mappers.
-
-
-
- Los mappers descubiertos serán nombrados usando la estratégia de nombres por defecto de Spring para los componentes
- autodetectados (see the Spring reference document(Core Technologies -Naming autodetected components-)).
- Es decir, si no se encuentra ninguna anotación, se usará el nombre no cualificado sin capitalizar del mapper.
- Pero si se encuentra una anotación @Component o JSR-330 @Named se obtendrá el nombre de dicha anotación.
- Fíjate que puedes usar como valor de la annotation el valor org.springframework.stereotype.Component,
- javax.inject.Named (if you have JSE 6) o una anotación propia
- (que debe ser a su vez anotada) de forma que la anotación hará las veces de localizador y de proveedor de nombre.
-
-
-
- NOTE<context:component-scan/>
- no puede encontrar y registrar mappers. Los mappers son interfaces y, para poderlos registrar en Spring,
- el scanner deben conocer cómo crear un MapperFactoryBean para cada interfaz encontrado.
-
-
-
@MapperScan
-
-
- Si usas la Java Configuration de Spring (@Configuration) posiblemente prefieras usar
- @MapperScan en lugar de <mybatis:scan/>.
-
-
-
La anotación @MapperScan se usa de la siguiente forma:
-
-
-
-
- La anotación fucniona exactamente igual que <mybatis:scan/> que hemos visto en la sección anterior.
- También te permite especificar un interfaz marcador o una anotación mediante sus propiedades
- markerInterface y annotationClass.
- Tambien puedes indicar una SqlSessionFactory o un SqlSessionTemplate específicos
- mediante las propiedades sqlSessionFactory y sqlSessionTemplate.
-
-
-
- NOTE Since 2.0.4, If basePackageClasses or basePackages are not defined, scanning will occur from the package of the class that declares this annotation.
-
-
-
MapperScannerConfigurer
-
-
- MapperScannerConfigurer es un BeanDefinitionRegistryPostProcessor
- que se puede incluir como un bean normal en el fichero clásico XML de configuración de Spring.
- Para configurar un MapperScannerConfigurer añade lo siguiente al fichero de configuración de Spring:
-
-
-
-]]>
-
-
- Si quieres indicar un sqlSessionFactory o un sqlSessionTemplate
- observa que se requeiren los nombres de los beans y no sus referencias
- por ello se usa el atributo value en lugar del habitual ref:
-
- NOTE
- See JPetstore 6 demo to know about how to use Spring with a full web application server.
-
-
-
- You can check out sample code from the MyBatis-Spring repo:
-
-
- Any of the samples can be run with JUnit 5.
-
-
- The sample code shows a typical design where a transactional service gets domain objects from a data access layer.
-
-
- FooService.java acts as the service:
-
-
-
- It is a transactional bean, so when the method is called, the transaction is started
- and the transaction is committed when the method ends without throwing an uncaught exception.
- Notice that transactional behaviour is configured with the
- @Transactional
- attribute. This is not required; any other way provided by Spring can be used to demarcate
- your transactions.
-
-
- This service calls a data access layer built with MyBatis. This layer
- consists on a just an interface UserMapper.java
- that will be used with a dynamic proxy built by MyBatis at
- runtime and injected into the service by Spring.
-
-
-
- Note that, for the sake of simplicity we used the interface UserMapper.java for the DAO scenario
- where a DAO is built with an interface and a implementation though in this case it would have been more
- adequate to use an interface called UserDao.java instead.
-
-
- We will see different ways to find the mapper interface, register it to Spring and inject it into the service bean:
-
-
-
Scenarios
-
-
-
Sample test
-
Description
-
-
-
-
-
- SampleMapperTest.java
-
-
- Shows you the base configuration based on a MapperFactoryBean
- that will dynamically build an implementation for UserMapper
-
-
-
-
- SampleScannerTest.java
-
-
- Shows how to use the MapperScannerConfigurer so all the mappers in a project are autodiscovered.
-
-
-
-
- SampleSqlSessionTest.java
-
-
- Shows how to hand code a DAO using a Spring managed SqlSession
- and providing your own implementation UserDaoImpl.java.
-
-
-
-
- SampleEnableTest
-
-
- Shows how to use Spring's @Configuration with the @MapperScann annotation so
- mappers are autodiscovered.
-
-
-
-
- SampleNamespaceTest
-
-
- Shows how to use the custom MyBatis XML namespace.
-
-
-
-
- SampleJavaConfigTest.java
-
-
- Shows how to use Spring's @Configuration to create MyBatis beans manually.
-
-
-
-
- SampleJobJavaConfigTest.java
-
-
- Shows how to use ItemReader and ItemWriter on Spring Batch using Java Configuration.
-
-
-
-
- SampleJobXmlConfigTest.java
-
-
- Shows how to use ItemReader and ItemWriter on Spring Batch using XML Configuration.
-
-
-
-
-
- Please take a look at the different applicationContext.xml files to see MyBatis-Spring in action.
-
- En MyBatis usas un SqlSessionFactory para crear un SqlSession.
- Una vez tienes una sesión, la usas para ejecutar tus mapped statements, hacer commit o rollback y finalmente
- cuando no la necesitas la cierras. Con MyBatis-Spring no es necesario que utilices la SqlSessionFactory
- directamente porque puedes inyectar en tus beans una SqlSession thread safe (reentrante)
- que hará de forma automática el commit, rollback y se cerrará conforme a la configuración de la transacción en Spring.
-
-
-
-
- El SqlSessionTemplate is el corazón de MyBatis-Spring.
- Implementa SqlSession y está pensado para que sea directamente reemplazable por cualquier código
- que actualmente use SqlSession.
- SqlSessionTemplate es thread safe y se puede compartir por más de un DAO.
-
-
-
- Cuando se invoca a cualquier método SQL, incluyendo cualquier método de un mapper devuelto por
- getMapper(), el SqlSessionTemplate
- se asegurará de que la SqlSession utilizada es la asociada con la transacción Spring en curso.
- Adicionalmente, se encarga de gestionar su ciclo de vida, incluyendo su cierre, commit o rollback de la sesión si fuera necesario.
-
-
-
- Se debe usar siempre un SqlSessionTemplate en lugar de la implementación de sesión
- por default MyBatis: DefaultSqlSession
- porque el template puede participar en transacciones Spring y es thread safe con lo que puede ser inyectado
- en múltiples mappers (proxies). Cambiar de uno a otro puede crear problemas de integridad de datos.
-
-
-
- El SqlSessionTemplate puede construirse usando un SqlSessionFactory como argumento de su constructor.
-
-
-
-]]>
-
-
-
-
- Este bean puede ser inyectado directamente en tus DAOs. Necesitarás una propiedad
- SqlSession en tu bean como se muestra a continuación:
-
-
-
- E inyectar el SqlSessionTemplate de la siguiente forma:
-
-
-
-]]>
-
-
- El SqlSessionTemplate tiene también un constructor que recibe como parámetro
- un ExecutorType. Esto permite construir, por ejemplo,
- una SqlSession batch utilizando la siguiente configuracíon de Spring:
-
-
-
-
-]]>
-
-
-
-
- Ahora todos tus statements se ejecutarán en batch de forma que puedes programar lo siguiente:
-
- users) {
- for (User user : users) {
- sqlSession.insert("org.mybatis.spring.sample.mapper.UserMapper.insertUser", user);
- }
-}]]>
-
-
- Fijate que esta configuración si el método de ejecución deseado es distinto del establecido por defecto
- en el SqlSessionFactory.
-
-
-
- La contrapartida de esto es que no es posible cambiar el méodo de ejecución dentro de una transacción.
- Por tanto asegurate que o bien todas las llamadas a un SqlSessionTemplates con distinto método de ejecución
- se ejecutan en una transacción diferente (p.ej: with PROPAGATION_REQUIRES_NEW) o completamente fuera de la transacción.
-
-
-
-
-
- SqlSessionDaoSupport es una clase de soporte abstracta que proporciona un SqlSession.
- Llamando a getSqlSession() obtiene un SqlSessionTemplate
- que puedes utilizar para ejecutar métodos SQL, como sigue:
-
-
-
- Normalmente es preferible usar un MapperFactoryBean a esta clase dao que no requeire código extra.
- Pero esta clase es de utilidad cuando es necesario hacer algún otro tipo de trabajo no-MyBatis en el DAO y se necesitan
- clases concretas.
-
-
-
- SqlSessionDaoSupport que se informe la propiedad
- sqlSessionFactory o la sqlSessionTemplate.
- Si se informan ambas propiedades, la sqlSessionFactory se ignora.
-
-
-
- Asumiendo una clase UserDaoImpl que extiende
- SqlSessionDaoSupport, se puede configurar Spring de la siguiente forma:
-
- Uno de los principales motivos para usar MyBatis-Spring es que permite que MyBatis participe en transacciones
- de Spring. En lugar de haber creado un TransactionManager especifico para MyBatis, MyBatis-Spring aprovecha
- el existente DataSourceTransactionManager de Spring.
-
-
- Una vez que has configurado un TransactionManager in Spring puedes configurar tus transacciones en Spring como siempre.
- Tanto las anotaciones @Transactional como las configuraciones de tipo AOP se soportan.
- Se creará una sola instancia de SqlSession para toda la transacción.
- Se hará commit o rollback de esta sesión cuando la transacción finalice.
-
-
- MyBatis-Spring se encargará de gestionar las transacciones de forma transparente una vez se hayan configurado. No es necesario
- incluir código adicional en tus clases.
-
-
-
-
- Para habilitar las transacciones Spring, simplemente crea un DataSourceTransactionManager en tu fichero de configuración:
-
-
-
-]]>
-
-
-
-
- El DataSource especificado puede ser cualquier DataSource JDBC que usarías normalmente con Spring.
- Esto incluye connection pools y DataSources obtenidos mediante JNDI.
-
-
- Fijate que el DataSource especificado en el transaction manager debe ser el mismo que el que se use para
- crear el SqlSessionFactoryBean o la gestión de transacciones no funcionará.
-
-
-
-
-
- Si estás usando un contenedor JEE y quiere que spring participe en las transacciones gestionadas por contenedor (CMT), entonces debes
- configurar un JtaTransactionManager en Spring o alguna de sus clases específicas de cada contenedor.
- Lo más sencillo es utilizar el namespace tx de Spring or the JtaTransactionManagerFactoryBean:
-
- ]]>
-
-
-
-
- Con esta configuración, MyBatis se comportará como cualquier otro recurso configurado con CMT.
- Spring utilizará cualquier transacción CMT existente y asociará la SqlSession a ella.
- Si no no hay ninguna transacción previa pero se necesita una en base a la configuración de la transacción, Spring creará
- una transacción gestionada por contenedor nueva.
-
-
- Fijate que si quieres usar transacciones CMT pero no quieres utilizar la gestión de transacciones de Spring
- no debes configurar ningun transaction manager en Spring y debes
- configurar el SqlSessionFactoryBean para que use la clase ManagedTransactionFactory de MyBatis de la siguiente forma:
-
-
-
-
-
-
-]]>
-
-
-
-
-
-
-
- La interfaz SqlSession proporciona métodos especificos para gestionar la transacción.
- Pero al usar MyBatis-Spring en tus beans se inyectará una SqlSession o un mapper gestionados por Spring.
- Esto significa que Spring siempre gestionará tus transacciones.
-
-
- No puedes llamar a los métodos SqlSession.commit(), SqlSession.rollback()
- o SqlSession.close() en una SqlSession gestionada por Spring.
- Si lo intentas obtendrás una excepción UnsupportedOperationException.
- Además, estos métodos no se exponen en los mapper interfaces.
-
-
- Independientemente de el estado del autocommit de la conexión JDBC cualquier llamada
- a un metodo SQL de SqlSession fuera de una transacción Spring será automaticamente commitada.
-
- With MyBatis-Spring, you can continue to directly use the MyBatis API.
- Simply create an SqlSessionFactory in Spring using
- SqlSessionFactoryBean and use the factory in your code.
-
-
-
-
- Use this option with care because wrong usage may produce runtime errors or
- worse, data integrity problems. Be aware of the following caveats with direct API usage:
-
-
-
-
- It will not participate in any Spring transactions.
-
-
-
-
- If the SqlSession is using a DataSource
- that is also being used by a Spring transaction manager and there is currently
- a transaction in progress, this code will throw an exception.
-
-
-
-
- MyBatis' DefaultSqlSession is not thread safe. If you
- inject it in your beans you will get errors.
-
-
-
-
- Mappers created using DefaultSqlSession are not thread safe either.
- If you inject them it in your beans you will get errors.
-
-
-
-
- You must make sure that your SqlSessions
- are always closed in a finally block.
-
-
-
-
-
-
diff --git a/src/site/ja/markdown/README.md b/src/site/ja/markdown/README.md
new file mode 100644
index 0000000000..3280241e0c
--- /dev/null
+++ b/src/site/ja/markdown/README.md
@@ -0,0 +1,18 @@
+# 目次
+
+このページはGitHub上でドキュメントの目次を表示するため用意したものです。
+
+> **NOTE:**
+>
+> リンクはmaven-site-pluginでHTMLに変換することを前提に指定されているため、GitHubでのレンダリングではリンク切れになっているものがあります。
+
+* [イントロダクション](./index.md)
+* [スタートガイド](./getting-started.md)
+* [SqlSessionFactoryBean](./factorybean.md)
+* [トランザクション](./transactions.md)
+* [SqlSessionの利用](./sqlsession.md)
+* [Mapperの注入](./mappers.md)
+* [Spring Boot](./boot.md)
+* [MyBatis APIの利用](./using-api.md)
+* [Spring Batch](./batch.md)
+* [サンプルコード](./sample.md)
diff --git a/src/site/ja/markdown/batch.md b/src/site/ja/markdown/batch.md
new file mode 100644
index 0000000000..0c0d55257e
--- /dev/null
+++ b/src/site/ja/markdown/batch.md
@@ -0,0 +1,344 @@
+
+# Spring Batch
+
+MyBatis-Spring 1.1.0 以降では、 Spring Batch を構築するための Bean として `MyBatisPagingItemReader` 、 `MyBatisCursorItemReader` 、 `MyBatisBatchItemWriter` が用意されています。
+また、2.0.0 以降では、Java Configuration をサポートするための Builder クラスとして `MyBatisPagingItemReaderBuilder` 、 `MyBatisCursorItemReaderBuilder` 、 `MyBatisBatchItemWriterBuilder` が用意されています。
+
+NOTE
+ここで扱うのは [Spring Batch](http://static.springsource.org/spring-batch/) を使ったバッチ処理で、MyBatis の [`SqlSession`](sqlsession.html) を利用したバッチ処理ではありません。
+
+## MyBatisPagingItemReader
+
+この Bean は、MyBatis を利用してデータベースからページ単位でレコードを読み出す `ItemReader` です。
+
+結果を取得する際は `setQueryId` プロパティで指定したクエリが実行されます。1ページあたりの件数は setPageSize プロパティで指定することができます。
+`read()` メソッドが呼び出されると、必要に応じて追加のページを取得するクエリが実行されます。
+実行されるクエリでは、Reader によって提供されるページング処理を行う際に必要となるパラメーターを使って期待される結果を返す SQL 文を記述することになります(実際の SQL 文は方言依存です)。
+提供されるパラメーターは次の通りです。
+
+* `_page`: 取得対象のページ番号(最初のページは0
+* `_pagesize`: 1ページあたりの件数
+* `_skiprows`: `_page` と `_pagesize` の積
+
+これらのパラメーターは、例えば次のように SELECT 文中で指定することができます。
+
+```xml
+
+```
+
+設定例:
+
+```xml
+
+
+
+
+```
+
+```java
+@Configuration
+public class BatchAppConfig {
+ @Bean
+ public MyBatisPagingItemReader reader() {
+ return new MyBatisPagingItemReaderBuilder()
+ .sqlSessionFactory(sqlSessionFactory())
+ .queryId("com.my.name.space.batch.EmployeeMapper.getEmployee")
+ .build();
+ }
+}
+```
+
+**さらに複雑な例:**
+
+```xml
+
+```
+```xml
+
+
+
+
+
+
+```
+
+```java
+@Configuration
+public class BatchAppConfig {
+ @StepScope
+ @Bean
+ public MyBatisPagingItemReader dateBasedCriteriaReader(
+ @Value("#{@datesParameters}") Map datesParameters) throws Exception {
+ return new MyBatisPagingItemReaderBuilder()
+ .sqlSessionFactory(batchReadingSessionFactory())
+ .queryId("com.my.name.space.batch.ExampleMapper.queryUserInteractionsOnSpecificTimeSlot")
+ .parameterValues(datesParameters)
+ .pageSize(200)
+ .build();
+ }
+
+ @StepScope
+ @Bean
+ public Map datesParameters(
+ @Value("#{jobExecutionContext['EXTRACTION_START_DATE']}") LocalDate yesterday,
+ @Value("#{jobExecutionContext['TODAY_DATE']}") LocalDate today,
+ @Value("#{jobExecutionContext['FIRST_DAY_OF_THE_MONTH_DATE']}") LocalDate firstDayOfTheMonth,
+ @Value("#{jobExecutionContext['FIRST_DAY_OF_THE_PREVIOUS_MONTH_DATE']}") LocalDate firstDayOfThePreviousMonth) {
+ Map map = new HashMap<>();
+ map.put("yesterday", yesterday);
+ map.put("today", today);
+ map.put("first_day_of_the_month", firstDayOfTheMonth);
+ map.put("first_day_of_the_previous_month", firstDayOfThePreviousMonth);
+ return map;
+ }
+}
+```
+
+The previous example makes use of a few different things:
+
+* `sqlSessionFactory`: あなた自身の sessionFactory を reader に指定することができます。複数のデータベースから読み取る場合は有用かも知れません。
+* `queryId`: レコード取得時に実行されるクエリの ID を指定します。異なるネームスペースに属するクエリを指定する場合はネームスペースの指定を忘れないようにしてください。
+* `parameterValues`: クエリ実行時に使用する追加のパラメーターを Map 形式で渡すことができます。上の例では Spring が `jobExecutionContext` から SpEL 式を使って取得した値をもとに構築した `Map` を指定しています。
+ MyBatis の Mapper ファイルでは `Map` のキーをパラメーター名として指定します(例: *yesterday* を指定する場合は `#{yesterday,jdbcType=TIMESTAMP}` のように指定します)。
+ `jobExecutionContext` と Spring EL 式を利用するため、`Map` および `Reader` はどちらも `step` スコープ内で構築されているという点に注意してください。
+ また、MyBatis の `TypeHandler` が正しく設定されていれば、この例のように JodaTime のようなカスタムのインスタンスを引数として渡すこともできます。
+* `pageSize`: バッチ処理のチャンクサイズを指定します。
+
+## MyBatisCursorItemReader
+
+This bean is an `ItemReader` that reads records from a database using a cursor.
+
+NOTE
+To use this bean you need at least MyBatis 3.4.0 or a newer version.
+
+It executes the query specified as the `setQueryId` property to retrieve requested data by using the method `selectCursor()`.
+Each time a `read()` method is called it will return the next element of the cursor until no more elements are left.
+
+The reader will use a separate connection so the select statement does no participate in any transactions created as part of the step processing.
+
+When using the cursor you can just execute a regular query:
+
+```xml
+
+```
+
+Follows below a sample configuration snippet:
+
+```xml
+
+
+
+
+```
+
+```java
+@Configuration
+public class BatchAppConfig {
+ @Bean
+ public MyBatisCursorItemReader reader() {
+ return new MyBatisCursorItemReaderBuilder()
+ .sqlSessionFactory(sqlSessionFactory())
+ .queryId("com.my.name.space.batch.EmployeeMapper.getEmployee")
+ .build();
+ }
+}
+```
+
+## MyBatisBatchItemWriter
+
+`SqlSessionTemplate` のバッチ機能を使って渡された一連のアイテムを処理する `ItemWriter` です。 `SqlSessionFactory` は `ExecutorType.BATCH` を使って設定する必要があります。
+
+`write()` の呼び出し時に実行するステートメントの ID を指定しておく必要があります。 `write()` はトランザクション内で呼び出されることを前提としています。
+
+設定例:
+
+```xml
+
+
+
+
+```
+
+```java
+@Configuration
+public class BatchAppConfig {
+ @Bean
+ public MyBatisBatchItemWriter writer() {
+ return new MyBatisBatchItemWriterBuilder()
+ .sqlSessionFactory(sqlSessionFactory())
+ .statementId("com.my.name.space.batch.EmployeeMapper.updateEmployee")
+ .build();
+ }
+}
+```
+
+**`ItemReader`を使用して読み込んだアイテムを任意のパラメータオブジェクトへ変換する**
+
+デフォルトの動作では、`MyBatisBatchItemWriter` は `ItemReader` を使用して読みこんだアイテム (または `ItemProcessor` によって変換したアイテム)を、そのままMyBatis(`SqlSession` の `update` メソッド)のパラメーターオブジェクトとして渡します。
+もしMyBatisへ渡すパラメーターオブジェクトをカスタマイズしたい場合は、`itemToParameterConverter` オプションを利用することで実現するすることができます。
+たとえば、`itemToParameterConverter` オプションを使用すると、 アイテムオブジェクト以外のオブジェクトをMyBatisへ渡すことができます。
+以下にサンプルを示します。
+
+まず、任意のパラメータオブジェクトに変換するためのコンバータクラス(またはファクトリメソッド)を作成します。以下のサンプルではファクトリメソッドを使用します。
+
+```java
+public class ItemToParameterMapConverters {
+ public static Converter> createItemToParameterMapConverter(String operationBy, LocalDateTime operationAt) {
+ return item -> {
+ Map parameter = new HashMap<>();
+ parameter.put("item", item);
+ parameter.put("operationBy", operationBy);
+ parameter.put("operationAt", operationAt);
+ return parameter;
+ };
+ }
+}
+```
+
+つぎに, SQLマッピングを書きます。
+
+```xml
+
+```
+
+さいごに, `MyBatisBatchItemWriter` の設定を行います。
+
+```java
+@Configuration
+public class BatchAppConfig {
+ @Bean
+ public MyBatisBatchItemWriter writer() throws Exception {
+ return new MyBatisBatchItemWriterBuilder()
+ .sqlSessionFactory(sqlSessionFactory())
+ .statementId("org.mybatis.spring.sample.mapper.PersonMapper.createPerson")
+ .itemToParameterConverter(createItemToParameterMapConverter("batch_java_config_user", LocalDateTime.now()))
+ .build();
+ }
+}
+```
+
+```xml
+
+
+
+
+
+
+
+
+
+
+```
+
+**Composite Writer を使って複数のテーブルに書き込む(注意事項あり)**
+
+このテクニックを使うには MyBatis 3.2 以降が必要です。それ以前のバージョンには [問題](http://code.google.com/p/mybatis/issues/detail?id=741) があるため、Writer が期待通りに動作しません。
+
+まず、*Interaction* と1対1の関係にある *InteractionMetadata* と、これらとは独立した *VisitorInteraction* および *CustomerInteraction* を保持する Item クラスを用意します。
+
+```java
+public class InteractionRecordToWriteInMultipleTables {
+ private final VisitorInteraction visitorInteraction;
+ private final CustomerInteraction customerInteraction;
+ private final Interaction interaction;
+ // ...
+}
+```
+```java
+public class Interaction {
+ private final InteractionMetadata interactionMetadata;
+}
+```
+
+`CompositeItemWriter` の設定では、それぞれのオブジェクトの writer を順番に呼び出すように設定します。
+この例では *Interaction* をアップデートするためのキーを取得するため、*InteractionMetadata* を先に書き込む必要があります。
+
+```xml
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```java
+@Configuration
+public class BatchAppConfig {
+ @Bean
+ public CompositeItemWriter> interactionsItemWriter() {
+ CompositeItemWriter compositeItemWriter = new CompositeItemWriter();
+ List> writers = new ArrayList<>(4);
+ writers.add(visitorInteractionsWriter());
+ writers.add(customerInteractionsWriter());
+ writers.add(interactionMetadataWriter());
+ writers.add(interactionWriter());
+ compositeItemWriter.setDelegates(writers);
+ return compositeItemWriter;
+ }
+}
+```
+
+それぞれの writer を必要に応じて設定します。例えば *Interaction* と *InteractionMetadata* の設定は次のようになります。
+
+```xml
+
+```
+```xml
+
+```
+
+reader の場合と同様、 `statementId` はネームスペースを含むステートメント ID です。
+
+Mapper ファイルにステートメントを定義します。
+
+```xml
+
+
+
+```
+```xml
+
+
+
+```
+
+はじめに `insertInteractionMetadata` が呼ばれ、その際に取得した主キーを使って親となる `Interaction` を `insertInteraction` を使って書き込むことができます。
+
+***JDBC ドライバによって動作が異なるので注意が必要です。例えば MySQL の JDBC ドライバは作成された全ての行の ID を返しますが、H2 バージョン 1.3.168 ではバッチモードでも最後に作成された行の ID のみが返されます。***
diff --git a/src/site/ja/markdown/boot.md b/src/site/ja/markdown/boot.md
new file mode 100644
index 0000000000..0243b87200
--- /dev/null
+++ b/src/site/ja/markdown/boot.md
@@ -0,0 +1,4 @@
+
+# Using Spring Boot
+
+詳細は [MyBatis Spring-boot-starter](http://www.mybatis.org/spring-boot-starter/mybatis-spring-boot-autoconfigure) のドキュメントを参照してください。
diff --git a/src/site/ja/markdown/factorybean.md b/src/site/ja/markdown/factorybean.md
new file mode 100644
index 0000000000..f1fef7443c
--- /dev/null
+++ b/src/site/ja/markdown/factorybean.md
@@ -0,0 +1,99 @@
+
+# SqlSessionFactoryBean
+
+基となる MyBatis では、`SqlSessionFactory` をビルドする際 `SqlSessionFactoryBuilder` を使いましたが、MyBatis-Spring では、`SqlSessionFactoryBean` を使います。
+
+## 設定
+
+Spring の XML 設定ファイルに次の Bean を定義することで Factory Bean を生成することができます。
+
+```xml
+
+
+
+```
+
+`SqlSessionFactoryBean` は Spring の `FactoryBean` インターフェイス([the Spring documentation(Core Technologies -Customizing instantiation logic with a FactoryBean-](https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#beans-factory-extension-factorybean) を参照してください)を実装しています。
+これはつまり、最終的に Spring が生成するのは `SqlSessionFactoryBean` ではなく、Factory の `getObject()` メソッドによって返されるオブジェクトであるということです。
+上記の設定では、Spring は `SqlSessionFactory` を生成し、`sqlSessionFactory` という名前の Bean として登録します。
+これに相当する Java のコードは下記のようになるでしょう。
+
+```java
+@Configuration
+public class MyBatisConfig {
+ @Bean
+ public SqlSessionFactory sqlSessionFactory() {
+ SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
+ factoryBean.setDataSource(dataSource());
+ return factoryBean.getObject();
+ }
+}
+```
+
+通常 MyBatis-Spring を使う場合、`SqlSessionFactoryBean` や対応する `SqlSessionFactory` を直接利用する必要はありません。
+`SqlSessionFactory` は `MapperFactoryBean` や `SqlSessionDaoSupport` を継承した他の DAO にインジェクト(注入)されます。
+
+## プロパティ
+
+`SqlSessionFactory` で必須のプロパティは JDBC の `DataSource` のみです。 どのような `DataSource` でも構いません。Spring でデータベース接続を定義する通常の手順で定義してください。
+
+`configLocation` は、MyBatis の XML 設定ファイルの場所を指定する際に使用します。これは、例えば基になる MyBatis の設定の一部を変更したい場合などに必要となります。
+よくあるのは `>settings>` や `` などの設定です。
+
+ここで指定する設定ファイルは、完全な MyBatis 設定ファイルである必要はありません。 環境、データソース、MyBatis のトランザクションマネージャーに関する設定は**無視されます**。
+`SqlSessionFactoryBean` は、独自にカスタマイズした MyBatis `Environment` を生成し、必要に応じてこれらの値を設定するようになっています。
+
+設定ファイルの指定が必要とされるもう一つの例は、MyBatis の Mapper XML ファイルが Mapper クラスとは別のクラスパスに存在する場合です。
+このような構成にする場合、次のどちらかの方法で設定することができます。最初の方法は、MyBatis の設定ファイルの `` で各 XML ファイルのクラスパスを指定する方法です。
+そしてもう一つは、Factory Bean の `mapperLocations` を使った方法です。
+
+`mapperLocations` プロパティは Resource Location のリストを取り、ここで MyBatis の XML Mapper ファイルの場所を指定することができます。
+Ant スタイルのパターン文字列を使って特定のディレクトリ内の全ファイルを指定したり、内包するディレクトリを再帰的に検索対象にすることもできます。次の例を見てください。
+
+```xml
+
+
+
+
+```
+
+このように指定すると、クラスパス内の `sample.config.mappers` パッケージと、そのサブパッケージに含まれる全ての MyBatis Mapper XML ファイルがロードされます。
+
+Container-Managed トランザクションを利用する環境では、`transactionFactoryClass` プロパティが必須となります。「トランザクション」章の該当する節を参照してください。
+
+複数のデータベースを使用する場合は、`databaseIdProvider` プロパティを設定する必要があります。
+
+```xml
+
+
+
+ sqlserver
+ db2
+ oracle
+ mysql
+
+
+
+```
+```xml
+
+
+
+
+
+```
+
+NOTE
+1.3.0より、`configuration` プロパティが追加されました。このプロパティには、MyBatisのXML設定ファイルを使わずに`Configuration`インスタンスを直接指定することができます。
+次の例を見てください。
+
+```xml
+
+
+
+
+
+
+
+
+```
diff --git a/src/site/ja/markdown/getting-started.md b/src/site/ja/markdown/getting-started.md
new file mode 100644
index 0000000000..d1ed42e4c1
--- /dev/null
+++ b/src/site/ja/markdown/getting-started.md
@@ -0,0 +1,100 @@
+
+# スタートガイド
+
+この章では、MyBatis-Spring のインストール・設定手順と、トランザクション処理を含むシンプルなアプリケーションの構築する方法について説明します。
+
+## インストール
+
+MyBatis-Spring を使うためには、 `mybatis-spring-${project.version}.jar` と依存するライブラリをクラスパスに追加するだけで OK です。
+
+Maven をお使いの場合は、 pom.xml に次の dependency を追加してください。
+
+```xml
+
+ org.mybatis
+ mybatis-spring
+ ${project.version}
+
+```
+
+## クイックセットアップ
+
+MyBatis と Spring を組み合わせて使う場合、Spring の Application Context 内に少なくとも `SqlSessionFactory` と一つ以上の Mapper インターフェイスを定義する必要があります。
+
+MyBatis-Spring では `SqlSessionFactory` の生成に `SqlSessionFactoryBean` を使います。この Factory Bean を設定するため、Spring の 設定ファイルに次の Bean を追加してください。
+
+```xml
+
+
+
+```
+
+```java
+@Configuration
+public class MyBatisConfig {
+ @Bean
+ public SqlSessionFactory sqlSessionFactory() throws Exception {
+ SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
+ factoryBean.setDataSource(dataSource());
+ return factoryBean.getObject();
+ }
+}
+```
+
+`SqlSessionFactory` が `DataSource` を必要としている点に注意してください。どのような `DataSource` でも構いません。通常の手順で設定してください。
+
+Mapper インターフェイスが次のように定義されている場合...
+
+```java
+public interface UserMapper {
+ @Select("SELECT * FROM users WHERE id = #{userId}")
+ User getUser(@Param("userId") String userId);
+}
+```
+
+`MapperFactoryBean` を使ってこのインターフェイスを Spring に登録する場合、以下のように設定します。
+
+```xml
+
+
+
+
+```
+
+ここで指定した Mapper は、実装クラスではなく **インターフェイス** である必要がありますので注意してください。
+この例では、アノテーションを使って SQL を指定していますが、Mapper XML ファイルを使うこともできます。
+
+上記のように設定しておけば、あとは他の Spring Bean と同様にビジネス/サービス層のオブジェクトにインジェクト(注入)することができます。
+`MapperFactoryBean` は `SqlSession` の生成とクローズを行います。
+もし Spring のトランザクション内で実行された場合は、トランザクション終了時にセッションがコミットあるいはロールバックされます。
+最後にもう一点、全ての例外は Spring の `DataAccessException` に変換されます。
+
+Java Configurationを使用する場合:
+
+```java
+@Configuration
+public class MyBatisConfig {
+ @Bean
+ public UserMapper userMapper() throws Exception {
+ SqlSessionTemplate sqlSessionTemplate = new SqlSessionTemplate(sqlSessionFactory());
+ return sqlSessionTemplate.getMapper(UserMapper.class);
+ }
+}
+```
+
+MyBatis のデータメソッドは、一行だけで実行可能となります。
+
+```java
+public class FooServiceImpl implements FooService {
+
+ private final UserMapper userMapper;
+
+ public FooServiceImpl(UserMapper userMapper) {
+ this.userMapper = userMapper;
+ }
+
+ public User doSomeBusinessStuff(String userId) {
+ return this.userMapper.getUser(userId);
+ }
+}
+```
diff --git a/src/site/ja/markdown/index.md b/src/site/ja/markdown/index.md
new file mode 100644
index 0000000000..0c6adb2296
--- /dev/null
+++ b/src/site/ja/markdown/index.md
@@ -0,0 +1,52 @@
+
+# イントロダクション
+
+## MyBatis-Spring とは?
+
+MyBatis-Spring によって MyBatis と Spring をシームレスに連携させることができます。このライブラリを使えば、MyBatis のステートメントを Spring のトランザクション内で実行することもできますし、Mapper や `SqlSession` の生成、他の Bean への注入、MyBatis の例外から Spring の `DataAccessException` への変換、さらには MyBatis や Spring, MyBatis-Spring に依存しないコードでアプリケーションを構築することも可能になります。
+
+## 動機
+
+Spring バージョン 2 は iBATIS バージョン 2 しかサポートしていません。Spring 3 の開発時に MyBatis 3 への対応が検討されました(こちらの [チケット](https://jira.springsource.org/browse/SPR-5991) 参照)が、Spring 3 が MyBatis 3 よりも前に正式リリースを迎えたため、残念ながら実装は見送られました。Spring 開発陣としては、未リリースの MyBatis 3 に合わせたコードをリリースしたくなかったという事情があり、Spring 側での正式対応は保留となっていました。MyBatis コミュニティの中で Spring 対応への要望が強かったため、有志によって Spring との連携を行う MyBatis のサブプロジェクトが立ち上げられました。
+
+## 動作条件
+
+MyBatis-Spring を利用するためには、MyBatis と Spring の用語について理解しておくことが重要です。このドキュメントには MyBatis や Spring についての説明や基本設定といった情報は含まれていません。
+
+MyBatis-Spring は以下のバージョンを必要とします。
+
+| MyBatis-Spring | MyBatis | Spring Framework | Spring Batch | Java |
+| --- | --- | --- | --- | --- |
+| **2.0** | 3.5+ | 5.0+ | 4.0+ | Java 8+ |
+| **1.3** | 3.4+ | 3.2.2+ | 2.1+ | Java 6+ |
+
+## 謝辞
+
+このプロジェクトの実現にご協力頂いた次の方々に感謝します(アルファベット順):
+Eduardo Macarron, Hunter Presnall, Putthiphong Boonphong(コーディング、テスト、ドキュメント作成);
+Andrius Juozapaitis, Giovanni Cuccu, Mike Lanyon, Raj Nagappan, Tomas Pinos(コントリビューション);
+Simone Tripodi(メンバーを集め、MyBatis のサブプロジェクトとしてまとめてくれました)
+このプロジェクトは彼らの協力なしには実現できなかったでしょう。
+
+## このドキュメントの改善にご協力ください...
+
+このドキュメントの中で誤りや特定の機能に関する記述が抜けていることに気づいたら、詳しく調べてドキュメントを更新して頂けると助かります。
+
+このマニュアルのソースは markdown 形式で、[プロジェクトの Git リポジトリ](https://github.com/mybatis/spring/tree/master/src/site) で配布されています。
+リポジトリをフォーク、それらを更新します、とプルリクエストを送信します。
+
+このドキュメントを必要としている人、つまりあなたこそが最高の著者なのです!
+
+## Translations
+
+MyBatis-Spring は以下の言語の翻訳を用意しています。
+
+
- This bean is an ItemReader that reads records from a database using a cursor.
-
-
-
- NOTE To use this bean you need at least MyBatis 3.4.0 or a newer version.
-
-
-
- It executes the query specified as the setQueryId property to retrieve requested data
- by using the method selectCursor().
- Each time a read() method is called it will return the next element of the cursor until no more
- elements are left.
-
-
-
- The reader will use a separate connection so the select statement does no participate in any transactions created
- as part of the step processing.
-
-
-
When using the cursor you can just execute a regular query:
-
- SELECT id, name, job FROM employees ORDER BY id ASC
-]]>
-
-
- NOTE
- See JPetstore 6 demo to know about how to use Spring with a full web application server.
-
-
-
- You can check out sample code from the MyBatis-Spring repo:
-
-
- Any of the samples can be run with JUnit 5.
-
-
- The sample code shows a typical design where a transactional service gets domain objects from a data access layer.
-
-
- FooService.java acts as the service:
-
-
-
- It is a transactional bean, so when the method is called, the transaction is started
- and the transaction is committed when the method ends without throwing an uncaught exception.
- Notice that transactional behaviour is configured with the
- @Transactional
- attribute. This is not required; any other way provided by Spring can be used to demarcate
- your transactions.
-
-
- This service calls a data access layer built with MyBatis. This layer
- consists on a just an interface UserMapper.java
- that will be used with a dynamic proxy built by MyBatis at
- runtime and injected into the service by Spring.
-
-
-
- Note that, for the sake of simplicity we used the interface UserMapper.java for the DAO scenario
- where a DAO is built with an interface and a implementation though in this case it would have been more
- adequate to use an interface called UserDao.java instead.
-
-
- We will see different ways to find the mapper interface, register it to Spring and inject it into the service bean:
-
-
-
Scenarios
-
-
-
Sample test
-
Description
-
-
-
-
-
- SampleMapperTest.java
-
-
- Shows you the base configuration based on a MapperFactoryBean
- that will dynamically build an implementation for UserMapper
-
-
-
-
- SampleScannerTest.java
-
-
- Shows how to use the MapperScannerConfigurer so all the mappers in a project are autodiscovered.
-
-
-
-
- SampleSqlSessionTest.java
-
-
- Shows how to hand code a DAO using a Spring managed SqlSession
- and providing your own implementation UserDaoImpl.java.
-
-
-
-
- SampleEnableTest
-
-
- Shows how to use Spring's @Configuration with the @MapperScann annotation so
- mappers are autodiscovered.
-
-
-
-
- SampleNamespaceTest
-
-
- Shows how to use the custom MyBatis XML namespace.
-
-
-
-
- SampleJavaConfigTest.java
-
-
- Shows how to use Spring's @Configuration to create MyBatis beans manually.
-
-
-
-
- SampleJobJavaConfigTest.java
-
-
- Shows how to use ItemReader and ItemWriter on Spring Batch using Java Configuration.
-
-
-
-
- SampleJobXmlConfigTest.java
-
-
- Shows how to use ItemReader and ItemWriter on Spring Batch using XML Configuration.
-
-
-
-
-
- Please take a look at the different applicationContext.xml files to see MyBatis-Spring in action.
-
-
-
-
diff --git a/src/site/ko/markdown/README.md b/src/site/ko/markdown/README.md
new file mode 100644
index 0000000000..4e31a121bc
--- /dev/null
+++ b/src/site/ko/markdown/README.md
@@ -0,0 +1,18 @@
+# 목차
+
+이 페이지는 GitHub에서 인덱스를 렌더링하기위한 것입니다.
+
+> **NOTE:**
+>
+> 링크 대상은 maven-site-plugin을 사용하여 html로 변환된다는 가정하에 지정되므로 GitHub의 렌더링에서 끊어진 앵커가 있습니다.
+
+* [소개](./index.md)
+* [시작하기](./getting-started.md)
+* [SqlSessionFactoryBean](./factorybean.md)
+* [트랜잭션](./transactions.md)
+* [SqlSession 사용](./sqlsession.md)
+* [매퍼 주입](./mappers.md)
+* [Spring Boot](./boot.md)
+* [MyBatis API 사용](./using-api.md)
+* [Spring Batch](./batch.md)
+* [샘플 코드](./sample.md)
diff --git a/src/site/ko/markdown/batch.md b/src/site/ko/markdown/batch.md
new file mode 100644
index 0000000000..29ec3f6df6
--- /dev/null
+++ b/src/site/ko/markdown/batch.md
@@ -0,0 +1,353 @@
+
+# Spring Batch
+
+마이바티스 스프링 연동모듈의 1.1.0버전에서는 스프링 배치 애플리케이션을 만들기 위해 두개의 빈을 제공한다.
+두개의 빈은 `MyBatisPagingItemReader` 와 `MyBatisCursorItemReader` 와 MyBatisBatchItemWriter이다.
+
+또한 2.0.0 버전에서는 Java Configuration 을 지원하는 다음의 세 가지 Builder class 를 제공한다.
+`MyBatisPagingItemReaderBuilder`, `MyBatisCursorItemReaderBuilder` 그리고 `MyBatisBatchItemWriterBuilder` 이다.
+
+중요
+이 문서는 [스프링 배치](http://static.springsource.org/spring-batch/) 에 대한 것으로 마이바티스 배치 `SqlSession` 을 다루지는 않는다.
+배치 세션에 대해서는 [SqlSession 사용](sqlsession.html) 에서 좀더 다루었다.
+
+# MyBatisPagingItemReader
+
+이 빈은 마이바티스로 페이지를 처리하는 형태로 데이터베이스 데이터를 읽어오는 `ItemReader`이다.
+
+요청된 데이터를 가져오기 위해 `setQueryId` 프로퍼티에 명시된 쿼리를 실행한다.
+쿼리는 `setPageSize` 프로퍼티에 명시된 크기만큼 데이터를 가져오도록 실행된다.
+`read()` 메서드를 사용하면 필요할 때 현재 위치에서 정해진 수 만큼 더 추가 데이터를 가져온다.
+reader는 몇가지의 표준적인 쿼리 파라미터를 제공하고 명명된 쿼리의 SQL은 요청된 크기만큼의 데이터를 만들기 위해 파라미터의 일부 혹은 모두 사용한다.
+여기서 사용가능한 파라미터이다.
+
+* `_page`: 읽을 페이지 수(0부터 시작)
+* `_pagesize`: 페이지의 크기, 이를테면 리턴하는 로우 수
+* `_skiprows`: `_page` 와 `_pagesize`의 결과
+
+각각의 파라미터는 selet구문에서 다음처럼 매핑될 수 있다.
+
+```xml
+
+```
+
+다음의 코드는 샘플 설정이다.
+
+```xml
+
+
+
+
+```
+
+```java
+@Configuration
+public class BatchAppConfig {
+ @Bean
+ public MyBatisPagingItemReader reader() {
+ return new MyBatisPagingItemReaderBuilder()
+ .sqlSessionFactory(sqlSessionFactory())
+ .queryId("com.my.name.space.batch.EmployeeMapper.getEmployee")
+ .build();
+ }
+}
+```
+
+**좀더 복잡한 예제를 보자.**
+
+```xml
+
+```
+```xml
+
+
+
+
+
+
+```
+
+```java
+@Configuration
+public class BatchAppConfig {
+ @StepScope
+ @Bean
+ public MyBatisPagingItemReader dateBasedCriteriaReader(
+ @Value("#{@datesParameters}") Map datesParameters) throws Exception {
+ return new MyBatisPagingItemReaderBuilder()
+ .sqlSessionFactory(batchReadingSessionFactory())
+ .queryId("com.my.name.space.batch.ExampleMapper.queryUserInteractionsOnSpecificTimeSlot")
+ .parameterValues(datesParameters)
+ .pageSize(200)
+ .build();
+ }
+
+ @StepScope
+ @Bean
+ public Map datesParameters(
+ @Value("#{jobExecutionContext['EXTRACTION_START_DATE']}") LocalDate yesterday,
+ @Value("#{jobExecutionContext['TODAY_DATE']}") LocalDate today,
+ @Value("#{jobExecutionContext['FIRST_DAY_OF_THE_MONTH_DATE']}") LocalDate firstDayOfTheMonth,
+ @Value("#{jobExecutionContext['FIRST_DAY_OF_THE_PREVIOUS_MONTH_DATE']}") LocalDate firstDayOfThePreviousMonth) {
+ Map map = new HashMap<>();
+ map.put("yesterday", yesterday);
+ map.put("today", today);
+ map.put("first_day_of_the_month", firstDayOfTheMonth);
+ map.put("first_day_of_the_previous_month", firstDayOfThePreviousMonth);
+ return map;
+ }
+}
+```
+
+앞의 예제와는 몇가지 차이점이 있다.
+
+* `sqlSessionFactory`: reader에 별도로 구현한 sessionFactory를 지정할 수 있다. 이 옵션은 다양한 데이터베이스에서 데이터를 읽을때 유용하다.
+* `queryId`: 여러개의 테이블에서 데이터를 읽어야 하고 서로 다른 쿼리를 사용한다면 서로다른 네임스페이스를 가진 매퍼 파일을 사용하는게 좋을수 있다. 쿼리를 알아볼때, 매퍼 파일의 네임스페이스를 잊지 말아야 한다.
+* `parameterValues`: 이 맵을 사용해서 추가로 파라미터를 전달할 수 있다. 위 예제는 `jobExecutionContext`에서 값들을 가져오는 SpEL표현식을 사용하는 맵을 사용하고 있다.
+ 맵의 키는 매퍼파일에서 마이바티스가 사용할 것이다. (예: *yesterday* 는 `#{yesterday,jdbcType=TIMESTAMP}` 로 사용될수 있다.).
+ 맵과 reader 모두 `jobExecutionContext`에서 SpEL표현식을 사용하기 위해 `step` 스코프를 사용한다. 마이바티스의 타입핸들러가 제대로 설정이 되었다면 JodaTime날짜를 맵을 사용해서 파라미터로 넘길수 있다.
+* `pageSize`: 배치가 청크크기가 지정된 형태로 처리가 되면 reader에 이 값을 전달하는게 적절하다.
+
+## MyBatisCursorItemReader
+
+이 빈은 cursor 를 사용하여 데이터베이스에서 레코드를 읽는 `ItemReader` 이다.
+
+중요
+이 빈을 사용하려면 최소한 MyBatis 3.4.0 이나 그 이상이어야 한다.
+
+`setQueryId` 속성으로 지정된 쿼리를 실행하여 `selectCursor()` 메서드를 사용하여 요청 된 데이터를 검색한다. `read()` 메서드가 호출 될 때마다 요소가 더 이상 남아 있지 않을 때까지 cursor 의 다음 요소를 반환한다.
+
+reader 는 별도의 connection 을 사용하므로 select 문은 step processing 일부로 생성된 트랜잭션에 속하지 않는다.
+
+cursor 를 사용할 때 다음과 같이 일반 쿼리를 실행할 수 있다.
+
+```xml
+
+```
+
+아래는 샘플 설정이다.
+
+```xml
+
+
+
+
+```
+
+```java
+@Configuration
+public class BatchAppConfig {
+ @Bean
+ public MyBatisCursorItemReader reader() {
+ return new MyBatisCursorItemReaderBuilder()
+ .sqlSessionFactory(sqlSessionFactory())
+ .queryId("com.my.name.space.batch.EmployeeMapper.getEmployee")
+ .build();
+ }
+}
+```
+
+# MyBatisBatchItemWriter
+
+모든 아이템을 배치로 구문을 일괄실행하기 위해 `SqlSessionTemplate`에서 배치로 작업을 처리하는 `ItemWriter`이다. `SqlSessionFactory`는 `BATCH` 실행자로 설정할 필요가 있다.
+
+사용자는 `write()` 메서드가 호출될때 실행될 매핑구문 아이디를 제공해야 한다. `write()` 메서드는 트랜잭션내에서 호출되는 것으로 예상된다.
+
+다음의 코드는 샘플설정이다.
+
+```xml
+
+
+
+
+```
+```java
+@Configuration
+public class BatchAppConfig {
+ @Bean
+ public MyBatisBatchItemWriter writer() {
+ return new MyBatisBatchItemWriterBuilder()
+ .sqlSessionFactory(sqlSessionFactory())
+ .statementId("com.my.name.space.batch.EmployeeMapper.updateEmployee")
+ .build();
+ }
+}
+```
+
+
+**Converting a item that read using ItemReader to an any parameter object:**
+
+By default behavior, the `MyBatisBatchItemWriter` passes a item that read using `ItemReader` (or convert by `ItemProcessor`) to the MyBatis(`SqlSession#update()`) as the parameter object.
+If you want to customize a parameter object that passes to the MyBatis, you can realize to use the `itemToParameterConverter` option.
+For example using `itemToParameterConverter` option, you can passes any objects other than the item object to the MyBatis.
+Follows below a sample:
+
+At first, you create a custom converter class (or factory method). The following sample uses a factory method.
+
+```java
+public class ItemToParameterMapConverters {
+ public static Converter> createItemToParameterMapConverter(String operationBy, LocalDateTime operationAt) {
+ return item -> {
+ Map parameter = new HashMap<>();
+ parameter.put("item", item);
+ parameter.put("operationBy", operationBy);
+ parameter.put("operationAt", operationAt);
+ return parameter;
+ };
+ }
+}
+```
+
+At next, you write a sql mapping.
+
+```xml
+
+```
+
+At last, you configure the `MyBatisBatchItemWriter`.
+
+```java
+@Configuration
+public class BatchAppConfig {
+ @Bean
+ public MyBatisBatchItemWriter writer() throws Exception {
+ return new MyBatisBatchItemWriterBuilder()
+ .sqlSessionFactory(sqlSessionFactory())
+ .statementId("org.mybatis.spring.sample.mapper.PersonMapper.createPerson")
+ .itemToParameterConverter(createItemToParameterMapConverter("batch_java_config_user", LocalDateTime.now()))
+ .build();
+ }
+}
+```
+
+```xml
+
+
+
+
+
+
+
+
+
+
+```
+
+**여러개의 테이블에 데이터를 쓰려면 한꺼번에 처리할 수 있도록 만든 writer(몇가지 규칙을 가지고)를 사용하자.**
+
+이 기능은 마이바티스 3.2이상에서만 사용할 수 있다. 이전의 버전에서는 예상과 다르게 동작하는데 그 내용은 [이슈](http://code.google.com/p/mybatis/issues/detail?id=741)를 참고하면 된다.
+
+배치가 관계를 가지는 데이터나 여러개의 데이터베이스를 다루는 것처럼 복잡한 데이터를 작성할때 필요하다면 insert구문이 한개에 테이블에만 데이터를 넣을수 있다는 사실만 피하면 가능하기도 하다.
+이런 복잡한 데이터를 처리하기 위해 writer가 작성하는 아이템(Item)을 준비해야 한다. 다음의 기술을 사용하면 단순한 관계를 가진 데이터나 관계가 없는 테이블을 처리하는 아이템에서 사용할 수 있다.
+
+이러한 방법으로 스프링 배치 아이템은 모든 레코드를 *다룰것이다*.
+여기에는 1:1 *관계*를 가지는 *InteractionMetadata*, 관계가 없는 두개의 로우는 *VisitorInteraction* 와 *CustomerInteraction*이 있다.
+이 각각의 객체는 다음과 같이 볼수 있다.
+
+```java
+public class InteractionRecordToWriteInMultipleTables {
+ private final VisitorInteraction visitorInteraction;
+ private final CustomerInteraction customerInteraction;
+ private final Interaction interaction;
+ // ...
+}
+```
+```java
+public class Interaction {
+ private final InteractionMetadata interactionMetadata;
+}
+```
+
+그리고 스프링 설정에는 각각의 레코드를 처리하기위해 특별히 설정된 전용(delegates) writer를 사용하는 `CompositeItemWriter`가 있다.
+
+```xml
+
+
+
+
+
+
+
+
+
+
+
+
+```
+```java
+@Bean
+@Configuration
+public class BatchAppConfig {
+ public CompositeItemWriter> interactionsItemWriter() {
+ CompositeItemWriter compositeItemWriter = new CompositeItemWriter();
+ List> writers = new ArrayList<>(4);
+ writers.add(visitorInteractionsWriter());
+ writers.add(customerInteractionsWriter());
+ writers.add(interactionMetadataWriter());
+ writers.add(interactionWriter());
+ compositeItemWriter.setDelegates(writers);
+ return compositeItemWriter;
+ }
+}
+```
+
+각각의 전용(delegate) writer는 필요할 만큼 설정할 수 있다. 예를들면 *Interaction* 과 *InteractionMetadata*를 위한 writer가 있다.
+
+```xml
+
+```
+```xml
+
+```
+
+reader와 동일하게 `statementId`는 네임스페이스를 가진 구문을 가리킬수 있다.
+
+매퍼 파일에서 구문은 다음과 같은 방법으로 각각의 레코드를 위해 만들어져있다.
+
+```xml
+
+
+
+```
+```xml
+
+
+
+```
+
+먼저 `insertInteractionMetadata`가 호출될것이고 update구문은 jdbc드라이버에 의해(`keyProperty` 와 `keyColumn`) 생성된 아이디들을 리턴하기 위해 설정되었다.
+`InteractionMetadata` 객체가 이 쿼리에 의해 업데이트되면 다음의 쿼리는 `insertInteraction`를 통해 상위객체인 `Interaction`를 작성하기 위해 사용될수 있다.
+
+***방금 언급한 내용에 관련하여 JDBC드라이버가 똑같이 동작하지 않을수 있다.
+이 글을 쓰는 시점에 H2 드라이버 1.3.168버전(`org.h2.jdbc.JdbcStatement#getGeneratedKeys`를 보라)만 배치모드에서 마지막 인덱스를 리턴한다.
+반면에 MySQL 드라이버는 기대한 것과 동일하게 동작하고 모든 아이디를 리턴한다.***
diff --git a/src/site/ko/markdown/boot.md b/src/site/ko/markdown/boot.md
new file mode 100644
index 0000000000..7e932a7fa6
--- /dev/null
+++ b/src/site/ko/markdown/boot.md
@@ -0,0 +1,4 @@
+
+# 스프링 부트 사용하기
+
+자세한 내용은 [MyBatis Spring-boot-starter](http://www.mybatis.org/spring-boot-starter/mybatis-spring-boot-autoconfigure) 하위 프로젝트 문서를 참조하십시오.
diff --git a/src/site/ko/markdown/factorybean.md b/src/site/ko/markdown/factorybean.md
new file mode 100644
index 0000000000..e0a79081ad
--- /dev/null
+++ b/src/site/ko/markdown/factorybean.md
@@ -0,0 +1,97 @@
+
+# SqlSessionFactoryBean
+
+마이바티스만 사용하면, `SqlSessionFactory`는 `SqlSessionFactoryBuilder`를 사용해서 생성한다.
+마이바티스 스프링 연동모듈에서는, `SqlSessionFactoryBean`가 대신 사용된다.
+
+## 설정
+
+팩토리 빈을 생성하기 위해, 스프링 XML설정파일에 다음설정을 추가하자.
+
+```xml
+
+
+
+```
+
+`SqlSessionFactoryBean` 은 스프링의 `FactoryBean` 인터페이스를 구현(see [the Spring documentation(Core Technologies -Customizing instantiation logic with a FactoryBean-)](https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#beans-factory-extension-factorybean))한다는 점을 알아야 한다.
+이 설정은 스프링이 `SqlSessionFactoryBean` 자체를 생성하는 것이 **아니라** 팩토리에서 `getObject()` 메서드를 호출한 결과를 리턴한다는 것을 의미한다.
+이 경우, 스프링은 애플리케이션 시작 시점에 `SqlSessionFactory`를 빌드하고 `sqlSessionFactory` 라는 이름으로 저장한다. 자바에서 코드로 표현하면 아래와 같다.
+
+```java
+@Configuration
+public class MyBatisConfig {
+ @Bean
+ public SqlSessionFactory sqlSessionFactory() {
+ SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
+ factoryBean.setDataSource(dataSource());
+ return factoryBean.getObject();
+ }
+}
+```
+
+일반적인 마이바티스 스프링 사용법에서는, `SqlSessionFactoryBean`이나 관련된 `SqlSessionFactory`를 직접 사용할 필요가 없다.
+대신 세션 팩토리가 `MapperFactoryBean`나 `SqlSessionDaoSupport`를 확장하는 다른 DAO에 주입될것이다.
+
+## 속성
+
+`SqlSessionFactory`는 JDBC `DataSource`의 필수 프로퍼티가 필요하다. 어떤 `DataSource`라도 상관없고 다른 스프링 데이터베이스 연결처럼 설정되어야만 한다.
+
+하나의 공통적인 프로퍼티는 마이바티스 XML설정파일의 위치를 지정하기 위해 사용되는 `configLocation`이다. 이 프로퍼티를 설정하는 것은 디폴트 설정을 가진 마이바티스 설정을 변경해야 할 경우 뿐이다.
+대개는 ``과 `` 섹션을 변경하는 경우이다.
+
+설정파일이 마이바티스 설정을 완전히 다룰 필요는 없다. 어떤 환경, 어떤 데이터소스 그리고 마이바티스 트랜잭션 관리자가 **무시**될수도 있다.
+`SqlSessionFactoryBean` 는 필요에 따라 이 값들을 설정하여 자체적인 MyBatis `Environment` 를 만든다.
+
+설정파일이 필요한 다른 이유는 마이바티스 XML파일이 매퍼 클래스와 동일한 클래스패스에 있지 않은 경우이다. 이 설정을 사용하면 두가지 옵션이 있다.
+첫번째는 마이바티스 설정파일에 `` 섹션을 사용해서 XML파일의 클래스패스를 지정하는 것이다. 두번째는 팩토리 빈의 `mapperLocations` 프로퍼티를 사용하는 것이다.
+
+`mapperLocations` 프로퍼티는 매퍼에 관련된 자원의 위치를 나열한다. 이 프로퍼티는 마이바티스의 XML매퍼 파일들의 위치를 지정하기 위해 사용될 수 있다.
+디렉터리 아래 모든 파일을 로드하기 위해 앤트(Ant) 스타일의 패턴을 사용할수도 있고 가장 상위 위치를 지정하는 것으로 재귀적으로 하위 경로를 찾도록 할수도 있다. 예를 들어보면 다음과 같다.
+
+```xml
+
+
+
+
+```
+
+이 설정은 `sample.config.mappers` 패키지 아래와 그 하위 패키지를 모두 검색해서 마이바티스 매퍼 XML파일을 모두 로드할 것이다.
+
+컨테이너 관리 트랜잭션을 사용하는 환경에서 필요한 하나의 프로퍼티는 `transactionFactoryClass` 이다. 이에 관련해서는 트랜잭션을 다루는 장에서 볼수 있다.
+
+만약 multi-db 기능을 사용한다면 다음과 같이 `databaseIdProvider` 속성을 설정해야 한다.
+
+```xml
+
+
+
+ sqlserver
+ db2
+ oracle
+ mysql
+
+
+
+```
+````xml
+
+
+
+
+
+````
+
+NOTE
+1.3.0 버전 부터 `configuration` 속성이 추가되었다. 다음과 같이 MyBatis XML 설정 파일없이 `Configuration` 인스턴스를 직접 지정할 수 있습니다.
+
+```xml
+
+
+
+
+
+
+
+
+```
diff --git a/src/site/ko/markdown/getting-started.md b/src/site/ko/markdown/getting-started.md
new file mode 100644
index 0000000000..f04bde22cc
--- /dev/null
+++ b/src/site/ko/markdown/getting-started.md
@@ -0,0 +1,98 @@
+
+# 시작하기
+
+이 장은 마이바티스 스프링 연동모듈을 설치하고 셋팅하는 방법에 대해 간단히 보여준다. 그리고 트랜잭션을 사용하는 간단한 애플리케이션을 만드는 방법까지 다룰 것이다.
+
+## 설치
+
+마이바티스 스프링 연동모듈을 사용하기 위해서, 클래스패스에 `mybatis-spring-${project.version}.jar`를 포함시켜야 한다.
+
+메이븐을 사용하고 있다면 pom.xml에 다음처럼 의존성을 추가하면 된다.
+
+```xml
+
+ org.mybatis
+ mybatis-spring
+ ${project.version}
+
+```
+
+## 빠른 설정
+
+마이바티스를 스프링과 함께 사용하려면 스프링의 애플리케이션 컨텍스트에 적어도 두개를 정의해줄 필요가 있다.
+두가지는 `SqlSessionFactory`와 한개 이상의 매퍼 인터페이스이다.
+
+마이바티스 스프링 연동모듈에서, `SqlSessionFactoryBean`은 `SqlSessionFactory`를 만들기 위해 사용된다. 팩토리 빈을 설정하기 위해, 스프링 설정파일에 다음 설정을 추가하자.
+
+```xml
+
+
+
+```
+
+```java
+@Configuration
+public class MyBatisConfig {
+ @Bean
+ public SqlSessionFactory sqlSessionFactory() throws Exception {
+ SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
+ factoryBean.setDataSource(dataSource());
+ return factoryBean.getObject();
+ }
+}
+```
+
+`SqlSessionFactory`는 `DataSource`를 필요로 하는 것을 알아둘 필요가 있다. 어떤 `DataSource`도 상관없지만 다른 스프링의 데이터베이스 연결과 동일하게 설정되어야 한다.
+
+매퍼 인터페이스가 다음처럼 정의되었다고 가정해보자.
+
+```java
+public interface UserMapper {
+ @Select("SELECT * FROM users WHERE id = #{userId}")
+ User getUser(@Param("userId") String userId);
+}
+```
+
+UserMapper인터페이스는 다음처럼 `MapperFactoryBean`을 사용해서 스프링에 추가된다.
+
+```xml
+
+
+
+
+```
+
+매퍼는 **반드시** 구현체 클래스가 아닌 인터페이스로 정의되어야 한다. 예를들어, 애노테이션이 SQL을 명시하기 위해 사용되지만 마이바티스 매퍼 XML파일 또한 사용될 수 있다.
+
+한번만 설정하면, 다른 스프링 빈에 주입하는 같은 방법으로 비즈니스/서비스 객체에 매퍼를 직접 주입할 수 있다. `MapperFactoryBean`은 `SqlSession`을 생성하고 닫는 작업을 잘 다룬다.
+실행중인 스프링 트랜잭션이 있다면, 트랜잭션이 완료되는 시점에 커밋이나 롤백이 될 것이다. 마지막으로 예외가 발생하면 스프링의 `DataAccessException`예외가 발생한다.
+
+자바로 설정하면 다음과 같다.
+
+```java
+@Configuration
+public class MyBatisConfig {
+ @Bean
+ public UserMapper userMapper() throws Exception {
+ SqlSessionTemplate sqlSessionTemplate = new SqlSessionTemplate(sqlSessionFactory());
+ return sqlSessionTemplate.getMapper(UserMapper.class);
+ }
+}
+```
+
+마이바티스의 데이터 관련 메서드는 호출하는 것은 한줄이면 된다.
+
+```java
+public class FooServiceImpl implements FooService {
+
+ private final UserMapper userMapper;
+
+ public FooServiceImpl(UserMapper userMapper) {
+ this.userMapper = userMapper;
+ }
+
+ public User doSomeBusinessStuff(String userId) {
+ return this.userMapper.getUser(userId);
+ }
+}
+```
diff --git a/src/site/ko/markdown/index.md b/src/site/ko/markdown/index.md
new file mode 100644
index 0000000000..393eec171f
--- /dev/null
+++ b/src/site/ko/markdown/index.md
@@ -0,0 +1,54 @@
+
+# 소개
+
+## MyBatis-Spring 은 무엇일까?
+
+마이바티스 스프링 연동모듈은 마이바티스와 스프링을 편하고 간단하게 연동한다. 이 모듈은 마이바티스로 하여금 스프링 트랜잭션에 쉽게 연동되도록 처리한다. 게다가 마이바티스 매퍼와 `SqlSession`을 다루고 다른 빈에 주입시켜준다.
+마이바티스 예외를 스프링의 `DataAccessException`로 변환하기도 하고 마이바티스, 스프링 또는 마이바티스 스프링 연동모듈에 의존성을 없애기도 한다.
+
+## 동기 부여
+
+스프링 2.x은 아이바티스 2.x만을 지원한다. 스프링 3.x에서 마이바티스 3.x를 지원하기 위한 시도가 진행중이다. (스프링의 이슈관리 시스템인 [이슈](https://jira.springsource.org/browse/SPR-5991) 를 보라.)
+불행하게도 스프링 3의 개발이 마이바티스 3.0의 정식릴리즈전에 개발이 완료되었다. 그래서 스프링팀은 릴리즈가 안된 마이바티스 코드를 함께 릴리즈하는 것을 원하지 않았고 실제적인 스프링 지원을 기다릴수밖에 없었다.
+스프링의 마이바티스 지원에 대한 관심으로 인해, 마이바티스 커뮤니티는 재결합하는 형태로 결정을 내고 대신 마이바티스의 하위 프로젝트 형태로 스프링 연동 프로젝트를 추가한다.
+
+## 필요 조건
+
+마이바티스 스프링 연동을 시작하기 전에, 마이바티스와 스프링의 용어를 맞추는 일이 굉장히 중요했다. 이 문서는 배경지식이나 기본적인 셋업방법 그리고 마이바티스와 스프링의 설정에 대한 튜토리얼등은 제공하지 않는다.
+
+MyBatis-Spring requires following versions:
+
+| MyBatis-Spring | MyBatis | Spring Framework | Spring Batch | Java |
+| --- | --- | --- | --- | --- |
+| **2.0** | 3.5+ | 5.0+ | 4.0+ | Java 8+ |
+| **1.3** | 3.4+ | 3.2.2+ | 2.1+ | Java 6+ |
+
+## 감사 인사
+
+이 프로젝트가 실제로 만들어지게 도와준 모든 특별한 분들에게 정말 감사한다.
+알파벳 순서로 보면, 코딩및 테스트 그리고 문서화를 담당했던 Eduardo Macarron, Hunter Presnall, Putthiphong Boonphong;
+그외 다양한 프로젝트 기여자인 Andrius Juozapaitis, Giovanni Cuccu, Mike Lanyon, Raj Nagappan, Tomas Pinos;
+그리고 마이바티스에 하위 프로젝트로 가져올수 있도록 많은 것을 찾아준 Simone Tripodi 에게 감사한다. ;)
+이들이 없었다면 이 프로젝트는 존재하지 않았을 것이다.
+
+## 이 문서가 더 나아지도록 도와주세요…
+
+만약에 어떤 방법으로든 이 문서의 취약점이 발견되거나 기능에 대한 문서화가 빠진 부분이 보인다면, 가장 좋은 방법은 먼저 공부해서 자신만의 문서를 작성하는 것이다.
+
+이 문서의 원본은 xdoc포맷이며 [프로젝트의 Git](https://github.com/mybatis/spring/tree/master/src/site)에서 찾을 수 있다. repository 를 fork 하고, 업데이트하고 pull request 를 보내주십시오.
+
+당신처럼 이 문서를 읽는 사람들에게 이 문서의 최고의 저자가 될수 있다!
+
+## 번역
+
+사용자들은 다음의 번역문서별로 마이바티스 스프링 연동모듈에 대해 알수 있다.
+
+
+
+위 번역문서에는 없지만 자국의 언어로 문서로 보고 싶다면, 자국의 언어로 된 문서를 만들어서 우리에게 보내달라.
diff --git a/src/site/ko/markdown/mappers.md b/src/site/ko/markdown/mappers.md
new file mode 100644
index 0000000000..c56ba731ff
--- /dev/null
+++ b/src/site/ko/markdown/mappers.md
@@ -0,0 +1,184 @@
+
+# 매퍼 주입
+
+`SqlSessionDaoSupport` 나 `SqlSessionTemplate` 를 직접적으로 사용하는 데이터 접근 객체(DAO)를 생성하기 보다, 마이바티스 스프링 연동모듈은 다른 빈에 직접 주입할 수 있는 쓰레드에 안전한 매퍼를 생성할 수 있다.
+
+```xml
+
+
+
+```
+
+한번 주입하고나면 매퍼는 애플리케이션 로직에서 사용할수 있는 준비가 된다.
+
+```java
+public class FooServiceImpl implements FooService {
+
+ private final UserMapper userMapper;
+
+ public FooServiceImpl(UserMapper userMapper) {
+ this.userMapper = userMapper;
+ }
+
+ public User doSomeBusinessStuff(String userId) {
+ return this.userMapper.getUser(userId);
+ }
+}
+```
+
+이 코드를 보면 `SqlSession`이나 마이바티스 객체가 보이지 않는다. 게다가 세션을 생성하거나 열고 닫을필요도 없어보인다. 마이바티스 스프링 연동모듈이 알아서 처리할 것이다.
+
+
+## 매퍼 등록하기
+
+매퍼를 등록하는 방법은 기존의 전통적인 XML설정법을 사용하거나 새로운 3.0 이후의 자바설정(일명 `@Configuration`)을 사용하느냐에 따라 다르다.
+
+### XML설정 사용
+
+매퍼는 다음처럼 XML설정파일에 `MapperFactoryBean`을 두는 것으로 스프링에 등록된다.
+
+```xml
+
+
+
+
+```
+
+UserMapper가 매퍼 인터페이스와 같은 경로의 클래스패스에 마이바티스 XML매퍼 파일을 가지고 있다면 `MapperFactoryBean`이 자동으로 파싱할것이다.
+매퍼 XML파일을 다른 클래스패스에 두는게 아니라면 마이바티스 설정파일에 매퍼를 지정할 필요가 없다. 좀더 세부적인 정보는 `SqlSessionFactoryBean`의 [`configLocation`](factorybean.html) 프로퍼티를 살펴보자.
+
+`MapperFactoryBean`은 `SqlSessionFactory` 나 `SqlSessionTemplate`가 필요하다. `sqlSessionFactory` 와 `sqlSessionTemplate` 프로퍼티를 셋팅하면 된다.
+둘다 셋팅하면 `SqlSessionFactory`가 무시된다. 세션 팩토리 셋은 `SqlSessionTemplate`이 필요하고 `MapperFactoryBean`는 팩토리를 사용할것이다.
+
+### 자바설정 사용
+
+```java
+@Configuration
+public class MyBatisConfig {
+ @Bean
+ public MapperFactoryBean userMapper() throws Exception {
+ MapperFactoryBean factoryBean = new MapperFactoryBean<>(UserMapper.class);
+ factoryBean.setSqlSessionFactory(sqlSessionFactory());
+ return factoryBean;
+ }
+}
+```
+
+
+## 매퍼 스캔
+
+하나씩 매퍼를 모두 등록할 필요가 없다. 대신 클래스패스를 지정해서 마이바티스 스프링 연동모듈의 자동스캔기능을 사용할 수 있다.
+
+자동스캔을 사용하는데는 3가지 방법이 있다.
+
+* `` 엘리먼트 사용
+* `@MapperScan` 애노테이션 사용
+* 스프링 XML파일을 사용해서 `MapperScannerConfigurer`를 등록
+
+`` 와 `@MapperScan` 모두 마이바티스 스프링 연동모듈 1.2.0에서 추가된 기능이다. `@MapperScan` 은 스프링 버전이 3.1이상이어야 한다.
+
+Since 2.0.2, mapper scanning feature support a option (`lazy-initialization`) that control lazy initialization enabled/disabled of mapper bean.
+The motivation for adding this option is supporting a lazy initialization control feature supported by Spring Boot 2.2.
+The default of this option is `false` (= not use lazy initialization). If developer want to use lazy initialization for mapper bean, it should be set to the `true` expressly.
+
+IMPORTANT
+If use the lazy initialization feature, the developer need to understand following limitations. If any of following conditions are matches, usually the lazy initialization feature cannot use on your application.
+
+* When refers to the statement of **other mapper** using ``(`@One`) and ``(`@Many`)
+* When includes to the fragment of **other mapper** using ``
+* When refers to the cache of **other mapper** using ``(`@CacheNamespaceRef`)
+* When refers to the result mapping of **other mapper** using `]]>
-
-
sqlSessionFactory: reader에 별도로 구현한 sessionFactory를 지정할 수 있다.
- 이 옵션은 다양한 데이터베이스에서 데이터를 읽을때 유용하다.
-
queryId: 여러개의 테이블에서 데이터를 읽어야 하고 서로 다른 쿼리를 사용한다면
- 서로다른 네임스페이스를 가진 매퍼 파일을 사용하는게 좋을수 있다.
- 쿼리를 알아볼때, 매퍼 파일의 네임스페이스를 잊지 말아야 한다.
-
parameterValues: 이 맵을 사용해서 추가로 파라미터를 전달할 수 있다.
- 위 예제는 jobExecutionContext에서 값들을 가져오는 SpEL표현식을 사용하는 맵을 사용하고 있다.
- 맵의 키는 매퍼파일에서 마이바티스가 사용할 것이다. (예: yesterday 는 #{yesterday,jdbcType=TIMESTAMP} 로 사용될수 있다.).
- 맵과 reader 모두 jobExecutionContext에서 SpEL표현식을 사용하기 위해 step 스코프를 사용한다.
- 마이바티스의 타입핸들러가 제대로 설정이 되었다면 JodaTime날짜를 맵을 사용해서 파라미터로 넘길수 있다.
-
pageSize: 배치가 청크크기가 지정된 형태로 처리가 되면 reader에 이 값을 전달하는게 적절하다.
-
-
-
-
-
-
- 이 빈은 cursor 를 사용하여 데이터베이스에서 레코드를 읽는 ItemReader 이다.
-
-
-
- 중요 이 빈을 사용하려면 최소한 MyBatis 3.4.0 이나 그 이상이어야 한다.
-
-
-
- setQueryId 속성으로 지정된 쿼리를 실행하여 selectCursor() 메서드를 사용하여 요청 된 데이터를 검색한다.
- read() 메서드가 호출 될 때마다 요소가 더 이상 남아 있지 않을 때까지 cursor 의 다음 요소를 반환한다.
-
-
-
- reader 는 별도의 connection 을 사용하므로 select 문은 step processing 일부로 생성된 트랜잭션에 속하지 않는다.
-
-
-
cursor 를 사용할 때 다음과 같이 일반 쿼리를 실행할 수 있다.
-
- SELECT id, name, job FROM employees ORDER BY id ASC
-]]>
-
-
Converting a item that read using ItemReader to an any parameter object:
-
-
- By default behavior, the MyBatisBatchItemWriter passes a item that read using ItemReader
- (or convert by ItemProcessor) to the MyBatis(SqlSession#update()) as the parameter object.
- If you want to customize a parameter object that passes to the MyBatis, you can realize to use the itemToParameterConverter option.
- For example using itemToParameterConverter option, you can passes any objects other than the item object to the MyBatis.
- Follows below a sample:
-
-
-
- At first, you create a custom converter class (or factory method). The following sample uses a factory method.
-
여러개의 테이블에 데이터를 쓰려면 한꺼번에 처리할 수 있도록 만든 writer(몇가지 규칙을 가지고)를 사용하자.
-
-
이 기능은 마이바티스 3.2이상에서만 사용할 수 있다. 이전의 버전에서는 예상과 다르게 동작하는데 그 내용은
- 이슈를 참고하면 된다.
-
-
배치가 관계를 가지는 데이터나 여러개의 데이터베이스를 다루는 것처럼 복잡한 데이터를 작성할때 필요하다면
- insert구문이 한개에 테이블에만 데이터를 넣을수 있다는 사실만 피하면 가능하기도 하다.
- 이런 복잡한 데이터를 처리하기 위해 writer가 작성하는 아이템(Item)을 준비해야 한다.
- 다음의 기술을 사용하면 단순한 관계를 가진 데이터나 관계가 없는 테이블을 처리하는 아이템에서 사용할 수 있다.
-
-
이러한 방법으로 스프링 배치 아이템은 모든 레코드를 다룰것이다.
- 여기에는 1:1 관계를 가지는 InteractionMetadata,
- 관계가 없는 두개의 로우는 VisitorInteraction 와 CustomerInteraction이 있다.
- 이 각각의 객체는 다음과 같이 볼수 있다.
-
-
-
-
그리고 스프링 설정에는 각각의 레코드를 처리하기위해 특별히 설정된
- 전용(delegates) writer를 사용하는 CompositeItemWriter가 있다.
각각의 전용(delegate) writer는 필요할 만큼 설정할 수 있다.
- 예를들면 Interaction 과 InteractionMetadata를 위한 writer가 있다.
-
-
-]]>
-
-
reader와 동일하게 statementId는 네임스페이스를 가진 구문을 가리킬수 있다.
-
-
매퍼 파일에서 구문은 다음과 같은 방법으로 각각의 레코드를 위해 만들어져있다.
-
-
-
-
-
-
-]]>
-
-
먼저 insertInteractionMetadata가 호출될것이고
- update구문은 jdbc드라이버에 의해(keyProperty 와 keyColumn) 생성된 아이디들을 리턴하기 위해 설정되었다.
- InteractionMetadata 객체가 이 쿼리에 의해 업데이트되면 다음의 쿼리는
- insertInteraction를 통해 상위객체인 Interaction를 작성하기 위해 사용될수 있다.
-
-
방금 언급한 내용에 관련하여 JDBC드라이버가 똑같이 동작하지 않을수 있다.
- 이 글을 쓰는 시점에 H2 드라이버 1.3.168버전(org.h2.jdbc.JdbcStatement#getGeneratedKeys를 보라)만 배치모드에서 마지막 인덱스를 리턴한다.
- 반면에 MySQL 드라이버는 기대한 것과 동일하게 동작하고 모든 아이디를 리턴한다.
일반적인 마이바티스 스프링 사용법에서는, SqlSessionFactoryBean이나 관련된 SqlSessionFactory를 직접 사용할 필요가 없다.
- 대신 세션 팩토리가 MapperFactoryBean나 SqlSessionDaoSupport를 확장하는 다른 DAO에 주입될것이다.
-
-
-
-
-
SqlSessionFactory는 JDBC DataSource의 필수 프로퍼티가 필요하다.
- 어떤 DataSource라도 상관없고 다른 스프링 데이터베이스 연결처럼 설정되어야만 한다.
-
-
하나의 공통적인 프로퍼티는 마이바티스 XML설정파일의 위치를 지정하기 위해 사용되는 configLocation이다.
- 이 프로퍼티를 설정하는 것은 디폴트 설정을 가진 마이바티스 설정을 변경해야 할 경우 뿐이다.
- 대개는 <settings>과 <typeAliases> 섹션을 변경하는 경우이다.
-
-
설정파일이 마이바티스 설정을 완전히 다룰 필요는 없다.
- 어떤 환경, 어떤 데이터소스 그리고 마이바티스 트랜잭션 관리자가 무시될수도 있다.
- SqlSessionFactoryBean 는 필요에 따라 이 값들을 설정하여 자체적인 MyBatis Environment 를 만든다.
-
-
설정파일이 필요한 다른 이유는 마이바티스 XML파일이 매퍼 클래스와 동일한 클래스패스에 있지 않은 경우이다.
- 이 설정을 사용하면 두가지 옵션이 있다.
- 첫번째는 마이바티스 설정파일에 <mappers> 섹션을 사용해서 XML파일의 클래스패스를 지정하는 것이다.
- 두번째는 팩토리 빈의 mapperLocations 프로퍼티를 사용하는 것이다.
-
-
mapperLocations 프로퍼티는 매퍼에 관련된 자원의 위치를 나열한다.
- 이 프로퍼티는 마이바티스의 XML매퍼 파일들의 위치를 지정하기 위해 사용될 수 있다.
- 디렉터리 아래 모든 파일을 로드하기 위해 앤트(Ant) 스타일의 패턴을 사용할수도 있고 가장 상위 위치를 지정하는 것으로 재귀적으로 하위 경로를 찾도록 할수도 있다.
- 예를 들어보면 다음과 같다.
-
-
-
-
-]]>
-
-
이 설정은 sample.config.mappers 패키지 아래와 그 하위 패키지를 모두 검색해서 마이바티스 매퍼 XML파일을 모두 로드할 것이다.
-
-
컨테이너 관리 트랜잭션을 사용하는 환경에서 필요한 하나의 프로퍼티는 transactionFactoryClass 이다.
- 이에 관련해서는 트랜잭션을 다루는 장에서 볼수 있다.
-
-
- 만약 multi-db 기능을 사용한다면 다음과 같이 databaseIdProvider 속성을 설정해야 한다.
-
마이바티스를 스프링과 함께 사용하려면 스프링의 애플리케이션 컨텍스트에 적어도 두개를 정의해줄 필요가 있다.
- 두가지는 SqlSessionFactory와 한개 이상의 매퍼 인터페이스이다.
-
-
마이바티스 스프링 연동모듈에서, SqlSessionFactoryBean은 SqlSessionFactory를 만들기 위해 사용된다.
- 팩토리 빈을 설정하기 위해, 스프링 설정파일에 다음 설정을 추가하자.
-
-
-
-
-]]>
-
-
-
-
SqlSessionFactory는 DataSource를 필요로 하는 것을 알아둘 필요가 있다.
- 어떤 DataSource도 상관없지만 다른 스프링의 데이터베이스 연결과 동일하게 설정되어야 한다.
-
-
매퍼 인터페이스가 다음처럼 정의되었다고 가정해보자.
-
-
-
UserMapper인터페이스는 다음처럼 MapperFactoryBean을 사용해서 스프링에 추가된다.
-
-
-
-]]>
-
-
매퍼는 반드시 구현체 클래스가 아닌 인터페이스로 정의되어야 한다.
- 예를들어, 애노테이션이 SQL을 명시하기 위해 사용되지만 마이바티스 매퍼 XML파일 또한 사용될 수 있다.
-
-
한번만 설정하면, 다른 스프링 빈에 주입하는 같은 방법으로 비즈니스/서비스 객체에 매퍼를 직접 주입할 수 있다.
- MapperFactoryBean은 SqlSession을 생성하고 닫는 작업을 잘 다룬다.
- 실행중인 스프링 트랜잭션이 있다면, 트랜잭션이 완료되는 시점에 커밋이나 롤백이 될 것이다.
- 마지막으로 예외가 발생하면 스프링의 DataAccessException예외가 발생한다.
마이바티스 스프링 연동모듈은 마이바티스와 스프링을 편하고 간단하게 연동한다.
- 이 모듈은 마이바티스로 하여금 스프링 트랜잭션에 쉽게 연동되도록 처리한다.
- 게다가 마이바티스 매퍼와 SqlSession을 다루고 다른 빈에 주입시켜준다.
- 마이바티스 예외를 스프링의 DataAccessException로 변환하기도 하고 마이바티스, 스프링 또는 마이바티스 스프링 연동모듈에 의존성을 없애기도 한다.
-
-
-
-
스프링 2.x은 아이바티스 2.x만을 지원한다.
- 스프링 3.x에서 마이바티스 3.x를 지원하기 위한 시도가 진행중이다.
- (스프링의 이슈관리 시스템인 이슈 를 보라.)
- 불행하게도 스프링 3의 개발이 마이바티스 3.0의 정식릴리즈전에 개발이 완료되었다.
- 그래서 스프링팀은 릴리즈가 안된 마이바티스 코드를 함께 릴리즈하는 것을 원하지 않았고 실제적인 스프링 지원을 기다릴수밖에 없었다.
- 스프링의 마이바티스 지원에 대한 관심으로 인해,
- 마이바티스 커뮤니티는 재결합하는 형태로 결정을 내고 대신 마이바티스의 하위 프로젝트 형태로 스프링 연동 프로젝트를 추가한다.
-
-
-
-
마이바티스 스프링 연동을 시작하기 전에, 마이바티스와 스프링의 용어를 맞추는 일이 굉장히 중요했다.
- 이 문서는 배경지식이나 기본적인 셋업방법 그리고 마이바티스와 스프링의 설정에 대한 튜토리얼등은 제공하지 않는다.
-
- MyBatis-Spring requires following versions:
-
-
-
-
-
- MyBatis-Spring
-
-
- MyBatis
-
-
- Spring Framework
-
-
- Spring Batch
-
-
- Java
-
-
-
-
-
-
- 2.0
-
-
- 3.5+
-
-
- 5.0+
-
-
- 4.0+
-
-
- Java 8+
-
-
-
-
- 1.3
-
-
- 3.4+
-
-
- 3.2.2+
-
-
- 2.1+
-
-
- Java 6+
-
-
-
-
-
-
-
-
이 프로젝트가 실제로 만들어지게 도와준 모든 특별한 분들에게 정말 감사한다.
- 알파벳 순서로 보면, 코딩및 테스트 그리고 문서화를 담당했던 Eduardo Macarron, Hunter Presnall, Putthiphong Boonphong;
- 그외 다양한 프로젝트 기여자인 Andrius Juozapaitis, Giovanni Cuccu, Mike Lanyon, Raj Nagappan, Tomas Pinos;
- 그리고 마이바티스에 하위 프로젝트로 가져올수 있도록 많은 것을 찾아준 Simone Tripodi 에게 감사한다. ;)
- 이들이 없었다면 이 프로젝트는 존재하지 않았을 것이다.
-
-
-
-
만약에 어떤 방법으로든 이 문서의 취약점이 발견되거나 기능에 대한 문서화가 빠진 부분이 보인다면,
- 가장 좋은 방법은 먼저 공부해서 자신만의 문서를 작성하는 것이다.
-
-
이 문서의 원본은 xdoc포맷이며 프로젝트의 Git에서 찾을 수 있다.
- repository 를 fork 하고, 업데이트하고 pull request 를 보내주십시오.
-
SqlSessionDaoSupport 나 SqlSessionTemplate 를 직접적으로 사용하는 데이터 접근 객체(DAO)를 생성하기 보다,
- 마이바티스 스프링 연동모듈은 다른 빈에 직접 주입할 수 있는 쓰레드에 안전한 매퍼를 생성할 수 있다.
-
-
-
-]]>
-
-
한번 주입하고나면 매퍼는 애플리케이션 로직에서 사용할수 있는 준비가 된다.
-
-
이 코드를 보면 SqlSession이나 마이바티스 객체가 보이지 않는다.
- 게다가 세션을 생성하거나 열고 닫을필요도 없어보인다.
- 마이바티스 스프링 연동모듈이 알아서 처리할 것이다.
-
-
-
매퍼를 등록하는 방법은 기존의 전통적인 XML설정법을 사용하거나 새로운 3.0 이후의 자바설정(일명 @Configuration)을 사용하느냐에 따라 다르다.
-
-
XML설정 사용
-
-
매퍼는 다음처럼 XML설정파일에 MapperFactoryBean을 두는 것으로 스프링에 등록된다.
-
-
-
-]]>
-
-
UserMapper가 매퍼 인터페이스와 같은 경로의 클래스패스에 마이바티스 XML매퍼 파일을 가지고 있다면 MapperFactoryBean이 자동으로 파싱할것이다.
- 매퍼 XML파일을 다른 클래스패스에 두는게 아니라면 마이바티스 설정파일에 매퍼를 지정할 필요가 없다.
- 좀더 세부적인 정보는 SqlSessionFactoryBean의 configLocation 프로퍼티를 살펴보자.
-
-
MapperFactoryBean은 SqlSessionFactory 나 SqlSessionTemplate가 필요하다.
- sqlSessionFactory 와 sqlSessionTemplate 프로퍼티를 셋팅하면 된다.
- 둘다 셋팅하면 SqlSessionFactory가 무시된다.
- 세션 팩토리 셋은 SqlSessionTemplate이 필요하고 MapperFactoryBean는 팩토리를 사용할것이다.
하나씩 매퍼를 모두 등록할 필요가 없다.
- 대신 클래스패스를 지정해서 마이바티스 스프링 연동모듈의 자동스캔기능을 사용할 수 있다.
-
-
자동스캔을 사용하는데는 3가지 방법이 있다.
-
-
<mybatis:scan/> 엘리먼트 사용
-
@MapperScan 애노테이션 사용
-
스프링 XML파일을 사용해서 MapperScannerConfigurer를 등록
-
-
-
<mybatis:scan/> 와 @MapperScan 모두 마이바티스 스프링 연동모듈 1.2.0에서 추가된 기능이다.
- @MapperScan 은 스프링 버전이 3.1이상이어야 한다.
-
-
- Since 2.0.2, mapper scanning feature support a option (lazy-initialization)
- that control lazy initialization enabled/disabled of mapper bean.
- The motivation for adding this option is supporting a lazy initialization control feature supported by Spring Boot 2.2.
- The default of this option is false (= not use lazy initialization).
- If developer want to use lazy initialization for mapper bean, it should be set to the true expressly.
-
-
- IMPORTANT If use the lazy initialization feature,
- the developer need to understand following limitations. If any of following conditions are matches,
- usually the lazy initialization feature cannot use on your application.
-
-
-
When refers to the statement of other mapper using ]]>(@One) and ]]>(@Many)
-
When includes to the fragment of other mapper using ]]>
-
When refers to the cache of other mapper using ]]>(@CacheNamespaceRef)
-
When refers to the result mapping of other mapper using ]]>(@ResultMap)
-
-
-
- NOTE However, It become possible to use it by simultaneously initializing dependent beans using @DependsOn(Spring's feature) as follow:
-
-
-
-
-
- Since 2.0.6, the develop become can specified scope of mapper using mapper scanning feature option(default-scope)
- and scope annotation(@Scope, @RefreshScope, etc ...).
- The motivation for adding this option is supporting the refresh scope provided by the Spring Cloud.
- The default of this option is empty (= equiv to specify the singleton scope).
- The default-scope apply to the mapper bean(MapperFactoryBean) when scope of scanned bean definition
- is singleton(default scope) and create a scoped proxy bean for scanned mapper when final scope is not singleton.
-
-
-
<mybatis:scan/>
-
-
<mybatis:scan/> XML엘리먼트는 스프링에서 제공하는 <context:component-scan/> 엘리먼트와 매우 유사한 방법으로 매퍼를 검색할 것이다.
-
-
샘플 XML설정을 아래에서 볼수 있다.
-
-
-
-
-
-
-
-]]>
-
-
base-package 속성은 매퍼 인터페이스 파일이 있는 가장 상위 패키지를 지정하면 된다.
- 세미콜론이나 콤마를 구분자로 사용해서 한개 이상의 패키지를 셋팅할 수 있다.
- 매퍼는 지정된 패키지에서 재귀적으로 하위 패키지를 모두 검색할 것이다.
-
-
<mybatis:scan/>이 자동으로 주입할 수 있는 MapperFactoryBean를 생성하기 때문에
- SqlSessionFactory 나 SqlSessionTemplate 를 명시할 필요가 없다.
- 하지만 한개 이상의 DataSource를 사용한다면 자동주입이 생각한데로 동작하지 않을수도 있다.
- 이 경우 사용할 빈 이름을 지정하기 위해 factory-ref 나 template-ref 속성을 사용할수 있다.
-
-
<mybatis:scan/>은 마커(marker) 인터페이스나 애노테이션을 명시해서 생성되는 매퍼를 필터링할수도 있다.
- annotation 프로퍼티는 검색할 애노테이션을 지정한다.
- marker-interface 프로퍼티는 검색할 상위 인터페이스를 지정한다.
- 이 두개의 프로퍼티를 모두 지정하면, 매퍼는 두 조건을 모두 만족하는 인터페이스만을 추가한다.
- 디폴트로 이 두가지 프로퍼티는 모두 null이다.
- 그래서 base-package프로퍼티에 설정된 패키지 아래 모든 인터페이스가 매퍼로 로드될 것이다.
-
-
발견된 매퍼는 자동검색된 컴포넌트를 위한 스프링의 디폴트 명명규칙 전략(see the Spring reference document(Core Technologies -Naming autodetected components-))을 사용해서 빈이름이 명명된다.
- 빈 이름을 정하는 애노테이션이 없다면 매퍼의 이름에서 첫글자를 소문자로 변환한 형태로 빈 이름을 사용할 것이다.
- @Component 나 JSR-330의 @Named 애노테이션이 있다면 애노테이션에 정의한 이름을 그대로 사용할 것이다.
- annotation 프로퍼티를 org.springframework.stereotype.Component,
- javax.inject.Named(자바SE 1.6을 사용한다면) 또는 개발자가 스스로 작성한 애노테이션으로 셋팅할 수 있다.
- 그러면 애노테이션은 마커와 이름을 제공하는 역할로 동작할 것이다.
-
-
- 중요<context:component-scan/> 가 매퍼를 검색해서 등록을 하지 못할수도 있다.
- 매퍼는 인터페이스고 스프링에 빈으로 등록하기 위해서는 각각의 인터페이스를 찾기 위해 스캐너가 MapperFactoryBean 를 생성하는 방법을 알아야만 한다.
-
-
@MapperScan
-
-
@Configuration 라고 불리는 스프링의 자바설정을 사용한다면 <mybatis:scan/>보다는
- @MapperScan를 사용하길 선호할것이다.
-
-
@MapperScan 애노테이션은 다음처럼 사용된다.
-
-
-
-
애노테이션은 앞서 본 <mybatis:scan/> 에서 설명하는 것과 동일하게 동작한다.
- markerInterface 와 annotationClass 프로퍼티를 사용해서 마커 인터페이스와 애노테이션 클래스를 명시하게 한다.
- sqlSessionFactory 와 sqlSessionTemplate 프로퍼티를 사용해서
- SqlSessionFactory 나 SqlSessionTemplate을 제공할 수도 있다.
-
-
- NOTE Since 2.0.4, If basePackageClasses or basePackages are not defined, scanning will occur from the package of the class that declares this annotation.
-
-
-
MapperScannerConfigurer
-
-
MapperScannerConfigurer는 평범한 빈처럼 XML애플리케이션 컨텍스트에 포함된 BeanDefinitionRegistryPostProcessor 이다.
- MapperScannerConfigurer를 셋업하기 위해 다음의 스프링 설정을 추가하자.
-
-
-]]>
-
-
sqlSessionFactory 나 sqlSessionTemplate를 지정할 필요가 있다면 빈참조가 아닌 빈이름이 필요하다.
- value 프로퍼티는 빈 이름을 지정하고 ref 는 빈 참조를 지정하기 때문에 value 프로퍼티를 사용하자.
- ]]>
-
-
중요sqlSessionFactoryBean 과 sqlSessionTemplateBean 프로퍼티는
- 마이바티스 스프링 연동모듈 1.0.2 버전 이상에서만 사용이 가능하다. 하지만 MapperScannerConfigurer는 잦은 에러를 발생시키는
- PropertyPlaceholderConfigurer보다 앞서 실행되기 때문에 이 프로퍼티들은 사용하지 말길 바란다(deprecated).
- 대신 새롭게 추가된 프로퍼티인 sqlSessionFactoryBeanName 과 sqlSessionTemplateBeanName 를 사용하도록 권한다.
- 샘플 코드는 트랜잭션 서비스가 data access layer 에서 도메인 개체를 가져 오는 일반적인 디자인을 보여준다.
-
-
- 다음 FooService.java 는 서비스처럼 작동한다.
-
-
-
- 이것은 트랜잭션 빈이다. 따라서 어떤 메서드든 실행이 되면 트랜잭션이 시작되고 예외가 발생하지 않았을 때 커밋된다.
- 트랜잭션은 @Transactional annotation 을 통해 설정할 수 있다.
- 이것은 필수가 아니다. Spring이 제공하는 다른 방법을 사용하여 트랜잭션을 구분할 수 있다.
-
-
- 이 서비스는 MyBatis로 이루어진 DAO layer 를 호출한다.
- 이 layer는 런타임시 MyBatis에 의해 작성되고 Spring에 의해 서비스에 주입되는 동적 프록시와 함께 사용되는 UserMapper.java 인터페이스로 구성된다.
-
-
-
- 단순함을 위해서 DAO가 인터페이스와 그 구현체로 만들어진 DAO 시나리오를 위해 UserMapper.java 인터페이스를 사용했지만,
- 이 경우 대신 UserDao.java라는 인터페이스를 사용하는 것이 더 적절하다.
-
-
- 매퍼 인터페이스를 찾고 Spring에 등록하고 서비스 빈에 주입하는 여러 가지 방법을 살펴본다.
-
-
-
시나리오
-
-
-
샘플 테스트
-
설명
-
-
-
-
-
- SampleMapperTest.java
-
-
- UserMapper 구현체를 동적으로 빌드 할 MapperFactoryBean에 기반한 기본 구성을 보여준다.
-
-
-
-
- SampleScannerTest.java
-
-
- MapperScannerConfigurer 를 사용하여 어떻게 프로젝트의 모든 매퍼들을 자동으로 검색되도록 하는 방법을 보여준다.
-
-
-
-
- SampleSqlSessionTest.java
-
-
- Spring에서 관리하는 SqlSession을 사용하여 DAO를 코딩하고 자체적인 구현체인 UserDaoImpl.java 를 제공하는 방법을 보여준다.
-
-
-
-
- SampleEnableTest
-
-
- 스프링의 @Configuration과 @MapperScann annotation을 함께 사용하여 매퍼를 자동으로 검색하는 방법을 보여준다.
-
-
-
-
- SampleNamespaceTest
-
-
- 커스텀 MyBatis XML 네임스페이스를 사용하는 방법을 보여준다.
-
-
-
-
- SampleJavaConfigTest.java
-
-
- 스프링의 @Configuration을 사용하여 MyBatis 빈들을 수동적으로 생성하는 방법을 보여준다.
-
-
-
-
- SampleJobJavaConfigTest.java
-
-
- Java Configuration을 이용하여 Spring Batch에서 어떻게 ItemReader과 ItemWriter를 사용하는지 보여준다.
-
-
-
-
- SampleJobXmlConfigTest.java
-
-
- XML Configuration을 이용하여 Spring Batch에서 어떻게 ItemReader과 ItemWriter를 사용하는지 보여준다.
-
-
-
-
-
- MyBatis-Spring이 실제로 어떻게 다르게 작동하는지 보려면 applicationContext.xml 파일을 살펴보십시오.
-
마이바티스에서는 SqlSession를 생성하기 위해 SqlSessionFactory를 사용한다.
- 세션을 한번 생성하면 매핑구문을 실행하거나 커밋 또는 롤백을 하기 위해 세션을 사용할수 있다.
- 마지막으로 더 이상 필요하지 않은 상태가 되면 세션을 닫는다.
- 마이바티스 스프링 연동모듈을 사용하면 SqlSessionFactory를 직접 사용할 필요가 없다.
- 왜냐하면, 스프링 트랜잭션 설정에 따라 자동으로 커밋 혹은 롤백을 수행하고 닫혀지는, 쓰레드에 안전한 SqlSession 개체가 스프링 빈에 주입될 수 있기 때문이다.
-
-
-
SqlSessionTemplate은 마이바티스 스프링 연동모듈의 핵심이다.
- SqlSessionTemplate은 SqlSession을 구현하고 코드에서 SqlSession를 대체하는 역할을 한다.
- SqlSessionTemplate 은 쓰레드에 안전하고 여러개의 DAO나 매퍼에서 공유할수 있다.
-
-
getMapper()에 의해 리턴된 매퍼가 가진 메서드를 포함해서 SQL을 처리하는 마이바티스 메서드를 호출할때
- SqlSessionTemplate은 SqlSession이 현재의 스프링 트랜잭션에서 사용될수 있도록 보장한다.
- 추가적으로 SqlSessionTemplate은 필요한 시점에 세션을 닫고, 커밋하거나 롤백하는 것을 포함한 세션의 생명주기를 관리한다.
- 또한 마이바티스 예외를 스프링의 DataAccessException로 변환하는 작업또한 처리한다.
-
-
SqlSessionTemplate은 마이바티스의 디폴트 구현체인 DefaultSqlSession 대신 항상 사용된다.
- 왜냐하면 템플릿은 스프링 트랜잭션의 일부처럼 사용될 수 있고 여러개 주입된 매퍼 클래스에 의해 사용되도록 쓰레드에 안전하다.
- 동일한 애플리케이션에서 두개의 클래스간의 전환은 데이터 무결성 이슈를 야기할수 있다.
-
-
SqlSessionTemplate은 생성자 인자로 SqlSessionFactory를 사용해서 생성될 수 있다.
-
-
-]]>
-
-
-
-
이 빈은 DAO빈에 직접 주입될 수 있다. 다음처럼 빈 설정에서 SqlSession 프로퍼티를 설정하면 된다.
-
-
그리고 다음처럼 SqlSessionTemplate 를 주입하자.
-
-
-]]>
-
-
SqlSessionTemplate은 인자로 ExecutorType를 가지는 생성자를 가지고 있다.
- 이 인자는 예를들면 스프링 설정 XML을 다음처럼 설정해서 배치형태의 SqlSession를 만들수도 있다.
-
-
-
-]]>
-
-
-
-
DAO의 코드를 다음처럼 작성했다면 모든 구문은 배치형태로 실행이 될 것이다.
- users) {
- for (User user : users) {
- sqlSession.insert("org.mybatis.spring.sample.mapper.UserMapper.insertUser", user);
- }
-}]]>
-
-
이러한 설정형태는 SqlSessionFactory의 디폴트 형태가 아닌 다른형태로 메서드를 실행해야 할때만 사용할 필요가 있다.
-
-
이러한 형태에 대해 굳이 경로를 하자면 메서드를 호출할때 ExecutorType이 다르면 이미 시작된 트랜잭션을 사용하지 못할것이다.
- 다른 실행자(executor) 타입을 사용할때는 SqlSessionTemplate의 메서드를 구분된 트랜잭션(PROPAGATION_REQUIRES_NEW를 사용하는)이나 트랜잭션 외부에서 호출하는지 확실히해야 한다.
-
-
-
-
SqlSessionDaoSupport는 SqlSession을 제공하는 추상클래스이다.
- getSqlSession()메서드를 호출해서 다음처럼 SQL을 처리하는 마이바티스 메서드를 호출하기 위해 사용할 SqlSessionTemplate을 얻을 수 있다.
-
-
대개 MapperFactoryBean은 추가적인 코드가 필요없기 때문에 이 클래스를 선호한다.
- 하지만 DAO에서 마이바티스가 필요하지 않고 구현된 클래스가 필요하지 않을때만 유용하다.
-
-
SqlSessionDaoSupport는 sqlSessionFactory 와 sqlSessionTemplate 프로퍼티를 셋팅할 필요가 있다.
- 두개의 프로퍼티를 모두 셋팅하면 sqlSessionFactory는 무시된다.
-
-
SqlSessionDaoSupport의 하위클래스인 UserDaoImpl가 있다고 하면 스프링에서는 다음처럼 설정될 수 있다.
마이바티스 스프링 연동모듈을 사용하는 중요한 이유중 하나는 마이바티스가 스프링 트랜잭션에 자연스럽게 연동될수 있다는 것이다.
- 마이바티스에 종속되는 새로운 트랜잭션 관리를 만드는 것보다는 마이바티스 스프링 연동모듈이 스프링의 DataSourceTransactionManager과 융합되는 것이 좋다.
-
스프링 트랜잭션 관리자를 한번 설정하면, 대개의 경우처럼 스프링에서 트랜잭션을 설정할 수 있다.
- @Transactional 애노테이션과 AOP스타일의 설정 모두 지원한다.
- 하나의 SqlSession객체가 생성되고 트랜잭션이 동작하는 동안 지속적으로 사용될것이다.
- 세션은 트랜잭션이 완료되면 적절히 커밋이 되거나 롤백될것이다.
-
마이바티스 스프링 연동모듈은 한번 셋업되면 트랜잭션을 투명하게 관리한다.
- DAO클래스에 어떠한 추가적인 코드를 넣을 필요가 없다.
-
-
-
스프링 트랜잭션을 가능하게 하려면, 스프링 설정파일에 DataSourceTransactionManager를 생성하자.
-
-
-]]>
-
-
-
-
명시된 DataSource는 스프링을 사용할때 일반적으로 사용한다면 어떠한 JDBC DataSource도 될수 있다.
- JNDI룩업을 통해 얻어진 DataSource뿐 아니라 커넥션 풀링 기능도 포함한다.
-
트랜잭션 관리자에 명시된 DataSource가 SqlSessionFactoryBean을 생성할때 사용된 것과 반드시 동일한 것이어야 하는 것만 꼭 기억하자.
- 그렇지 않으면 트랜잭션 관리가 제대로 되지 않을것이다.
-
-
-
-
만약에 JEE컨테이너를 사용하고 스프링을 컨테이너 관리 트랜잭션(container managed transactions, CMT)에 두려한다면,
- 스프링은 JtaTransactionManager나 그 하위 클래스로 설정되어야 한다.
- 이러한 설정을 가장 쉽게 하는 방법은 스프링의 트랜잭션 네임스페이스 or JtaTransactionManagerFactoryBean 를 사용하는 것이다.
-
- ]]>
-
-
-
-
이 설정에서, 마이바티스는 CMT와 함께 설정된 스프링 트랜잭션 리소스처럼 동작할 것이다.
- 스프링은 이미 설정된 트랜잭션을 사용해서 SqlSession을 이미 동작중인 트랜잭션에 넣을 것이다.
- 시작된 트랜잭션이 없고 트랜잭션이 필요한 경우라면 스프링은 새로운 컨테이너 관리 트랜잭션을 시작할 것이다.
-
CMT는 사용하지만 스프링 트랜잭션 관리를 원하지 않는다면 어떠한 스프링 트랜잭션 관리자를 설정해서도 안되고
- 마이바티스 ManagedTransactionFactory를 사용하기 위해 SqlSessionFactoryBean를 설정해야만 한다.
-
-
-
-
-
-]]>
-
-
-
-
-
-
-
마이바티스 SqlSession은 트랜잭션을 제어하는 메서드를 제공한다.
- 하지만 마이바티스 스프링 연동모듈은 빈을 스프링이 관리하는 SqlSession이나 스프링이 관리하는 매퍼에 주입한다.
- 이 말은 스프링이 항상 트랜잭션을 관리한다는 뜻이다.
-
스프링이 관리하는 SqlSession에서는 SqlSession.commit(), SqlSession.rollback()
- 또는 SqlSession.close() 메서드를 호출할수가 없다.
- 그럼에도 불구하고 이 메서드들을 사용하면 UnsupportedOperationException 예외가 발생한다.
- 이러한 메서드는 주입된 매퍼 클래스에서는 사용할 수 없다.
-
JDBC연결의 자동커밋 설정을 어떻게 하더라도 스프링 트랜잭션 밖의 SqlSession 데이터 메서드나 매퍼 메서드의 실행은 자동으로 커밋된다.
MyBatis-Spring 연동 모듈을 사용해도 계속해서 MyBatis API를 직접 사용할 수 있다.
- SqlSessionFactoryBean을 사용해서 스프링에서 SqlSessionFactory를 생성하고 팩토리를 사용하면 된다.
-
-
-
이 방법은 신중히 사용하자. 왜냐하면 잘못사용하면 런타임 에러나 데이터 문제등을 야기할수 있기 때문이다.
- API를 직접 사용할때는 다음의 규칙들에 유의해야 한다.
-
-
-
스프링 트랜잭션에 속하지 않고 별도의 트랜잭션에서 동작한다.
-
-
-
SqlSession이 스프링 트랜잭션 관리자가 사용하는 DataSource를 사용하고
- 이미 트랜잭션이 동작하고 있다면 이 코드는 예외를 발생시킬 것이다.
-
-
-
마이바티스의 DefaultSqlSession은 쓰레드에 안전하지 않다.
- 빈에 이 객체를 주입하면 아마도 에러를 발생시킬 수 있다.
-
-
-
DefaultSqlSession을 사용해서 생성한 매퍼 또한 쓰레드에 안전하지 않다.
- 이렇게 만든 매퍼를 빈에 주입하면 에러를 발생시킬 수 있다.
-
-
-
SqlSession은 항상 마지막에 close() 메서드를 호출해야 한다.
-
-
-
-
-
diff --git a/src/site/markdown/README.md b/src/site/markdown/README.md
new file mode 100644
index 0000000000..74036dbd21
--- /dev/null
+++ b/src/site/markdown/README.md
@@ -0,0 +1,18 @@
+# Table of contents
+
+This page is for rendering index on GitHub.
+
+> **NOTE:**
+>
+> Since the link destination is specified on the assumption that it is converted to html with maven-site-plugin, there is an anchor that is broken in the rendering on GitHub.
+
+* [Introduction](./index.md)
+* [Getting Started](./getting-started.md)
+* [SqlSessionFactoryBean](./factorybean.md)
+* [Transactions](./transactions.md)
+* [Using an SqlSession](./sqlsession.md)
+* [Injecting Mappers](./mappers.md)
+* [Spring Boot](./boot.md)
+* [Using the MyBatis API](./using-api.md)
+* [Spring Batch](./batch.md)
+* [Sample Code](./sample.md)
diff --git a/src/site/markdown/batch.md b/src/site/markdown/batch.md
new file mode 100644
index 0000000000..a6ad50418c
--- /dev/null
+++ b/src/site/markdown/batch.md
@@ -0,0 +1,359 @@
+
+# Spring Batch
+
+As of version 1.1.0 MyBatis-Spring provides three beans for building Spring Batch applications: the `MyBatisPagingItemReader`, the `MyBatisCursorItemReader` and the `MyBatisBatchItemWriter`.
+Also, As of version 2.0.0 provides three builder classes for supporting the Java Configuration: the `MyBatisPagingItemReaderBuilder`, the `MyBatisCursorItemReaderBuilder` and the `MyBatisBatchItemWriterBuilder`.
+
+NOTE
+This is about [Spring Batch](http://static.springsource.org/spring-batch/) and not about MyBatis batch SqlSessions. For information about batch sessions go to section [Using an SqlSession](sqlsession.html).
+
+## MyBatisPagingItemReader
+
+This bean is an `ItemReader` that reads records from a database in a paging fashion.
+
+It executes the query specified as the `setQueryId` property to retrieve requested data.
+The query is executed using paged requests of a size specified in `setPageSize` property.
+Additional pages are requested when needed as `read()` method is called, returning an object corresponding to current position.
+
+Some standard query parameters are provided by the reader and the SQL in the named query must use some or all of these parameters (depending on the SQL variant) to construct a result set of the required size.
+The parameters are:
+
+* `_page`: the page number to be read (starting at 0)
+* `_pagesize`: the size of the pages, i.e. the number of rows to return
+* `_skiprows`: the product of `_page` and `_pagesize`
+
+And they could be mapped as the follow in a select statement:
+
+```xml
+
+```
+
+Follows below a sample configuration snippet:
+
+```xml
+
+
+
+
+```
+
+```java
+@Configuration
+public class BatchAppConfig {
+ @Bean
+ public MyBatisPagingItemReader reader() {
+ return new MyBatisPagingItemReaderBuilder()
+ .sqlSessionFactory(sqlSessionFactory())
+ .queryId("com.my.name.space.batch.EmployeeMapper.getEmployee")
+ .build();
+ }
+}
+```
+
+**Explaining a more complex example:**
+
+```xml
+
+```
+```xml
+
+
+
+
+
+
+```
+
+```java
+@Configuration
+public class BatchAppConfig {
+ @StepScope
+ @Bean
+ public MyBatisPagingItemReader dateBasedCriteriaReader(
+ @Value("#{@datesParameters}") Map datesParameters) throws Exception {
+ return new MyBatisPagingItemReaderBuilder()
+ .sqlSessionFactory(batchReadingSessionFactory())
+ .queryId("com.my.name.space.batch.ExampleMapper.queryUserInteractionsOnSpecificTimeSlot")
+ .parameterValues(datesParameters)
+ .pageSize(200)
+ .build();
+ }
+
+ @StepScope
+ @Bean
+ public Map datesParameters(
+ @Value("#{jobExecutionContext['EXTRACTION_START_DATE']}") LocalDate yesterday,
+ @Value("#{jobExecutionContext['TODAY_DATE']}") LocalDate today,
+ @Value("#{jobExecutionContext['FIRST_DAY_OF_THE_MONTH_DATE']}") LocalDate firstDayOfTheMonth,
+ @Value("#{jobExecutionContext['FIRST_DAY_OF_THE_PREVIOUS_MONTH_DATE']}") LocalDate firstDayOfThePreviousMonth) {
+ Map map = new HashMap<>();
+ map.put("yesterday", yesterday);
+ map.put("today", today);
+ map.put("first_day_of_the_month", firstDayOfTheMonth);
+ map.put("first_day_of_the_previous_month", firstDayOfThePreviousMonth);
+ return map;
+ }
+}
+```
+
+The previous example makes use of a few different things:
+
+* `sqlSessionFactory`: You can specify your own sessionFactory to the reader, it might be useful if you want to read from several databases.
+
+* `queryId`: If the base code have several tables or databases to read from, and that you have different queries, it might be interesting to use different mapper files with different namespaces.
+ so when referring to the query, don't forget about the namespace of the mapper file.
+
+* `parameterValues`: You can pass additional parameters via this map, the example above uses a map that is build by spring using a SpEL expression taking values from the `jobExecutionContext`.
+ The keys of the map will be used by MyBatis in the mapper file (ex: *yesterday* could be used as `#{yesterday,jdbcType=TIMESTAMP}`).
+ Note that the map and the reader are both built in the `step` scope in order to be able to use the Spring EL expression with the `jobExecutionContext`.
+ Also if MyBatis type handlers are correctly configured you can pass custom instances like the parameters of this map that are JodaTime dates.
+
+* `pageSize`: If the batch flow is configured with chunk size, it is relevant to pass this information to the reader as well, which is done via this property.
+
+## MyBatisCursorItemReader
+
+This bean is an `ItemReader` that reads records from a database using a cursor.
+
+NOTE
+To use this bean you need at least MyBatis 3.4.0 or a newer version.
+
+It executes the query specified as the `setQueryId` property to retrieve requested data by using the method `selectCursor()`.
+Each time a `read()` method is called it will return the next element of the cursor until no more elements are left.
+
+The reader will use a separate connection so the select statement does no participate in any transactions created as part of the step processing.
+
+When using the cursor you can just execute a regular query:
+
+```xml
+
+```
+
+Follows below a sample configuration snippet:
+
+```xml
+
+
+
+
+```
+
+```java
+@Configuration
+public class BatchAppConfig {
+ @Bean
+ public MyBatisCursorItemReader reader() {
+ return new MyBatisCursorItemReaderBuilder()
+ .sqlSessionFactory(sqlSessionFactory())
+ .queryId("com.my.name.space.batch.EmployeeMapper.getEmployee")
+ .build();
+ }
+}
+```
+
+## MyBatisBatchItemWriter
+
+It is an `ItemWriter` that uses the batching features from `SqlSessionTemplate` to execute a batch of statements for all items provided.
+The `SqlSessionFactory` needs to be configured with a `BATCH` executor.
+
+When `write()` is called it executes the mapped statement indicated in the property `statementId`. It is expected that `write()` is called inside a transaction.
+
+Follows below a sample configuration snippet:
+
+```xml
+
+
+
+
+```
+
+```java
+@Configuration
+public class BatchAppConfig {
+ @Bean
+ public MyBatisBatchItemWriter writer() {
+ return new MyBatisBatchItemWriterBuilder()
+ .sqlSessionFactory(sqlSessionFactory())
+ .statementId("com.my.name.space.batch.EmployeeMapper.updateEmployee")
+ .build();
+ }
+}
+```
+
+**Converting a item that read using ItemReader to an any parameter object:**
+
+By default behavior, the `MyBatisBatchItemWriter` passes a item that read using `ItemReader` (or convert by `ItemProcessor`) to the MyBatis(`SqlSession#update()`) as the parameter object.
+If you want to customize a parameter object that passes to the MyBatis, you can realize to use the `itemToParameterConverter` option.
+For example using `itemToParameterConverter` option, you can passes any objects other than the item object to the MyBatis.
+Follows below a sample:
+
+At first, you create a custom converter class (or factory method). The following sample uses a factory method.
+
+```java
+public class ItemToParameterMapConverters {
+ public static Converter> createItemToParameterMapConverter(String operationBy, LocalDateTime operationAt) {
+ return item -> {
+ Map parameter = new HashMap<>();
+ parameter.put("item", item);
+ parameter.put("operationBy", operationBy);
+ parameter.put("operationAt", operationAt);
+ return parameter;
+ };
+ }
+}
+```
+
+At next, you write a sql mapping.
+
+```xml
+
+```
+
+At last, you configure the MyBatisBatchItemWriter.
+
+```java
+@Configuration
+public class BatchAppConfig {
+ @Bean
+ public MyBatisBatchItemWriter writer() throws Exception {
+ return new MyBatisBatchItemWriterBuilder()
+ .sqlSessionFactory(sqlSessionFactory())
+ .statementId("org.mybatis.spring.sample.mapper.PersonMapper.createPerson")
+ .itemToParameterConverter(createItemToParameterMapConverter("batch_java_config_user", LocalDateTime.now()))
+ .build();
+ }
+}
+```
+
+```xml
+
+
+
+
+
+
+
+
+
+
+```
+
+**Writing to different tables using composite writers (with some caveats):**
+
+This technique can only be used with MyBatis 3.2+, as there was an [issue](http://code.google.com/p/mybatis/issues/detail?id=741) in previous versions that made the writer misbehave.
+
+If the batch needs to write complex data, like records with associations, or even to different databases, then it is possible to work around the fact that insert statements only insert in one table.
+In order to make it happen the batch have to prepare the *Item* to be written by the writer.
+However depending on the constraints, opportunities or insight on the processed data it might be interesting to use the following technique.
+The following trick can work on items with simple associations or just with unrelated tables.
+
+In a processor craft the Spring Batch Item in such way it will *hold* all the different records.
+Suppose for each Item there is an *Interaction* that have one association *InteractionMetadata*,
+and two non associated rows *VisitorInteraction* and *CustomerInteraction*, the holder object will look like:
+
+```java
+public class InteractionRecordToWriteInMultipleTables {
+ private final VisitorInteraction visitorInteraction;
+ private final CustomerInteraction customerInteraction;
+ private final Interaction interaction;
+ // ...
+}
+```
+```java
+public class Interaction {
+ private final InteractionMetadata interactionMetadata;
+}
+```
+
+Then in the spring configuration there will be a `CompositeItemWriter` that will use delegate writers specifically configured for each kind of records.
+Note that as the *InteractionMetadata* is an association in the example it will need to be written first so that Interaction can have the updated key.
+
+```xml
+
+
+
+
+
+
+
+
+
+
+
+
+```
+
+```java
+@Configuration
+public class BatchAppConfig {
+ @Bean
+ public CompositeItemWriter> interactionsItemWriter() {
+ CompositeItemWriter compositeItemWriter = new CompositeItemWriter();
+ List> writers = new ArrayList<>(4);
+ writers.add(visitorInteractionsWriter());
+ writers.add(customerInteractionsWriter());
+ writers.add(interactionMetadataWriter());
+ writers.add(interactionWriter());
+ compositeItemWriter.setDelegates(writers);
+ return compositeItemWriter;
+ }
+}
+```
+
+Then each delegate writer will be configured as needed; for example for *Interaction* and *InteractionMetadata*:
+
+```xml
+
+```
+```xml
+
+```
+
+Same as the reader the `statementId` can refer to the statement with the prefixed namespace.
+
+Now in the mapper file the statement have to be crafted for each kind of records in the following way:
+
+```xml
+
+
+
+```
+```xml
+
+
+
+```
+
+What's happening is that first the `insertInteractionMetadata` will be called, and the update statement is configured to return the ids created by the jdbc driver (`keyProperty` and `keyColumn`).
+As the `InteractionMetadata` object were updated by this query the next query can be used to write the parent object `Interaction` via `insertInteraction`.
+
+***However note that JDBC drivers don't behave the same in this regard. At the time of this writing the H2 driver 1.3.168 will only return the latest index even in BATCH mode (see `org.h2.jdbc.JdbcStatement#getGeneratedKeys`),
+while the MySQL JDBC driver will behave as expected and return all the IDs.***
diff --git a/src/site/markdown/boot.md b/src/site/markdown/boot.md
new file mode 100644
index 0000000000..678db5d753
--- /dev/null
+++ b/src/site/markdown/boot.md
@@ -0,0 +1,4 @@
+
+# Using Spring Boot
+
+Please see the [MyBatis Spring-boot-starter](http://www.mybatis.org/spring-boot-starter/mybatis-spring-boot-autoconfigure) sub project docs for details.
diff --git a/src/site/markdown/factorybean.md b/src/site/markdown/factorybean.md
new file mode 100644
index 0000000000..cf403649f8
--- /dev/null
+++ b/src/site/markdown/factorybean.md
@@ -0,0 +1,100 @@
+
+# SqlSessionFactoryBean
+
+In base MyBatis, the `SqlSessionFactory` is built using `SqlSessionFactoryBuilder`. In MyBatis-Spring, `SqlSessionFactoryBean` is used instead.
+
+## Setup
+
+To create the factory bean, put the following in the Spring XML configuration file:
+
+```xml
+
+
+
+```
+Note that `SqlSessionFactoryBean` implements Spring's `FactoryBean` interface see [the Spring documentation(Core Technologies -Customizing instantiation logic with a FactoryBean-)](https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#beans-factory-extension-factorybean)).
+This means that the bean Spring ultimately creates is **not** the `SqlSessionFactoryBean` itself, but what the factory returns as a result of the `getObject()` call on the factory.
+In this case, Spring will build an `SqlSessionFactory` for you at application startup and store it with the name `sqlSessionFactory`.
+In Java, the equivalent code would be:
+
+```java
+@Configuration
+public class MyBatisConfig {
+ @Bean
+ public SqlSessionFactory sqlSessionFactory() {
+ SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
+ factoryBean.setDataSource(dataSource());
+ return factoryBean.getObject();
+ }
+}
+```
+
+In normal MyBatis-Spring usage, you will not need to use `SqlSessionFactoryBean` or the corresponding `SqlSessionFactory` directly.
+Instead, the session factory will be injected into `MapperFactoryBean`s or other DAOs that extend `SqlSessionDaoSupport`.
+
+## Properties
+
+`SqlSessionFactory` has a single required property, the JDBC `DataSource`. This can be any `DataSource` and should be configured just like any other Spring database connection.
+
+One common property is `configLocation` which is used to specify the location of the MyBatis XML configuration file.
+One case where this is needed is if the base MyBatis configuration needs to be changed. Usually this will be `` or `` sections.
+
+Note that this config file does **not** need to be a complete MyBatis config. Specifically, any environments, data sources and MyBatis transaction managers will be **ignored**.
+`SqlSessionFactoryBean` creates its own, custom MyBatis `Environment` with these values set as required.
+
+Another reason to require a config file is if the MyBatis mapper XML files are not in the same classpath location as the mapper classes. With this configuration, there are two options.
+This first is to manually specify the classpath of the XML files using a `` section in the MyBatis config file. A second option is to use the `mapperLocations` property of the factory bean.
+
+The `mapperLocations` property takes a list of resource locations. This property can be used to specify the location of MyBatis XML mapper files.
+The value can contain Ant-style patterns to load all files in a directory or to recursively search all paths from a base location.
+
+For example:
+
+```xml
+
+
+
+
+```
+
+This will load all the MyBatis mapper XML files in the `sample.config.mappers` package and its sub-packages from the classpath.
+
+One property that may be required in an environment with container managed transactions is `transactionFactoryClass`. Please see the relevant section in the Transactions chapter.
+
+In case you are using the multi-db feature you will need to set the `databaseIdProvider` property:
+
+```xml
+
+
+
+ sqlserver
+ db2
+ oracle
+ mysql
+
+
+
+```
+```xml
+
+
+
+
+
+```
+
+NOTE
+Since 1.3.0, `configuration` property has been added. It can be specified a `Configuration` instance directly without MyBatis XML configuration file.
+
+For example:
+
+```xml
+
+
+
+
+
+
+
+
+```
diff --git a/src/site/markdown/getting-started.md b/src/site/markdown/getting-started.md
new file mode 100644
index 0000000000..c33f7f393d
--- /dev/null
+++ b/src/site/markdown/getting-started.md
@@ -0,0 +1,100 @@
+
+# Getting Started
+
+This chapter will show you in a few steps how to install and setup MyBatis-Spring and how to build a simple transactional application.
+
+## Installation
+
+To use the MyBatis-Spring module, you just need to include the `mybatis-spring-${project.version}.jar` file and its dependencies in the classpath.
+
+If you are using Maven just add the following dependency to your pom.xml:
+
+```xml
+
+ org.mybatis
+ mybatis-spring
+ ${project.version}
+
+```
+
+## Quick Setup
+
+To use MyBatis with Spring you need at least two things defined in the Spring application context:
+an `SqlSessionFactory` and at least one mapper interface.
+
+In MyBatis-Spring, an `SqlSessionFactoryBean` is used to create an `SqlSessionFactory`. To configure the factory bean, put the following in the Spring configuration file:
+
+```xml
+
+
+
+```
+
+```java
+@Configuration
+public class MyBatisConfig {
+ @Bean
+ public SqlSessionFactory sqlSessionFactory() throws Exception {
+ SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
+ factoryBean.setDataSource(dataSource());
+ return factoryBean.getObject();
+ }
+}
+```
+
+Notice that the `SqlSessionFactory` requires a `DataSource`. This can be any `DataSource` and should be configured just like any other Spring database connection.
+
+Assume you have a mapper interface defined like the following:
+
+```java
+public interface UserMapper {
+ @Select("SELECT * FROM users WHERE id = #{userId}")
+ User getUser(@Param("userId") String userId);
+}
+```
+
+This interface is added to Spring using a `MapperFactoryBean` like the following:
+
+```xml
+
+
+
+
+```
+
+Note that the mapper class specified **must** be an interface, not an actual implementation class. In this example, annotations are used to specify the SQL, but a MyBatis mapper XML file could also be used.
+
+Once configured, you can inject mappers directly into your business/service objects in the same way you inject any other Spring bean.
+The `MapperFactoryBean` handles creating an `SqlSession` as well as closing it.
+If there is a Spring transaction in progress, the session will also be committed or rolled back when the transaction completes.
+Finally, any exceptions will be translated into Spring `DataAccessException`s.
+
+If you use the Java Configuration:
+
+```java
+@Configuration
+public class MyBatisConfig {
+ @Bean
+ public UserMapper userMapper() throws Exception {
+ SqlSessionTemplate sqlSessionTemplate = new SqlSessionTemplate(sqlSessionFactory());
+ return sqlSessionTemplate.getMapper(UserMapper.class);
+ }
+}
+```
+
+Calling MyBatis data methods is now only one line of code:
+
+```java
+public class FooServiceImpl implements FooService {
+
+ private final UserMapper userMapper;
+
+ public FooServiceImpl(UserMapper userMapper) {
+ this.userMapper = userMapper;
+ }
+
+ public User doSomeBusinessStuff(String userId) {
+ return this.userMapper.getUser(userId);
+ }
+}
+```
diff --git a/src/site/markdown/index.md b/src/site/markdown/index.md
new file mode 100644
index 0000000000..c7b577c2ff
--- /dev/null
+++ b/src/site/markdown/index.md
@@ -0,0 +1,54 @@
+
+# Introduction
+
+## What is MyBatis-Spring?
+
+MyBatis-Spring integrates MyBatis seamlessly with Spring.
+This library allows MyBatis to participate in Spring transactions, takes care of building MyBatis mappers and `SqlSession`s and inject them into other beans, translates MyBatis exceptions into Spring `DataAccessException`s, and finally, it lets you build your application code free of dependencies on MyBatis, Spring or MyBatis-Spring.
+
+## Motivation
+
+Spring version 2 only supports iBATIS version 2. An attempt was made to add MyBatis 3 support into Spring 3 (see the Spring Jira [issue](https://jira.springsource.org/browse/SPR-5991).
+Unfortunately, Spring 3 development ended before MyBatis 3 was officially released. Because the Spring team did not want to release with code based on a non-released version of MyBatis, official Spring support would have to wait.
+Given the interest in Spring support for MyBatis, the MyBatis community decided it was time to reunite the interested contributors and add Spring integration as a community sub-project of MyBatis instead.
+
+## Requirements
+
+Before starting with MyBatis-Spring integration, it is very important that you are familiar with both MyBatis and Spring terminology.
+This document does not attempt to provide background information or basic setup and configuration tutorials for either MyBatis or Spring.
+
+MyBatis-Spring requires following versions:
+
+| MyBatis-Spring | MyBatis | Spring Framework | Spring Batch | Java |
+| --- | --- | --- | --- | --- |
+| **2.0** | 3.5+ | 5.0+ | 4.0+ | Java 8+ |
+| **1.3** | 3.4+ | 3.2.2+ | 2.1+ | Java 6+ |
+
+## Acknowledgements
+
+A special thanks goes to all the special people who made this project a reality (in alphabetical order): Eduardo Macarron, Hunter Presnall and Putthiphong Boonphong for the coding,
+testing and documentation; Andrius Juozapaitis, Giovanni Cuccu, Mike Lanyon, Raj Nagappan and Tomas Pinos for their contributions; and Simone Tripodi for finding everyone and bringing them all back to the project under MyBatis ;)
+Without them, this project wouldn't exist.
+
+## Help make this documentation better…
+
+If you find this documentation lacking in any way, or missing documentation for a feature, then the best thing to do is learn about it and then write the documentation yourself!
+
+Sources of this manual are available in markdown format at [project's Git](https://github.com/mybatis/spring/tree/master/src/site) Fork the repository, update them and send a pull request.
+
+You’re the best author of this documentation, people like you have to read it!
+
+## Translations
+
+Users can read about MyBatis-Spring in the following translations:
+
+
+
+Do you want to read about MyBatis in your own native language? Fill an issue providing patches with your mother tongue documentation!
+
diff --git a/src/site/markdown/mappers.md b/src/site/markdown/mappers.md
new file mode 100644
index 0000000000..7153f7385d
--- /dev/null
+++ b/src/site/markdown/mappers.md
@@ -0,0 +1,182 @@
+
+# Injecting Mappers
+
+Rather than code data access objects (DAOs) manually using `SqlSessionDaoSupport` or `SqlSessionTemplate`, Mybatis-Spring can create a thread safe mapper that you can inject directly into other beans:
+
+```xml
+
+
+
+```
+
+Once injected, the mapper is ready to be used in application logic:
+
+```java
+public class FooServiceImpl implements FooService {
+
+ private final UserMapper userMapper;
+
+ public FooServiceImpl(UserMapper userMapper) {
+ this.userMapper = userMapper;
+ }
+
+ public User doSomeBusinessStuff(String userId) {
+ return this.userMapper.getUser(userId);
+ }
+}
+```
+
+Notice that there are no `SqlSession` or MyBatis references in this code. Nor is there any need to create, open or close the session, MyBatis-Spring will take care of that.
+
+
+## Registering a mapper
+
+The way you register a mapper depends on whether you are using a classic XML configuration or the new 3.0+ Java Config (a.k.a. `@Configuration`).
+
+### With XML Config
+
+A mapper is registered to Spring by including a `MapperFactoryBean` in your XML config file like follows:
+
+```xml
+
+
+
+
+```
+
+If the UserMapper has a corresponding MyBatis XML mapper file in the same classpath location as the mapper interface, it will be parsed automatically by the `MapperFactoryBean`.
+There is no need to specify the mapper in a MyBatis configuration file unless the mapper XML files are in a different classpath location. See the `SqlSessionFactoryBean`'s `[configLocation](factorybean.html)` property for more information.
+
+Note that `MapperFactoryBean` requires either an `SqlSessionFactory` or an `SqlSessionTemplate`. These can be set through the respective `sqlSessionFactory` and `sqlSessionTemplate` properties.
+If both properties are set, the `SqlSessionFactory` is ignored. Since the `SqlSessionTemplate` is required to have a session factory set, that factory will be used by `MapperFactoryBean`.
+
+### With Java Config
+
+```java
+@Configuration
+public class MyBatisConfig {
+ @Bean
+ public MapperFactoryBean userMapper() throws Exception {
+ MapperFactoryBean factoryBean = new MapperFactoryBean<>(UserMapper.class);
+ factoryBean.setSqlSessionFactory(sqlSessionFactory());
+ return factoryBean;
+ }
+}
+```
+
+
+## Scanning for mappers
+
+There is no need to register all your mappers one by one. Instead, you can let MyBatis-Spring scan your classpath for them.
+
+There are three different ways to do it:
+
+* Using the `` element.
+* Using the annotation `@MapperScan`
+* Using a classic Spring xml file and registering the `MapperScannerConfigurer`
+
+Both `` and `@MapperScan` are features introduced in MyBatis-Spring 1.2.0. `@MapperScan` requires Spring 3.1+.
+
+Since 2.0.2, mapper scanning feature support an option (`lazy-initialization`) that control lazy initialization enabled/disabled of mapper bean.
+The motivation for adding this option is supporting a lazy initialization control feature supported by Spring Boot 2.2. The default of this option is `false` (= not use lazy initialization).
+If developer want to use lazy initialization for mapper bean, it should be set to the `true` expressly.
+
+IMPORTANT
+If use the lazy initialization feature, the developer need to understand following limitations. If any of following conditions are matches, usually the lazy initialization feature cannot use on your application.
+
+* When refers to the statement of **other mapper** using ``(`@One`) and ``(`@Many`)
+* When includes to the fragment of **other mapper** using ``
+* When refers to the cache of **other mapper** using ``(`@CacheNamespaceRef`)
+* When refers to the result mapping of **other mapper** using `]]>
-
-
- The previous example makes use of a few different things:
-
-
-
-
sqlSessionFactory: You can specify your own sessionFactory to the reader, it might be
- useful if you want to read from several databases.
-
queryId: If the base code have several tables or databases to read from, and that you have different
- queries, it might be interesting to use different mapper files with different namespaces.
- so when referring to the query, don't forget about the namespace of the mapper file.
-
parameterValues: You can pass additional parameters via this map, the example above uses
- a map that is build by spring using a SpEL expression taking values from the jobExecutionContext.
- The keys of the map will be used by MyBatis in the mapper file (ex:
- yesterday could be used as #{yesterday,jdbcType=TIMESTAMP}).
- Note that the map and the reader are both built in the step scope in order to be able to use
- the Spring EL expression with the jobExecutionContext. Also if MyBatis type handlers
- are correctly configured you can pass custom instances like the parameters of this map that are JodaTime
- dates.
-
pageSize: If the batch flow is configured with chunk size, it is relevant to pass this
- information to the reader as well, which is done via this property.
-
-
-
-
-
-
- This bean is an ItemReader that reads records from a database using a cursor.
-
-
-
- NOTE To use this bean you need at least MyBatis 3.4.0 or a newer version.
-
-
-
- It executes the query specified as the setQueryId property to retrieve requested data
- by using the method selectCursor().
- Each time a read() method is called it will return the next element of the cursor until no more
- elements are left.
-
-
-
- The reader will use a separate connection so the select statement does no participate in any transactions created
- as part of the step processing.
-
-
-
When using the cursor you can just execute a regular query:
-
- SELECT id, name, job FROM employees ORDER BY id ASC
-]]>
-
-
- It is an ItemWriter that uses the batching features from SqlSessionTemplate
- to execute a batch of statements for all items provided.
- The SqlSessionFactory needs to be configured with a BATCH executor.
-
-
-
- When write() is called it executes the mapped statement indicated in the property statementId.
- It is expected that write() is called inside a transaction.
-
Converting a item that read using ItemReader to an any parameter object:
-
-
- By default behavior, the MyBatisBatchItemWriter passes a item that read using ItemReader
- (or convert by ItemProcessor) to the MyBatis(SqlSession#update()) as the parameter object.
- If you want to customize a parameter object that passes to the MyBatis, you can realize to use the itemToParameterConverter option.
- For example using itemToParameterConverter option, you can passes any objects other than the item object to the MyBatis.
- Follows below a sample:
-
-
-
- At first, you create a custom converter class (or factory method). The following sample uses a factory method.
-
Writing to different tables using composite writers (with some caveats):
-
-
This technique can only be used with MyBatis 3.2+, as there was an
- issue in previous
- versions that made the writer misbehave.
-
-
-
If the batch needs to write complex data, like records with associations, or even to different databases, then
- it is possible to work around the fact that insert statements only insert in one table. In order to make it
- happen the batch have to prepare the Item to be written by the writer. However depending on the
- constraints, opportunities or insight on the processed data it might be interesting to use the following technique.
- The following trick can work on items with simple associations or just with unrelated tables.
-
-
-
In a processor craft the Spring Batch Item in such way it will hold all the different records.
- Suppose for each Item there is an Interaction that have one association
- InteractionMetadata, and two non associated rows VisitorInteraction and
- CustomerInteraction, the holder object will look like:
-
-
-
-
-
Then in the spring configuration there will be a CompositeItemWriter that will use delegate
- writers specifically configured for each kind of records. Note that as the InteractionMetadata is
- an association in the example it will need to be written first so that Interaction can have the updated key.
-
Then each delegate writer will be configured as needed; for example for Interaction and
- InteractionMetadata:
-
-
-
-]]>
-
-
Same as the reader the statementId can refer to the statement with the prefixed namespace.
-
-
Now in the mapper file the statement have to be crafted for each kind of records in the following way:
-
-
-
-
-
-
-]]>
-
-
What's happening is that first the insertInteractionMetadata will be called, and the update
- statement is configured to return the ids created by the jdbc driver (keyProperty and keyColumn).
- As the InteractionMetadata object were updated by this query the next query can be used to write the parent
- object Interaction via insertInteraction.
-
-
-
However note that JDBC drivers don't behave the same in this regard. At the time of this writing
- the H2 driver 1.3.168 will only return the latest index even in BATCH mode (see org.h2.jdbc.JdbcStatement#getGeneratedKeys),
- while the MySQL JDBC driver will behave as expected and return all the IDs.
-
- In base MyBatis, the SqlSessionFactory is built using
- SqlSessionFactoryBuilder. In MyBatis-Spring,
- SqlSessionFactoryBean is used instead.
-
-
-
-
- To create the factory bean, put the following in the Spring XML
- configuration file:
-
-
-
-]]>
-
- Note that
- SqlSessionFactoryBean
- implements Spring's
- FactoryBean
- interface (see the Spring documentation(Core Technologies -Customizing instantiation logic with a FactoryBean-)).
- This means that the bean Spring ultimately creates is
- not
- the
- SqlSessionFactoryBean
- itself, but what the
- factory returns as a result of the
- getObject()
- call on
- the factory. In this case, Spring will build an
- SqlSessionFactory
- for you at application startup and
- store it with the name
- sqlSessionFactory
- . In Java, the
- equivalent code would be:
-
-
-
-
-
- In normal MyBatis-Spring usage, you will not need to use
- SqlSessionFactoryBean
- or the corresponding
- SqlSessionFactory
- directly. Instead, the session
- factory will be injected into
- MapperFactoryBeans or
- other DAOs that extend
- SqlSessionDaoSupport
- .
-
-
-
-
-
-
- SqlSessionFactory
- has a single required property, the
- JDBC
- DataSource
- . This can be any
- DataSource
- and should be configured just
- like any other Spring database
- connection.
-
-
-
- One common property is
- configLocation
- which is used to
- specify the location of the MyBatis XML
- configuration file. One case
- where this is needed is if the base
- MyBatis configuration needs to be
- changed. Usually this will be
- <settings>
- or
- <typeAliases>
- sections.
-
-
-
- Note that this config file does
- not
- need to be a
- complete MyBatis config. Specifically, any environments,
- data sources
- and MyBatis transaction managers will be
- ignored
- .
- SqlSessionFactoryBean
- creates its own, custom MyBatis
- Environment
- with these values set as required.
-
-
-
- Another reason to require a config file is if the MyBatis mapper XML
- files are not in the same classpath location as the mapper classes.
- With
- this configuration, there are two options. This first is to
- manually
- specify the classpath of the XML files using a
- <mappers>
- section in the MyBatis config
- file. A second option is to use the
- mapperLocations
- property of the factory bean.
-
-
-
- The
- mapperLocations
- property takes a list of resource
- locations. This property can be
- used to specify the location of MyBatis
- XML mapper files. The value
- can contain Ant-style patterns to load all
- files in a directory or to
- recursively search all paths from a base
- location. For example:
-
-
-
-
-
-]]>
-
-
- This will load all the MyBatis mapper XML files in the
- sample.config.mappers package and its sub-packages from the
- classpath.
-
-
-
- One property that may be required in an environment with container
- managed transactions is
- transactionFactoryClass
- .
- Please see the relevant section in the
- Transactions chapter.
-
-
-
- In case you are using the multi-db feature you will need to set the databaseIdProvider property:
-
- NOTE
- Since 1.3.0, configuration property has been added.
- It can be specified a Configuration instance directly without MyBatis XML configuration file.
- For example:
-
- This chapter will show you in a few steps how to install and setup
- MyBatis-Spring and how to build
- a simple transactional application.
-
-
-
-
- To use the MyBatis-Spring module, you just need to include the
- mybatis-spring-${project.version}.jar
- file and its dependencies in the classpath.
-
-
- If you are using Maven just add the following dependency
- to your
- pom.xml:
-
- To use MyBatis with Spring you need at least two things defined in
- the
- Spring application context: an
- SqlSessionFactory
- and
- at least one mapper interface.
-
-
-
- In MyBatis-Spring, an
- SqlSessionFactoryBean
- is used to
- create an
- SqlSessionFactory
- . To configure the
- factory bean, put the following in the Spring
- configuration file:
-
-
-
-
-]]>
-
-
-
-
- Notice that the
- SqlSessionFactory
- requires a
- DataSource
- . This can be any
- DataSource
- and should be configured just like any other Spring database
- connection.
-
-
-
- Assume you have a mapper interface defined like the following:
-
-
-
-
- This interface is added to Spring using a
- MapperFactoryBean
- like the following:
-
-
-
-
-]]>
-
-
- Note that the mapper class specified
- must
- be an
- interface, not an actual implementation class. In this example,
- annotations are used to specify the SQL, but a MyBatis mapper XML
- file
- could also be used.
-
-
-
- Once configured, you can inject mappers directly into your
- business/service objects in the same way you inject any other Spring
- bean. The MapperFactoryBean
- handles creating an SqlSession
- as well as closing it. If there is a Spring transaction in
- progress,
- the session will also be committed or rolled back when the
- transaction completes. Finally, any exceptions will be translated
- into Spring DataAccessExceptions.
-
-
-
- If you use the Java Configuration:
-
-
-
-
-
- Calling MyBatis data methods is now only one line of code:
-
- MyBatis-Spring integrates MyBatis seamlessly with Spring.
- This library allows MyBatis to participate in Spring transactions, takes care of
- building MyBatis mappers and SqlSessions and inject them into other beans,
- translates MyBatis exceptions into Spring DataAccessExceptions,
- and finally, it lets you build your application code free of
- dependencies on MyBatis, Spring or MyBatis-Spring.
-
-
-
-
-
- Spring version 2 only supports iBATIS version 2. An attempt was made to
- add MyBatis 3 support into Spring 3 (see the Spring Jira
- issue).
- Unfortunately, Spring 3 development ended before MyBatis 3 was
- officially released. Because the Spring team did not want to release with
- code based on a non-released version of MyBatis, official Spring support
- would have to wait. Given the interest in Spring support for MyBatis,
- the MyBatis community decided it was time to reunite the interested contributors
- and add Spring integration as a community sub-project of MyBatis instead.
-
-
-
-
-
- Before starting with MyBatis-Spring integration, it is very important
- that you are familiar with both MyBatis and Spring terminology. This
- document does not attempt to provide background information or basic
- setup and configuration tutorials for either MyBatis or Spring.
-
-
- MyBatis-Spring requires following versions:
-
-
-
-
-
- MyBatis-Spring
-
-
- MyBatis
-
-
- Spring Framework
-
-
- Spring Batch
-
-
- Java
-
-
-
-
-
-
- 2.0
-
-
- 3.5+
-
-
- 5.0+
-
-
- 4.0+
-
-
- Java 8+
-
-
-
-
- 1.3
-
-
- 3.4+
-
-
- 3.2.2+
-
-
- 2.1+
-
-
- Java 6+
-
-
-
-
-
-
-
-
- A special thanks goes to all the special people who made this project
- a reality (in alphabetical order): Eduardo Macarron, Hunter Presnall
- and Putthiphong Boonphong for the coding, testing and documentation;
- Andrius Juozapaitis, Giovanni Cuccu, Mike Lanyon, Raj Nagappan and Tomas Pinos
- for their contributions; and Simone Tripodi for finding everyone and
- bringing them all back to the project under MyBatis ;) Without them,
- this project wouldn't exist.
-
-
-
-
-
- If you find this documentation lacking in any way, or missing
- documentation for a feature, then the best thing to do is learn
- about it and then write the documentation yourself!
-
-
- Sources of this manual are available in xdoc format at
- project's Git
- Fork the repository, update them and send a pull request.
-
-
- You’re the best author of this documentation, people like you have
- to read it!
-
-
-
-
-
Users can read about MyBatis-Spring in the following translations:
- Rather than code data access objects (DAOs) manually using
- SqlSessionDaoSupport or
- SqlSessionTemplate, Mybatis-Spring can create a
- thread safe mapper that you can inject directly into other beans:
-
-
-
-
-]]>
-
-
- Once injected, the mapper is ready to be used in application logic:
-
-
-
- Notice that there are no SqlSession or MyBatis
- references in this code. Nor is there any need to create, open or close
- the session, MyBatis-Spring will take care of that.
-
-
-
-
- The way you register a mapper depends on whether you are using a classic XML configuration
- or the new 3.0+ Java Config (a.k.a. @Configuration).
-
-
With XML Config
-
-
- A mapper is registered to Spring by including a MapperFactoryBean in your XML
- config file like follows:
-
-
-
-
-]]>
-
-
- If the UserMapper has a corresponding MyBatis XML mapper file
- in the same classpath location as the mapper interface, it will be
- parsed automatically by the MapperFactoryBean. There
- is no need to specify the mapper in a MyBatis configuration file unless
- the mapper XML files are in a different classpath location. See the
- SqlSessionFactoryBean's
- configLocation
- property for more information.
-
-
-
- Note that MapperFactoryBean requires either an
- SqlSessionFactory or an SqlSessionTemplate.
- These can be set through the respective sqlSessionFactory and
- sqlSessionTemplate properties.
- If both properties are set, the SqlSessionFactory is ignored.
- Since the SqlSessionTemplate is required to have a session
- factory set, that factory will be used by MapperFactoryBean.
-
- There is no need to register all your mappers one by one.
- Instead, you can let MyBatis-Spring scan your classpath for them.
-
-
-
- There are three different ways to do it:
-
-
-
Using the <mybatis:scan/> element.
-
Using the annotation @MapperScan
-
Using a classic Spring xml file and registering the MapperScannerConfigurer
-
-
-
Both <mybatis:scan/> and @MapperScan are features introduced in MyBatis-Spring 1.2.0.
- @MapperScan requires Spring 3.1+.
-
-
- Since 2.0.2, mapper scanning feature support a option (lazy-initialization)
- that control lazy initialization enabled/disabled of mapper bean.
- The motivation for adding this option is supporting a lazy initialization control feature supported by Spring Boot 2.2.
- The default of this option is false (= not use lazy initialization).
- If developer want to use lazy initialization for mapper bean, it should be set to the true expressly.
-
-
- IMPORTANT If use the lazy initialization feature,
- the developer need to understand following limitations. If any of following conditions are matches,
- usually the lazy initialization feature cannot use on your application.
-
-
-
When refers to the statement of other mapper using ]]>(@One) and ]]>(@Many)
-
When includes to the fragment of other mapper using ]]>
-
When refers to the cache of other mapper using ]]>(@CacheNamespaceRef)
-
When refers to the result mapping of other mapper using ]]>(@ResultMap)
-
-
-
- NOTE However, It become possible to use it by simultaneously initializing dependent beans using @DependsOn(Spring's feature) as follow:
-
-
-
-
-
- Since 2.0.6, the develop become can specified scope of mapper using mapper scanning feature option(default-scope)
- and scope annotation(@Scope, @RefreshScope, etc ...).
- The motivation for adding this option is supporting the refresh scope provided by the Spring Cloud.
- The default of this option is empty (= equiv to specify the singleton scope).
- The default-scope apply to the mapper bean(MapperFactoryBean) when scope of scanned bean definition
- is singleton(default scope) and create a scoped proxy bean for scanned mapper when final scope is not singleton.
-
-
-
<mybatis:scan/>
-
-
- The <mybatis:scan/> XML element will search for mappers
- in a very similar way than the Spring built-in element <context:component-scan/>
- searches for beans.
-
-
-
Follows below a sample XML configuration:
-
-
-
-
-
-
-
-]]>
-
-
- The base-package attribute lets you set the base package
- for your mapper interface files. You can set more than one package by
- using a semicolon or comma as a separator. Mappers will be searched for
- recursively starting in the specified package(s).
-
-
-
- Notice that there is no need to specify a SqlSessionFactory or
- SqlSessionTemplate as an attribute in the <mybatis:scan/>
- element because it will create MapperFactoryBeans that can be autowired.
- But if you are using more than one DataSource autowire may not work for you.
- In this case you can use the factory-ref or
- template-ref attributes to set the right bean name to use.
-
-
-
- <mybatis:scan/> supports filtering the mappers
- created by either specifying a marker interface or an annotation. The
- annotation property specifies an annotation to
- search for. The marker-interface attribute specifies a
- parent interface to search for. If both properties are specified, mappers
- are added for interfaces that match either criteria.
- By default, these two properties are null, so all interfaces in the given
- base package(s) will be loaded as mappers.
-
-
-
- Discovered mappers will be named using Spring default naming strategy for
- autodetected components (see the Spring reference document(Core Technologies -Naming autodetected components-)).
- That is, if no annotation is found, it will use the uncapitalized non-qualified class
- name of the mapper. But if either a @Component or a JSR-330 @Named annotation is
- found it will get the name from the annotation.
- Notice that you can set the annotation attribute
- to org.springframework.stereotype.Component,
- javax.inject.Named (if you have JSE 6) or to your own annotation
- (that must be itself annotated) so the annotation will work both as a marker
- and as a name provider.
-
-
-
- NOTE<context:component-scan/>
- won't be able to scan and register mappers. Mappers are interfaces and, in order to register them to
- Spring, the scanner must know how to create a MapperFactoryBean for each interface
- it finds.
-
-
-
@MapperScan
-
-
- If you are using the Spring Java Configuration (a.k.a @Configuration) you would
- prefer to use the @MapperScan rather than the
- <mybatis:scan/>.
-
-
-
The @MapperScan annotation is used as follows:
-
-
-
-
The annotation works in the same exact way than <mybatis:scan/> we
- saw in the previous section. It also lets you specify a marker interface or an annotation class
- through its properties markerInterface and annotationClass.
- You can also provide an specific SqlSessionFactory or SqlSessionTemplate
- by using its properties sqlSessionFactory and sqlSessionTemplate.
-
-
-
- NOTE Since 2.0.4, If basePackageClasses or basePackages are not defined, scanning will occur from the package of the class that declares this annotation.
-
-
-
MapperScannerConfigurer
-
-
- The MapperScannerConfigurer is a BeanDefinitionRegistryPostProcessor that
- can be included in a classic xml application context as a normal bean.
- To set up a MapperScannerConfigurer add the following to the Spring configuration:
-
-
-
-]]>
-
-
- If you need to specify an specific sqlSessionFactory or sqlSessionTemplate
- note that bean names are required,
- not bean references, thus the value attribute is used instead of the
- usual ref:
-
- ]]>
-
-
- NOTEsqlSessionFactoryBean and
- sqlSessionTemplateBean properties were the only option available up to MyBatis-Spring 1.0.2
- but given that the MapperScannerConfigurer runs earlier in the startup
- process that PropertyPlaceholderConfigurer there were frequent errors.
- For that purpose that properties have been deprecated and the new properties
- sqlSessionFactoryBeanName and sqlSessionTemplateBeanName
- are recommended.
-
- NOTE
- See JPetstore 6 demo to know about how to use Spring with a full web application server.
-
-
-
- You can check out sample code from the MyBatis-Spring repo:
-
-
- Any of the samples can be run with JUnit 5.
-
-
- The sample code shows a typical design where a transactional service gets domain objects from a data access layer.
-
-
- FooService.java acts as the service:
-
-
-
- It is a transactional bean, so when the method is called, the transaction is started
- and the transaction is committed when the method ends without throwing an uncaught exception.
- Notice that transactional behaviour is configured with the
- @Transactional
- attribute. This is not required; any other way provided by Spring can be used to demarcate
- your transactions.
-
-
- This service calls a data access layer built with MyBatis. This layer
- consists on a just an interface UserMapper.java
- that will be used with a dynamic proxy built by MyBatis at
- runtime and injected into the service by Spring.
-
-
-
- Note that, for the sake of simplicity we used the interface UserMapper.java for the DAO scenario
- where a DAO is built with an interface and a implementation though in this case it would have been more
- adequate to use an interface called UserDao.java instead.
-
-
- We will see different ways to find the mapper interface, register it to Spring and inject it into the service bean:
-
-
-
Scenarios
-
-
-
Sample test
-
Description
-
-
-
-
-
- SampleMapperTest.java
-
-
- Shows you the base configuration based on a MapperFactoryBean
- that will dynamically build an implementation for UserMapper
-
-
-
-
- SampleScannerTest.java
-
-
- Shows how to use the MapperScannerConfigurer so all the mappers in a project are autodiscovered.
-
-
-
-
- SampleSqlSessionTest.java
-
-
- Shows how to hand code a DAO using a Spring managed SqlSession
- and providing your own implementation UserDaoImpl.java.
-
-
-
-
- SampleEnableTest
-
-
- Shows how to use Spring's @Configuration with the @MapperScann annotation so
- mappers are autodiscovered.
-
-
-
-
- SampleNamespaceTest
-
-
- Shows how to use the custom MyBatis XML namespace.
-
-
-
-
- SampleJavaConfigTest.java
-
-
- Shows how to use Spring's @Configuration to create MyBatis beans manually.
-
-
-
-
- SampleJobJavaConfigTest.java
-
-
- Shows how to use ItemReader and ItemWriter on Spring Batch using Java Configuration.
-
-
-
-
- SampleJobXmlConfigTest.java
-
-
- Shows how to use ItemReader and ItemWriter on Spring Batch using XML Configuration.
-
-
-
-
-
- Please take a look at the different applicationContext.xml files to see MyBatis-Spring in action.
-
- In MyBatis you use the SqlSessionFactory to create an
- SqlSession. Once you have a session, you use it to
- execute your mapped statements, commit or rollback connections and
- finally, when it is no longer needed, you close the session. With
- MyBatis-Spring you don't need to use SqlSessionFactory
- directly because your beans can be injected with a thread safe
- SqlSession that automatically commits, rollbacks and
- closes the session based on Spring's transaction configuration.
-
-
-
-
- SqlSessionTemplate is the heart of MyBatis-Spring.
- It implements SqlSession and is meant to be a drop-in replacement
- for any existing use of SqlSession in your code.
- SqlSessionTemplate is thread safe and can be shared
- by multiple DAOs or mappers.
-
-
-
- When calling SQL methods, including any method from Mappers returned by
- getMapper(), SqlSessionTemplate
- will ensure that the SqlSession used is the one
- associated with the current Spring transaction. In addition, it manages
- the session life-cycle, including closing, committing or rolling back the
- session as necessary. It will also translate MyBatis exceptions
- into Spring DataAccessExceptions.
-
-
-
- SqlSessionTemplate should always
- be used instead of default MyBatis implementation DefaultSqlSession
- because the template can participate in Spring transactions and is thread safe for use by
- multiple injected mapper classes. Switching between the two classes in the
- same application can cause data integrity issues.
-
-
-
- A SqlSessionTemplate can be constructed
- using an SqlSessionFactory as a constructor argument.
-
-
-
-]]>
-
-
-
-
- This bean can now be injected directly in your DAO beans. You need a
- SqlSession property in your bean like the following
-
-
-
- And inject the SqlSessionTemplate as follows
-
-
-
-]]>
-
-
- SqlSessionTemplate has also a constructor that takes
- an ExecutorType as an argument. This allows you to
- construct, for example, a batch SqlSession by using
- the following in Spring's configuration file:
-
-
-
-
-]]>
-
-
-
-
- Now all your statements will be batched so the following could be coded
- in a DAO
-
- users) {
- for (User user : users) {
- sqlSession.insert("org.mybatis.spring.sample.mapper.UserMapper.insertUser", user);
- }
-}]]>
-
-
- Note that this configuration style only needs to be used if the desired
- execution method differs from the default set for the
- SqlSessionFactory.
-
-
-
- The caveat to this form is that
- there cannot be an existing transaction running with
- a different ExecutorType when this method is called. Either ensure that
- calls to SqlSessionTemplates with different executor
- types run in a separate transaction (e.g. with PROPAGATION_REQUIRES_NEW) or
- completely outside of a transaction.
-
-
-
-
-
- SqlSessionDaoSupport is an abstract support class that
- provides you with a SqlSession. Calling
- getSqlSession() you will get a SqlSessionTemplate
- which can then be used to execute SQL methods, like the following:
-
-
-
- Usually MapperFactoryBean is preferred to this class,
- since it requires no extra code. But, this class is useful if you need
- to do other non-MyBatis work in your DAO and concrete classes are
- required.
-
-
-
- SqlSessionDaoSupport requires either an
- sqlSessionFactory or an sqlSessionTemplate
- property to be set.
- If both properties are set, the sqlSessionFactory is ignored.
-
-
-
- Assuming a class UserDaoImpl that subclasses
- SqlSessionDaoSupport, it can be configured in Spring
- like the following:
-
- One of the primary reasons for using MyBatis-Spring is that it allows
- MyBatis to participate in Spring transactions. Rather than create a new
- transaction manager specific to MyBatis, MyBatis-Spring leverages the
- existing DataSourceTransactionManager in Spring.
-
-
- Once a Spring transaction manager is configured, you can configure
- transactions in Spring as you normally would. Both
- @Transactional annotations and AOP style
- configurations are supported. A single SqlSession
- object will be created and used for the duration of the transaction. This
- session will be committed or rolled back as appropriate when then
- transaction completes.
-
-
- MyBatis-Spring will transparently manage transactions once they are set up.
- There is no need for additional code in your DAO classes.
-
-
-
-
- To enable Spring transaction processing, simply create a
- DataSourceTransactionManager in your Spring
- configuration file:
-
-
-
-
-]]>
-
-
-
-
- The DataSource specified can be any JDBC
- DataSource you would normally
- use with Spring. This includes connection pools as well as DataSources
- obtained through JNDI lookups.
-
-
- Note that the DataSource specified for the transaction
- manager must be the same one that is used to create
- the SqlSessionFactoryBean or transaction management will
- not work.
-
-
-
-
-
- If you are using a JEE container and would like Spring to participate in
- container managed transactions (CMT), then Spring should be configured
- with a JtaTransactionManager or one of its container
- specific subclasses. The easiest way to do this is to use the Spring
- transaction namespace or the JtaTransactionManagerFactoryBean:
-
- ]]>
-
-
-
-
- In this configuration, MyBatis will behave like any other Spring
- transactional resource configured with CMT. Spring will automatically use
- any existing container transaction and attach an SqlSession to it. If no
- transaction is started and one is needed based on the transaction
- configuration, Spring will start a new container managed transaction.
-
-
- Note that if you want to use CMT and do not want to
- use Spring transaction management, you must not
- configure any Spring transaction manager and you must
- also configure the SqlSessionFactoryBean to use the base
- MyBatis ManagedTransactionFactory:
-
-
-
-
-
-
-]]>
-
-
-
-
-
-
- MyBatis SqlSession provides you with specific methods to handle
- transactions programmatically. But when using MyBatis-Spring your beans will be
- injected with a Spring managed SqlSession or a Spring managed mapper.
- That means that Spring will always handle your transactions.
-
-
- You cannot call SqlSession.commit(), SqlSession.rollback()
- or SqlSession.close() over a Spring managed SqlSession.
- If you try to do so, a UnsupportedOperationException exception
- will be thrown. Note these methods are not exposed in injected mapper classes.
-
-
- Regardless of your JDBC connection's autocommit setting, any execution of a
- SqlSession data method or any call to a mapper
- method outside a Spring transaction will be automatically committed.
-
- With MyBatis-Spring, you can continue to directly use the MyBatis API.
- Simply create an SqlSessionFactory in Spring using
- SqlSessionFactoryBean and use the factory in your code.
-
-
-
-
- Use this option with care because wrong usage may produce runtime errors or
- worse, data integrity problems. Be aware of the following caveats with direct API usage:
-
-
-
-
- It will not participate in any Spring transactions.
-
-
-
-
- If the SqlSession is using a DataSource
- that is also being used by a Spring transaction manager and there is currently
- a transaction in progress, this code will throw an exception.
-
-
-
-
- MyBatis' DefaultSqlSession is not thread safe. If you
- inject it in your beans you will get errors.
-
-
-
-
- Mappers created using DefaultSqlSession are not thread safe either.
- If you inject them it in your beans you will get errors.
-
-
-
-
- You must make sure that your SqlSessions
- are always closed in a finally block.
-
+
+想用自己的母语阅读这篇文档吗?那就用你的母语翻译它吧!
diff --git a/src/site/zh/markdown/mappers.md b/src/site/zh/markdown/mappers.md
new file mode 100644
index 0000000000..2be7d90375
--- /dev/null
+++ b/src/site/zh/markdown/mappers.md
@@ -0,0 +1,183 @@
+
+# 注入映射器
+
+与其在数据访问对象(DAO)中手工编写使用 `SqlSessionDaoSupport` 或 `SqlSessionTemplate` 的代码,还不如让 Mybatis-Spring 为你创建一个线程安全的映射器,这样你就可以直接注入到其它的 bean 中了:
+
+```xml
+
+
+
+```
+
+注入完毕后,映射器就可以在你的应用逻辑代码中使用了:
+
+```java
+public class FooServiceImpl implements FooService {
+
+ private final UserMapper userMapper;
+
+ public FooServiceImpl(UserMapper userMapper) {
+ this.userMapper = userMapper;
+ }
+
+ public User doSomeBusinessStuff(String userId) {
+ return this.userMapper.getUser(userId);
+ }
+}
+```
+
+注意代码中并没有任何的对 `SqlSession` 或 MyBatis 的引用。你也不需要担心创建、打开、关闭 session,MyBatis-Spring 将为你打理好一切。
+
+
+## 注册映射器
+
+注册映射器的方法根据你的配置方法,即经典的 XML 配置或新的 3.0 以上版本的 Java 配置(也就是常说的 `@Configuration`),而有所不同。
+
+### XML 配置
+
+在你的 XML 中加入 `MapperFactoryBean` 以便将映射器注册到 Spring 中。就像下面一样:
+
+```xml
+
+
+
+
+```
+
+如果映射器接口 UserMapper 在相同的类路径下有对应的 MyBatis XML 映射器配置文件,将会被 `MapperFactoryBean` 自动解析。不需要在 MyBatis 配置文件中显式配置映射器,除非映射器配置文件与接口类不在同一个类路径下。
+参考 `SqlSessionFactoryBean` 的 [`configLocation`](factorybean.html) 属性以获取更多信息。
+
+注意 `MapperFactoryBean` 需要配置一个 `SqlSessionFactory` 或 `SqlSessionTemplate`。它们可以分别通过 `sqlSessionFactory` 和 `sqlSessionTemplate` 属性来进行设置。
+如果两者都被设置,`SqlSessionFactory` 将被忽略。由于 `SqlSessionTemplate` 已经设置了一个 session 工厂,`MapperFactoryBean` 将使用那个工厂。
+
+### Java 配置
+
+```java
+@Configuration
+public class MyBatisConfig {
+ @Bean
+ public MapperFactoryBean userMapper() throws Exception {
+ MapperFactoryBean factoryBean = new MapperFactoryBean<>(UserMapper.class);
+ factoryBean.setSqlSessionFactory(sqlSessionFactory());
+ return factoryBean;
+ }
+}
+```
+
+
+## 发现映射器
+
+不需要一个个地注册你的所有映射器。你可以让 MyBatis-Spring 对类路径进行扫描来发现它们。
+
+
+有几种办法来发现映射器:
+
+* 使用 `` 元素
+* 使用 `@MapperScan` 注解
+* 在经典 Spring XML 配置文件中注册一个 `MapperScannerConfigurer`
+
+`` 和 `@MapperScan` 都在 MyBatis-Spring 1.2.0 中被引入。`@MapperScan` 需要你使用 Spring 3.1+。
+
+Since 2.0.2, mapper scanning feature support a option (`lazy-initialization`) that control lazy initialization enabled/disabled of mapper bean.
+The motivation for adding this option is supporting a lazy initialization control feature supported by Spring Boot 2.2. The default of this option is `false` (= not use lazy initialization).
+If developer want to use lazy initialization for mapper bean, it should be set to the `true` expressly.
+
+IMPORTANT
+If use the lazy initialization feature, the developer need to understand following limitations.
+If any of following conditions are matches, usually the lazy initialization feature cannot use on your application.
+
+* When refers to the statement of **other mapper** using ``(`@One`) and ``(`@Many`)
+* When includes to the fragment of **other mapper** using ``
+* When refers to the cache of **other mapper** using ``(`@CacheNamespaceRef`)
+* When refers to the result mapping of **other mapper** using `]]>
-
-
- MyBatis-Spring 会帮助你将 MyBatis 代码无缝地整合到 Spring 中。它将允许 MyBatis 参与到 Spring 的事务管理之中,创建映射器 mapper 和 SqlSession 并注入到 bean 中,以及将 Mybatis 的异常转换为 Spring 的 DataAccessException。最终,可以做到应用代码不依赖于 MyBatis,Spring 或 MyBatis-Spring。
-
-
-
-
-
- Spring 2.0 只支持 iBatis 2.0。那么,我们就想将 MyBatis3 的支持添加到 Spring 3.0 中(参见 Spring Jira 中的问题)。不幸的是,Spring 3.0 的开发在 MyBatis 3.0 官方发布前就结束了。由于 Spring 开发团队不想发布一个基于未发布版的 MyBatis 的整合支持,如果要获得 Spring 官方的支持,只能等待下一次的发布了。基于在 Spring 中对 MyBatis 提供支持的兴趣,MyBatis 社区认为,应该开始召集有兴趣参与其中的贡献者们,将对 Spring 的集成作为 MyBatis 的一个社区子项目。
-
-
-
-
-
- 在开始使用 MyBatis-Spring 之前,你需要先熟悉 Spring 和 MyBatis 这两个框架和有关它们的术语。这很重要——因为本手册中不会提供二者的基本内容,安装和配置教程。
-
<mybatis:scan/> 和 @MapperScan 都在 MyBatis-Spring 1.2.0 中被引入。@MapperScan 需要你使用 Spring 3.1+。
-
-
- Since 2.0.2, mapper scanning feature support a option (lazy-initialization)
- that control lazy initialization enabled/disabled of mapper bean.
- The motivation for adding this option is supporting a lazy initialization control feature supported by Spring Boot 2.2.
- The default of this option is false (= not use lazy initialization).
- If developer want to use lazy initialization for mapper bean, it should be set to the true expressly.
-
-
- IMPORTANT If use the lazy initialization feature,
- the developer need to understand following limitations. If any of following conditions are matches,
- usually the lazy initialization feature cannot use on your application.
-
-
-
When refers to the statement of other mapper using ]]>(@One) and ]]>(@Many)
-
When includes to the fragment of other mapper using ]]>
-
When refers to the cache of other mapper using ]]>(@CacheNamespaceRef)
-
When refers to the result mapping of other mapper using ]]>(@ResultMap)
-
-
-
- NOTE However, It become possible to use it by simultaneously initializing dependent beans using @DependsOn(Spring's feature) as follow:
-
-
-
-
-
- Since 2.0.6, the develop become can specified scope of mapper using mapper scanning feature option(default-scope)
- and scope annotation(@Scope, @RefreshScope, etc ...).
- The motivation for adding this option is supporting the refresh scope provided by the Spring Cloud.
- The default of this option is empty (= equiv to specify the singleton scope).
- The default-scope apply to the mapper bean(MapperFactoryBean) when scope of scanned bean definition
- is singleton(default scope) and create a scoped proxy bean for scanned mapper when final scope is not singleton.
-
-
-
<mybatis:scan/>
-
-
- <mybatis:scan/> 元素会发现映射器,它发现映射器的方法与 Spring 内建的 <context:component-scan/> 发现 bean 的方法非常类似。
-
- NOTE Since 2.0.4, If basePackageClasses or basePackages are not defined, scanning will occur from the package of the class that declares this annotation.
-
-
-
MapperScannerConfigurer
-
-
- MapperScannerConfigurer 是一个 BeanDefinitionRegistryPostProcessor,这样就可以作为一个 bean,包含在经典的 XML 应用上下文中。为了配置 MapperScannerConfigurer,使用下面的 Spring 配置:
-