diff --git a/mvnw.cmd b/mvnw.cmd index 1d7c59bec3f..079fd5250bb 100644 --- a/mvnw.cmd +++ b/mvnw.cmd @@ -141,12 +141,12 @@ if exist %WRAPPER_JAR% ( ) powershell -Command "&{"^ - "$webclient = new-object System.Net.WebClient;"^ - "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ - "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ - "}"^ - "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^ - "}" + "$webclient = new-object System.Net.WebClient;"^ + "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ + "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ + "}"^ + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%WRAPPER_URL%', '%WRAPPER_JAR%')"^ + "}" if "%MVNW_VERBOSE%" == "true" ( echo Finished downloading %WRAPPER_JAR% ) diff --git a/src/site/es/xdoc/configuration.xml b/src/site/es/xdoc/configuration.xml index d61a93f96e7..6b21ca46b30 100644 --- a/src/site/es/xdoc/configuration.xml +++ b/src/site/es/xdoc/configuration.xml @@ -1,7 +1,7 @@ ]]> -

- Pero ¿y si quieres mapear el mismo Enum a un string en un sitio pero a un entero en otro? -

-

- El mapeo automático siempre usará EnumOrdinalTypeHandler, - así que si queremos usar el clásico EnumTypeHandler, - debemos indicarlo establiencidolo esplícitamente su uso en los statements. -

-

- Los mappers no se tratarán hasta la sección siguiente asi que si esta es tu primera lectura de - la documentación quizá prefieras saltarte esta sección por ahora y volver más tarde). -

- + Pero ¿y si quieres mapear el mismo Enum a un string en un sitio pero a un entero en otro? +

+

+ El mapeo automático siempre usará EnumOrdinalTypeHandler, + así que si queremos usar el clásico EnumTypeHandler, + debemos indicarlo establiencidolo esplícitamente su uso en los statements. +

+

+ Los mappers no se tratarán hasta la sección siguiente asi que si esta es tu primera lectura de + la documentación quizá prefieras saltarte esta sección por ahora y volver más tarde). +

+ - - - - - - - - - - insert into users (id, name, funkyNumber, roundingMode) values ( - #{id}, #{name}, #{funkyNumber}, #{roundingMode} - ) - - - - - - - - - - - insert into users2 (id, name, funkyNumber, roundingMode) values ( - #{id}, #{name}, #{funkyNumber}, #{roundingMode, typeHandler=org.apache.ibatis.type.EnumTypeHandler} - ) - + + + + + + + + + + insert into users (id, name, funkyNumber, roundingMode) values ( + #{id}, #{name}, #{funkyNumber}, #{roundingMode} + ) + + + + + + + + + + + insert into users2 (id, name, funkyNumber, roundingMode) values ( + #{id}, #{name}, #{funkyNumber}, #{roundingMode, typeHandler=org.apache.ibatis.type.EnumTypeHandler} + ) + ]]> -

- Observa que esto nos fuerza a usar un resultMap - en lugar de un resultType en nuestros statements tipo select. -

+

+ Observa que esto nos fuerza a usar un resultMap + en lugar de un resultType en nuestros statements tipo select. +

@@ -1879,9 +1879,9 @@ SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader,properti Enviará la propiedad “encoding” y el valor “UTF-8” al constructor del InitialContext durante su instanciación.

-

- You can plug any 3rd party DataSource by implementing the interface org.apache.ibatis.datasource.DataSourceFactory: -

+

+ You can plug any 3rd party DataSource by implementing the interface org.apache.ibatis.datasource.DataSourceFactory: +

- The org.apache.ibatis.datasource.unpooled.UnpooledDataSourceFactory puede extenderse para crear nuevos - adaptadores. Por ejemplo, este es el código necesario para integrar C3P0: -

+ The org.apache.ibatis.datasource.unpooled.UnpooledDataSourceFactory puede extenderse para crear nuevos + adaptadores. Por ejemplo, este es el código necesario para integrar C3P0: +

]]> -

- La implementación DB_VENDOR del databaseIdProvider establece como databaseId el String devuelto por - DatabaseMetaData#getDatabaseProductName(). - Como normalmente este string es demasiado largo, y además, distintas versiones del mismo producto devuelven valores - similares, puedes traducirlo a un valor más corto añadiendo propiedades de la siguente forma: -

+

+ La implementación DB_VENDOR del databaseIdProvider establece como databaseId el String devuelto por + DatabaseMetaData#getDatabaseProductName(). + Como normalmente este string es demasiado largo, y además, distintas versiones del mismo producto devuelven valores + similares, puedes traducirlo a un valor más corto añadiendo propiedades de la siguente forma: +

@@ -1943,16 +1943,16 @@ public class C3P0DataSourceFactory extends UnpooledDataSourceFactory { ]]> -

- Cuando se añaden propiedades, el databaseIdProvider DB_VENDOR devuelve el primer valor que corresponde a la primera clave - encontrada en el nombre devuelto por DatabaseMetaData#getDatabaseProductName() o "null" si no se encuentra ninguna. - En este caso, si getDatabaseProductName() devuelve "Oracle (DataDirect)" el databaseId se informará con "oracle". -

+

+ Cuando se añaden propiedades, el databaseIdProvider DB_VENDOR devuelve el primer valor que corresponde a la primera clave + encontrada en el nombre devuelto por DatabaseMetaData#getDatabaseProductName() o "null" si no se encuentra ninguna. + En este caso, si getDatabaseProductName() devuelve "Oracle (DataDirect)" el databaseId se informará con "oracle". +

-

- Puedes construir tu propio DatabaseIdProvider implementando la interfaz org.apache.ibatis.mapping.DatabaseIdProvider - y registrandolo en el fichero mybatis-config.xml: -

+

+ Puedes construir tu propio DatabaseIdProvider implementando la interfaz org.apache.ibatis.mapping.DatabaseIdProvider + y registrandolo en el fichero mybatis-config.xml: +

+ xsi:schemaLocation="http://maven.apache.org/XDOC/2.0 https://maven.apache.org/xsd/xdoc-2.0.xsd"> - - MyBatis 3 | Primeros pasos - Clinton Begin - Eduardo Macarron - + + MyBatis 3 | Primeros pasos + Clinton Begin + Eduardo Macarron + - -
+ +
@@ -46,43 +46,43 @@ ]]> - + -

- Una aplicación que usa MyBatis debe utilizar una instancia de - SqlSessionFactory. Se puede obtener una instancia de - SqlSessionFactory mediante un SqlSessionFactoryBuilder. Un - SqlSessionFactoryBuilder - puede construir una instancia de SqlSessionFactory a partir de un fichero - de configuración XML o de una - instancia personalizada de la clase Configuration. -

-

- Crear una instancia SqlSessionFactory desde un fichero xml es muy - sencillo. Se recomienda usar un - classpath resource, pero es posible usar cualquier InputStream, incluso - creado con un path de fichero o una - URL de tipo file://. MyBatis proporciona una clase de utilidad, - llamada Resources, que contiene métodos - que simplifican la carga de recursos desde el classpath u otras - ubicaciones. -

- + Una aplicación que usa MyBatis debe utilizar una instancia de + SqlSessionFactory. Se puede obtener una instancia de + SqlSessionFactory mediante un SqlSessionFactoryBuilder. Un + SqlSessionFactoryBuilder + puede construir una instancia de SqlSessionFactory a partir de un fichero + de configuración XML o de una + instancia personalizada de la clase Configuration. +

+

+ Crear una instancia SqlSessionFactory desde un fichero xml es muy + sencillo. Se recomienda usar un + classpath resource, pero es posible usar cualquier InputStream, incluso + creado con un path de fichero o una + URL de tipo file://. MyBatis proporciona una clase de utilidad, + llamada Resources, que contiene métodos + que simplifican la carga de recursos desde el classpath u otras + ubicaciones. +

+ -

- El fichero de configuración XML contiene la configuración del - core - de MyBatis, incluyendo el DataSource - para obtener instancias de conexión a la base de datos y también un - TransactionManager para - determinar cómo deben controlarse las transacciones. Los detalles completos - de la configuración XML - se describen más adelante en este documento, pero continuación se - muestra un ejemplo sencillo: -

- +

+ El fichero de configuración XML contiene la configuración del + core + de MyBatis, incluyendo el DataSource + para obtener instancias de conexión a la base de datos y también un + TransactionManager para + determinar cómo deben controlarse las transacciones. Los detalles completos + de la configuración XML + se describen más adelante en este documento, pero continuación se + muestra un ejemplo sencillo: +

+ @@ -102,104 +102,104 @@ SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(input ]]> -

- Aunque hay mucha más información sobre el fichero de configuración XML, - el ejemplo anterior contiene - las partes más importantes. Observa que hay una cabecera XML, - requerida para validar el fichero XML. - El cuerpo del elemento environment contiene la configuración de la - gestión de transacciones - correspondiente al entorno. El elemento mappers contiene la lista de mappers – Los - ficheros XML que - contienen las sentencias SQL y las definiciones de mapeo. -

-
- -

- Si lo prefieres puedes crear la configuración directamente desde - Java, en lugar de desde XML, o crear tu - propio - builder - . MyBatis dispone una clase Configuration que proporciona las - mismas opciones de - configuración que el fichero XML. -

- + Aunque hay mucha más información sobre el fichero de configuración XML, + el ejemplo anterior contiene + las partes más importantes. Observa que hay una cabecera XML, + requerida para validar el fichero XML. + El cuerpo del elemento environment contiene la configuración de la + gestión de transacciones + correspondiente al entorno. El elemento mappers contiene la lista de mappers – Los + ficheros XML que + contienen las sentencias SQL y las definiciones de mapeo. +

+
+ +

+ Si lo prefieres puedes crear la configuración directamente desde + Java, en lugar de desde XML, o crear tu + propio + builder + . MyBatis dispone una clase Configuration que proporciona las + mismas opciones de + configuración que el fichero XML. +

+ -

- Puedes observar que en este caso la configuración está añadiendo una - clase mapper. Las clases mapper - son clases Java que contienen anotaciones de mapeo SQL que permiten - evitar el uso de XML. Sin - embargo el XML sigue siendo necesario en ocasiones, debido a ciertas - limitaciones de las anotaciones - Java y la complejidad que pueden alcanzar los mapeos (ej. mapeos - anidados de Joins). Por esto, MyBatis - siempre busca si existe un fichero XML asociado a la clase mapper (en este - caso, se buscará un fichero - con nombre BlogMapper.xml cuyo nombre deriva del classpath y nombre de - BlogMapper.class). - Hablaremos más sobre esto más adelante. -

-
- -

- Ahora que dispones de un SqlSessionFactory, tal y como su nombre indica, - puedes adquirir una instancia - de SqlSession. SqlSession contiene todos los métodos necesarios para - ejecutar sentencias SQL contra la - base de datos. Puedes ejecutar mapped statements con la instancia de - SqlSession de la siguiente forma: -

- + Puedes observar que en este caso la configuración está añadiendo una + clase mapper. Las clases mapper + son clases Java que contienen anotaciones de mapeo SQL que permiten + evitar el uso de XML. Sin + embargo el XML sigue siendo necesario en ocasiones, debido a ciertas + limitaciones de las anotaciones + Java y la complejidad que pueden alcanzar los mapeos (ej. mapeos + anidados de Joins). Por esto, MyBatis + siempre busca si existe un fichero XML asociado a la clase mapper (en este + caso, se buscará un fichero + con nombre BlogMapper.xml cuyo nombre deriva del classpath y nombre de + BlogMapper.class). + Hablaremos más sobre esto más adelante. +

+
+ +

+ Ahora que dispones de un SqlSessionFactory, tal y como su nombre indica, + puedes adquirir una instancia + de SqlSession. SqlSession contiene todos los métodos necesarios para + ejecutar sentencias SQL contra la + base de datos. Puedes ejecutar mapped statements con la instancia de + SqlSession de la siguiente forma: +

+ -

- Aunque esta forma de trabajar con la SqlSession funciona correctamente y - les será familiar a aquellos que han usado las versiones anteriores - de MyBatis, actualmente existe una opción más recomendada. Usar un - interface (ej. BlogMapper.class) que describe tanto el parámetro de - entrada como el de retorno para una sentencia. De esta forma - tendrás un código más sencillo y type safe, sin castings ni - literales de tipo String que son fuente frecuente de errores. -

-

- Por ejemplo: -

- + Aunque esta forma de trabajar con la SqlSession funciona correctamente y + les será familiar a aquellos que han usado las versiones anteriores + de MyBatis, actualmente existe una opción más recomendada. Usar un + interface (ej. BlogMapper.class) que describe tanto el parámetro de + entrada como el de retorno para una sentencia. De esta forma + tendrás un código más sencillo y type safe, sin castings ni + literales de tipo String que son fuente frecuente de errores. +

+

+ Por ejemplo: +

+ -

- Vemos con detalle cómo funciona esto. -

-
- -

- Te estarás preguntando qué se está ejecutando en SqlSession o en la - clase Mapper. Los - Mapped Statements - son una materia muy densa, y será el tema que domine la mayor parte - de esta documentación. Pero, para que te hagas una idea de qué se - está ejecutando realmente proporcionaremos un par de ejemplos. -

-

- En cualquiera de los ejemplos a continuación podrían haberse usado - indistintamente XML o anotaciones. Veamos primero el XML. Todas las - opciones de configuración de MyBatis pueden obtenerse mediante el - lenguaje de mapeo XML que ha popularizado a MyBatis durante años. - Si ya has usado MyBatis antes el concepto te será familiar, pero - verás que hay numerosas mejoras en los ficheros de mapeo XML que - iremos explicando más adelante. Por ejemplo este mapped statement - en XML haría funcionar correctamente la llamada al SqlSession que - hemos visto previamente. -

- +

+ Vemos con detalle cómo funciona esto. +

+
+ +

+ Te estarás preguntando qué se está ejecutando en SqlSession o en la + clase Mapper. Los + Mapped Statements + son una materia muy densa, y será el tema que domine la mayor parte + de esta documentación. Pero, para que te hagas una idea de qué se + está ejecutando realmente proporcionaremos un par de ejemplos. +

+

+ En cualquiera de los ejemplos a continuación podrían haberse usado + indistintamente XML o anotaciones. Veamos primero el XML. Todas las + opciones de configuración de MyBatis pueden obtenerse mediante el + lenguaje de mapeo XML que ha popularizado a MyBatis durante años. + Si ya has usado MyBatis antes el concepto te será familiar, pero + verás que hay numerosas mejoras en los ficheros de mapeo XML que + iremos explicando más adelante. Por ejemplo este mapped statement + en XML haría funcionar correctamente la llamada al SqlSession que + hemos visto previamente. +

+ @@ -208,185 +208,185 @@ SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(confi select * from Blog where id = #{id} ]]> -

- Aunque pudiera parecer que hay excesivo XML para un ejemplo tan simple, - en realidad no hay tanto. Puedes definir tantos mapped statements - en un solo fichero XML como quieras así que rentabilizarás las - líneas XML extra que corresponden a la cabecera XML y a la - declaración de doctype. El resto del fichero se explica por sí - mismo. Define un nombre para el mapped statement “selectBlog”, en - un namespace (espacio de nombres) “org.mybatis.example.BlogMapper”, - que permite realizar una llamada especificando el nombre completo - (fully qualified) “org.mybatis.example.BlogMapper.selectBlog” tal y - como muestra el código a continuación: -

- -

- Observa el gran parecido que hay entre esta llamada y la llamada a una - clase java y hay una razón para eso. Este literal puede mapearse - con una clase que tenga el mismo nombre que el namespace, con un - método que coincida con el nombre del statement, y con parámetros - de entrada y retorno iguales que los del statement. Esto permite - que puedas hacer la misma llamada contra una interfaz Mapper tal y - como se muestra a continuación: -

- + Aunque pudiera parecer que hay excesivo XML para un ejemplo tan simple, + en realidad no hay tanto. Puedes definir tantos mapped statements + en un solo fichero XML como quieras así que rentabilizarás las + líneas XML extra que corresponden a la cabecera XML y a la + declaración de doctype. El resto del fichero se explica por sí + mismo. Define un nombre para el mapped statement “selectBlog”, en + un namespace (espacio de nombres) “org.mybatis.example.BlogMapper”, + que permite realizar una llamada especificando el nombre completo + (fully qualified) “org.mybatis.example.BlogMapper.selectBlog” tal y + como muestra el código a continuación: +

+ +

+ Observa el gran parecido que hay entre esta llamada y la llamada a una + clase java y hay una razón para eso. Este literal puede mapearse + con una clase que tenga el mismo nombre que el namespace, con un + método que coincida con el nombre del statement, y con parámetros + de entrada y retorno iguales que los del statement. Esto permite + que puedas hacer la misma llamada contra una interfaz Mapper tal y + como se muestra a continuación: +

+ -

- Este segunda forma de llamada tiene muchas ventajas. Primeramente, no - se usan literales de tipo String lo cual es mucho más seguro dado - que los errores se detectan en tiempo de compilación. Segundo, si - tu IDE dispone de autocompletado de código podrás aprovecharlo. -

-
-

- NOTA - Una nota sobre los namespaces. -

-

- Los namespaces (espacios de nombres) - eran opcionales en versiones anteriores de MyBatis, lo cual creaba - confusión y era de poca ayuda. Los namespaces son ahora - obligatorios y tienen un propósito más allá de la clasificación de - statements. -

-

- Los namespaces permiten realizar el enlace con los interfaces como se - ha visto anteriormente, e incluso si crees que no los vas a usar a - corto plazo, es recomendable que sigas estas prácticas de - organización de código por si en un futuro decides hacer lo - contrario. Usar un namespace y colocarlo en el paquete java que - corresponde con el namespace hará tu código más legible y mejorará - la usabilidad de MyBatis a largo plazo. -

-

- Resolución de nombres: - Para reducir la cantidad de texto a escribir MyBatis usa las - siguientes normas de resolución de nombres para todos los elementos - de configuración, incluidos statements, result maps, cachés, etc. -

-
    -
  • Primeramente se buscan directamente los nombres completamente - cualificados (fully qualified names) (ej. - “com.mypackage.MyMapper.selectAllThings”). -
  • -
  • Pueden usarse los nombres cortos (ej. “selectAllThings”) - siempre que no haya ambigüedad. Sin embargo, si hubiera dos o más - elementos (ej. “com.foo.selectAllThings" y - "com.bar.selectAllThings”), entonces obtendrás un error indicando - que el nombre es ambiguo y que debe ser “fully qualified”. -
  • -
-
-

- Hay otro aspecto importante sobre las clases Mapper como BlogMapper. - Sus mapped statements pueden no estar en ningún fichero XML. En su - lugar, pueden usarse anotaciones. Por ejemplo, el XML puede ser - eliminado y reemplazarse por: -

- + Este segunda forma de llamada tiene muchas ventajas. Primeramente, no + se usan literales de tipo String lo cual es mucho más seguro dado + que los errores se detectan en tiempo de compilación. Segundo, si + tu IDE dispone de autocompletado de código podrás aprovecharlo. +

+
+

+ NOTA + Una nota sobre los namespaces. +

+

+ Los namespaces (espacios de nombres) + eran opcionales en versiones anteriores de MyBatis, lo cual creaba + confusión y era de poca ayuda. Los namespaces son ahora + obligatorios y tienen un propósito más allá de la clasificación de + statements. +

+

+ Los namespaces permiten realizar el enlace con los interfaces como se + ha visto anteriormente, e incluso si crees que no los vas a usar a + corto plazo, es recomendable que sigas estas prácticas de + organización de código por si en un futuro decides hacer lo + contrario. Usar un namespace y colocarlo en el paquete java que + corresponde con el namespace hará tu código más legible y mejorará + la usabilidad de MyBatis a largo plazo. +

+

+ Resolución de nombres: + Para reducir la cantidad de texto a escribir MyBatis usa las + siguientes normas de resolución de nombres para todos los elementos + de configuración, incluidos statements, result maps, cachés, etc. +

+
    +
  • Primeramente se buscan directamente los nombres completamente + cualificados (fully qualified names) (ej. + “com.mypackage.MyMapper.selectAllThings”). +
  • +
  • Pueden usarse los nombres cortos (ej. “selectAllThings”) + siempre que no haya ambigüedad. Sin embargo, si hubiera dos o más + elementos (ej. “com.foo.selectAllThings" y + "com.bar.selectAllThings”), entonces obtendrás un error indicando + que el nombre es ambiguo y que debe ser “fully qualified”. +
  • +
+
+

+ Hay otro aspecto importante sobre las clases Mapper como BlogMapper. + Sus mapped statements pueden no estar en ningún fichero XML. En su + lugar, pueden usarse anotaciones. Por ejemplo, el XML puede ser + eliminado y reemplazarse por: +

+ -

- Las anotaciones son mucho más claras para sentencias sencillas, sin - embargo, las anotaciones java son limitadas y más complicadas de - usar para sentencias complejas. Por lo tanto, si tienes que hacer - algo complejo, es mejor que uses los ficheros XML. -

-

- Es decisión tuya y de tu proyecto cuál de los dos métodos usar y cómo - de importante es que los mapped statements estén definidos de forma - consistente. Dicho esto, no estás limitado a usar un solo método, - puedes migrar fácilmente de los mapped statements basados en - anotaciones a XML y viceversa. -

-
- -

Es muy importante entender los distintos ámbitos y ciclos de vida - de las clases de las que hemos hablado hasta ahora. Usarlas de - forma incorrecta puede traer serias complicaciones.

-
-

- NOTA - Ciclo de vida de los objetos y frameworks de inyección de - dependencias -

-

- Los frameworks de inyección de dependencias pueden crear - SqlSessions y mappers - thread safe - (reeentrante) y - transaccionales, e inyectarlos directmaente en tus beans de forma que puedes - olvidarte de su ciclo de vida. - Echa un vistazo a los sub-projectos MyBatis-Spring o MyBatis-Guice para - conocer más detalles sobre cómo usar - MyBatis con estos frameworks. -

-
+

+ Las anotaciones son mucho más claras para sentencias sencillas, sin + embargo, las anotaciones java son limitadas y más complicadas de + usar para sentencias complejas. Por lo tanto, si tienes que hacer + algo complejo, es mejor que uses los ficheros XML. +

+

+ Es decisión tuya y de tu proyecto cuál de los dos métodos usar y cómo + de importante es que los mapped statements estén definidos de forma + consistente. Dicho esto, no estás limitado a usar un solo método, + puedes migrar fácilmente de los mapped statements basados en + anotaciones a XML y viceversa. +

+
+ +

Es muy importante entender los distintos ámbitos y ciclos de vida + de las clases de las que hemos hablado hasta ahora. Usarlas de + forma incorrecta puede traer serias complicaciones.

+
+

+ NOTA + Ciclo de vida de los objetos y frameworks de inyección de + dependencias +

+

+ Los frameworks de inyección de dependencias pueden crear + SqlSessions y mappers + thread safe + (reeentrante) y + transaccionales, e inyectarlos directmaente en tus beans de forma que puedes + olvidarte de su ciclo de vida. + Echa un vistazo a los sub-projectos MyBatis-Spring o MyBatis-Guice para + conocer más detalles sobre cómo usar + MyBatis con estos frameworks. +

+
-

SqlSessionFactoryBuilder

-

Esta clase puede instanciarse, usarse y desecharse. No es - necesario mantenerla una vez que ya has creado la - SqlSessionFactory. Por lo tanto el mejor ámbito para el - SqlSessionFactoryBuilder es el método (ej. una variable local de - método). Puedes reusar el SqlSessionFactoryBuilder para construir - más de una instancia de SqlSessionFactory, pero aun así es - recomendable no conservar el objeto para asegurarse de que todos - los recursos utilizados para el parseo de XML se han liberado - correctamente y están disponibles para temas más importantes. -

-

SqlSessionFactory

-

Una vez creado, el SqlSessionFactory debería existir durante toda - la ejecución de tu aplicación. No debería haber ningún o casi - ningún motivo para eliminarlo o recrearlo. Es una buena práctica el - no recrear el SqlSessionFactory en tu aplicación más de una vez. Y - lo contrario debería considerarse código sospechoso. Por tanto el - mejor ámbito para el SqlSessionFactory es el ámbito de aplicación. - Esto puede conseguirse de muchas formas. Lo más sencillo es usar el - patrón Singleton o el Static Singleton.

-

SqlSession

-

Cada thread (hilo de ejecución) debería tener su propia instancia - de SqlSession. Las instancias de SqlSession no son thread safe y no - deben ser compartidas. Por tanto el ámbito adecuado es el de - petición (request) o bien el método. No guardes nunca instancias de - SqlSession en un campo estático o incluso en una propiedad de - instancia de una clase. Nunca guardes referencias a una SqlSession - en ningún tipo de ámbito gestionado como la HttpSession. Si estás - usando un framework web considera que el SqlSession debería tener - un ámbito similar al HttpRequest. Es decir, cuando recibas una - petición http puedes abrir una SqlSession y cerrarla cuando - devuelvas la respuesta. Cerrar la SqlSession es muy importante. - Deberías asegurarte de que se cierra con un bloque finally. A - continuación se muestra el patrón estándar para asegurarse de que - las sesiones se cierran correctamente.

- SqlSessionFactoryBuilder +

Esta clase puede instanciarse, usarse y desecharse. No es + necesario mantenerla una vez que ya has creado la + SqlSessionFactory. Por lo tanto el mejor ámbito para el + SqlSessionFactoryBuilder es el método (ej. una variable local de + método). Puedes reusar el SqlSessionFactoryBuilder para construir + más de una instancia de SqlSessionFactory, pero aun así es + recomendable no conservar el objeto para asegurarse de que todos + los recursos utilizados para el parseo de XML se han liberado + correctamente y están disponibles para temas más importantes. +

+

SqlSessionFactory

+

Una vez creado, el SqlSessionFactory debería existir durante toda + la ejecución de tu aplicación. No debería haber ningún o casi + ningún motivo para eliminarlo o recrearlo. Es una buena práctica el + no recrear el SqlSessionFactory en tu aplicación más de una vez. Y + lo contrario debería considerarse código sospechoso. Por tanto el + mejor ámbito para el SqlSessionFactory es el ámbito de aplicación. + Esto puede conseguirse de muchas formas. Lo más sencillo es usar el + patrón Singleton o el Static Singleton.

+

SqlSession

+

Cada thread (hilo de ejecución) debería tener su propia instancia + de SqlSession. Las instancias de SqlSession no son thread safe y no + deben ser compartidas. Por tanto el ámbito adecuado es el de + petición (request) o bien el método. No guardes nunca instancias de + SqlSession en un campo estático o incluso en una propiedad de + instancia de una clase. Nunca guardes referencias a una SqlSession + en ningún tipo de ámbito gestionado como la HttpSession. Si estás + usando un framework web considera que el SqlSession debería tener + un ámbito similar al HttpRequest. Es decir, cuando recibas una + petición http puedes abrir una SqlSession y cerrarla cuando + devuelvas la respuesta. Cerrar la SqlSession es muy importante. + Deberías asegurarte de que se cierra con un bloque finally. A + continuación se muestra el patrón estándar para asegurarse de que + las sesiones se cierran correctamente.

+ -

Usando este patrón en todo el código se asegura que los recursos - de base de datos se liberarán correctamente.

-

Instancias de mapper

-

Los mappers son interfaces que creas como enlace con los mapped - statements. Las instancias de mappers se obtienen de una - SqlSession. Y por tanto, técnicamente el mayor ámbito de una - instancia de Mapper es el mismo que el de la SqlSession de la que - fueron creados. Sin embargo el ámbito más recomendable para una - instancia de mapper es el ámbito de método. Es decir, deberían ser - obtenidos en el método que vaya a usarlos y posteriormente - descartarlos. No es necesario que sean cerrados explícitamente. - Aunque no es un problema propagar estos objetos por varias clases - dentro de una misma llamada, debes tener cuidado porque puede que - la situación se te vaya de las manos. Hazlo fácil (keep it simple) - y mantén los mappers en el ámbito de método. Este ejemplo muestra - esta práctica:

- Usando este patrón en todo el código se asegura que los recursos + de base de datos se liberarán correctamente.

+

Instancias de mapper

+

Los mappers son interfaces que creas como enlace con los mapped + statements. Las instancias de mappers se obtienen de una + SqlSession. Y por tanto, técnicamente el mayor ámbito de una + instancia de Mapper es el mismo que el de la SqlSession de la que + fueron creados. Sin embargo el ámbito más recomendable para una + instancia de mapper es el ámbito de método. Es decir, deberían ser + obtenidos en el método que vaya a usarlos y posteriormente + descartarlos. No es necesario que sean cerrados explícitamente. + Aunque no es un problema propagar estos objetos por varias clases + dentro de una misma llamada, debes tener cuidado porque puede que + la situación se te vaya de las manos. Hazlo fácil (keep it simple) + y mantén los mappers en el ámbito de método. Este ejemplo muestra + esta práctica:

+ -
-
- + +
+
diff --git a/src/site/es/xdoc/index.xml b/src/site/es/xdoc/index.xml index d4709109951..3429a084c56 100644 --- a/src/site/es/xdoc/index.xml +++ b/src/site/es/xdoc/index.xml @@ -1,7 +1,7 @@ - - - MyBatis 3 | Introducción - Clinton Begin - Eduardo Macarron - - - -
- -

- MyBatis es un framework de persistencia que soporta SQL, procedimientos - almacenados y mapeos avanzados. MyBatis elimina casi todo el código JDBC, el establecimiento - manual de parámetros y la obtención de resultados. MyBatis puede configurarse con XML o anotaciones y - permite mapear typos de datos primitivos, objetos de tipo Map y POJOs (Plain Old Java Objects) a registros de base de datos. -

-
- - -

- 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 + xsi:schemaLocation="http://maven.apache.org/XDOC/2.0 https://maven.apache.org/xsd/xdoc-2.0.xsd"> + + + MyBatis 3 | Introducción + Clinton Begin + Eduardo Macarron + + + +

+ +

+ MyBatis es un framework de persistencia que soporta SQL, procedimientos + almacenados y mapeos avanzados. MyBatis elimina casi todo el código JDBC, el establecimiento + manual de parámetros y la obtención de resultados. MyBatis puede configurarse con XML o anotaciones y + permite mapear typos de datos primitivos, objetos de tipo Map y POJOs (Plain Old Java Objects) a registros de base de datos. +

+
+ + +

+ 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, cámbialas y envía un pull request.

-

- Eres el mejor candidato para documentar porque los lectores de esta documentación son gente como tú! -

-
-
- +

+ Eres el mejor candidato para documentar porque los lectores de esta documentación son gente como tú! +

+
+
+
diff --git a/src/site/ja/xdoc/configuration.xml b/src/site/ja/xdoc/configuration.xml index 4be5d635a17..b22c026a794 100644 --- a/src/site/ja/xdoc/configuration.xml +++ b/src/site/ja/xdoc/configuration.xml @@ -1,7 +1,7 @@ ]]> -

- 같은 Enum을 사용해서 어떤 곳에는 문자열로 매핑하고 다른 곳에는 숫자로 매핑해야 한다면 무엇을 해야 하나? -

-

- 자동매퍼는 EnumOrdinalTypeHandler 를 자동으로 사용할 것이다. - 그래서 평범한 순서를 나타내는 EnumTypeHandler 를 사용하고자 한다면 SQL구문에 사용할 타입핸들러를 명시적으로 설정한다. -

-

- (매퍼 파일은 다음 절까지는 다루지 않는다. - 그래서 문서를 보면서 처음 봤다면 일단 이 부분은 건너띄고 다음에 다시 볼수도 있다. ) -

- + 같은 Enum을 사용해서 어떤 곳에는 문자열로 매핑하고 다른 곳에는 숫자로 매핑해야 한다면 무엇을 해야 하나? +

+

+ 자동매퍼는 EnumOrdinalTypeHandler 를 자동으로 사용할 것이다. + 그래서 평범한 순서를 나타내는 EnumTypeHandler 를 사용하고자 한다면 SQL구문에 사용할 타입핸들러를 명시적으로 설정한다. +

+

+ (매퍼 파일은 다음 절까지는 다루지 않는다. + 그래서 문서를 보면서 처음 봤다면 일단 이 부분은 건너띄고 다음에 다시 볼수도 있다. ) +

+ - - - - - - - - - - insert into users (id, name, funkyNumber, roundingMode) values ( - #{id}, #{name}, #{funkyNumber}, #{roundingMode} - ) - - - - - - - - - - - insert into users2 (id, name, funkyNumber, roundingMode) values ( - #{id}, #{name}, #{funkyNumber}, #{roundingMode, typeHandler=org.apache.ibatis.type.EnumTypeHandler} - ) - + + + + + + + + + + insert into users (id, name, funkyNumber, roundingMode) values ( + #{id}, #{name}, #{funkyNumber}, #{roundingMode} + ) + + + + + + + + + + + insert into users2 (id, name, funkyNumber, roundingMode) values ( + #{id}, #{name}, #{funkyNumber}, #{roundingMode, typeHandler=org.apache.ibatis.type.EnumTypeHandler} + ) + ]]> -

- 여기서 사용한 select구문에서는 resultType 대신에 resultMap을 사용해야 한다는 점을 알아두자. -

+

+ 여기서 사용한 select구문에서는 resultType 대신에 resultMap을 사용해야 한다는 점을 알아두자. +

매번 마이바티스는 결과 객체의 인스턴스를 만들기 위해 ObjectFactory를 사용한다. - 디폴트 ObjectFactory 는 디폴트 생성자를 가진 대상 클래스를 인스턴스화하는 것보다 조금 더 많은 작업을 한다. - ObjectFactory 의 디폴트 행위를 오버라이드하고자 한다면 만들 수 있다. - 예를들면:

+ 디폴트 ObjectFactory 는 디폴트 생성자를 가진 대상 클래스를 인스턴스화하는 것보다 조금 더 많은 작업을 한다. + ObjectFactory 의 디폴트 행위를 오버라이드하고자 한다면 만들 수 있다. + 예를들면:

]]>

ObjectFactory인터페이스는 매우 간단한다. - 두 개의 create메소드를 가지고 있으며 하나는 디폴트 생성자를 처리하고 다른 하나는 파라미터를 가진 생성자를 처리한다. - 마지막으로 setProperties 메소드는 ObjectFactory를 설정하기 위해 사용될 수 있다. - objectFactory엘리먼트에 정의된 프로퍼티는 ObjectFactory인스턴스가 초기화된 후 setProperties에 전달될 것이다.

+ 두 개의 create메소드를 가지고 있으며 하나는 디폴트 생성자를 처리하고 다른 하나는 파라미터를 가진 생성자를 처리한다. + 마지막으로 setProperties 메소드는 ObjectFactory를 설정하기 위해 사용될 수 있다. + objectFactory엘리먼트에 정의된 프로퍼티는 ObjectFactory인스턴스가 초기화된 후 setProperties에 전달될 것이다.

마이바티스는 매핑 구문을 실행하는 어떤 시점에 호출을 가로챈다. - 기본적으로 마이바티스는 메소드 호출을 가로채기 위한 플러그인을 허용한다.

+ 기본적으로 마이바티스는 메소드 호출을 가로채기 위한 플러그인을 허용한다.

이 클래스들의 메소드는 각각 메소드 시그니처를 통해 찾을 수 있고 소스코드는 마이바티스 릴리즈 파일에서 찾을 수 있다. - 오버라이드할 메소드의 행위를 이해해야만 한다. - 주어진 메소드의 행위를 변경하거나 오버라이드하고자 한다면 마이바티스의 핵심기능에 악영향을 줄 수도 있다. - 이러한 로우레벨 클래스와 메소드들은 주의를 해서 사용해야 한다.

+ 오버라이드할 메소드의 행위를 이해해야만 한다. + 주어진 메소드의 행위를 변경하거나 오버라이드하고자 한다면 마이바티스의 핵심기능에 악영향을 줄 수도 있다. + 이러한 로우레벨 클래스와 메소드들은 주의를 해서 사용해야 한다.

플러그인을 사용하도록 처리하는 방법은 간단하다. - Interceptor인터페이스를 구현해서 가로채고(intercept) 싶은 시그니처를 명시해야 한다.

+ Interceptor인터페이스를 구현해서 가로채고(intercept) 싶은 시그니처를 명시해야 한다.

설정파일 오버라이드하기

플러그인을 사용해서 마이바티스 핵심 행위를 변경하기 위해 Configuration클래스 전체를 오버라이드 할 수 있다. - 이 클래스를 확장하고 내부 메소드를 오버라이드하고 SqlSessionFactoryBuilder.build(myConfig)메소드에 그 객체를 넣어주면 된다. - 다시 얘기하지만 이 작업은 마이바티스에 큰 영향을 줄수 있으니 주의해서 해야 한다.

+ 이 클래스를 확장하고 내부 메소드를 오버라이드하고 SqlSessionFactoryBuilder.build(myConfig)메소드에 그 객체를 넣어주면 된다. + 다시 얘기하지만 이 작업은 마이바티스에 큰 영향을 줄수 있으니 주의해서 해야 한다.

마이바티스는 여러 개의 환경으로 설정할 수 있다. - 여러가지 이유로 여러 개의 데이터베이스에 SQL Map을 적용하는데 도움이 된다. - 예를들어, 개발, 테스트, 리얼 환경을 위해 별도의 설정을 가지거나 같은 스키마를 여러 개의 DBMS 제품을 사용할 경우들이다. - 그 외에도 많은 경우가 있을 수 있다.

+ 여러가지 이유로 여러 개의 데이터베이스에 SQL Map을 적용하는데 도움이 된다. + 예를들어, 개발, 테스트, 리얼 환경을 위해 별도의 설정을 가지거나 같은 스키마를 여러 개의 DBMS 제품을 사용할 경우들이다. + 그 외에도 많은 경우가 있을 수 있다.

중요하게 기억해야 할 것은 다중 환경을 설정할 수는 있지만 SqlSessionFactory 인스턴스마다 한 개만 사용할 수 있다는 것이다.

두 개의 데이터베이스에 연결하고 싶다면 SqlSessionFactory 인스턴스를 두 개 만들 필요가 있다. - 세 개의 데이터베이스를 사용한다면 역시 세 개의 인스턴스를 필요로 한다. - 기억하기 쉽게

+ 세 개의 데이터베이스를 사용한다면 역시 세 개의 인스턴스를 필요로 한다. + 기억하기 쉽게

환경을 명시하기 위해 SqlSessionFactoryBuilder에 옵션으로 추가 파라미터를 주면 된다. - 환경을 선택하는 두가지 시그니처는

+ 환경을 선택하는 두가지 시그니처는

@@ -1729,17 +1729,17 @@ SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader,properti

마이바티스는 두 가지 타입의 TransactionManager를 제공한다.