Configuración central de MyBatis

Prefacio

De hecho, el núcleo de MyBatis debería consistir en dos archivos de configuración, un archivo de configuración global y un archivo de mapeo. Siempre que comprenda estos dos archivos, comprenderá la mayor parte del uso de MyBatis. Este artículo presenta estos dos archivos de configuración.

Archivo de configuración global

El archivo de configuración de MyBatis contiene configuraciones e información de propiedades que afectan profundamente el comportamiento de MyBatis. La estructura de nivel superior del documento de configuración es la siguiente:

  • configuración
  • propiedades
  • ajustes
  • typeAliases (tipo alias)
  • typeHandlers (controladores de tipos)
  • objectFactory (fábrica de objetos)
  • complementos
  • entornos (configuración del entorno)
    • entorno (variable de entorno)
      • administrador de transacciones
      • fuente de datos (fuente de datos)
  • DatabaseIdProvider (identificación del proveedor de la base de datos)
  • mapeadores

configuración

La configuración es la etiqueta raíz de todo el archivo de configuración, que en realidad corresponde a la clase de configuración más importante Configuración en MyBatis. Recorre todos los aspectos del proceso de ejecución de MyBatis.

propiedades

La etiqueta de primer nivel son propiedades, que se utilizan para configurar información de parámetros, como la información de conexión de base de datos más común.

Para evitar escribir los parámetros directamente en el archivo de configuración xml, podemos colocar estos parámetros por separado en el archivo de propiedades, introducirlos con la etiqueta de propiedades y luego citarlos con ${} en el archivo de configuración xml. Puede usar recurso para hacer referencia a la ruta relativa en la aplicación, o puede usar URL para especificar la ruta absoluta del servidor o red local.

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
	<!-- 引入一个属性文件 -->
    <properties resource="db.properties"></properties>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/><!-- 单独使用时配置成MANAGED没有事务 -->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>

</configuration>

ajustes

Estos son ajustes extremadamente importantes en MyBatis que cambiarán el comportamiento de ejecución de MyBatis.

Configuración de parámetros describir Valores válidos valor por defecto
caché habilitado Activa o desactiva globalmente cualquier caché que se haya configurado para todos los asignadores en el archivo de configuración. verdadero FALSO
carga diferida habilitada Cambio global para carga diferida. Cuando está habilitado, todos los objetos asociados se cargan de forma diferida. En una asociación específica, el estado de cambio del elemento se puede anular configurando el atributo fetchType. verdadero FALSO
agresivoLazyLoading Cuando está habilitado, cualquier llamada a un método cargará todas las propiedades del objeto. De lo contrario, cada propiedad se carga según demanda (consulte lazyLoadTriggerMethods). verdadero FALSO
múltiplesResultSetsEnabled Si se debe permitir que una sola declaración devuelva múltiples conjuntos de resultados (requiere un controlador compatible). verdadero FALSO
utilizarColumnLabel Utilice etiquetas de columna en lugar de nombres de columna. Diferentes controladores tendrán diferentes actuaciones a este respecto. Para obtener más detalles, puede consultar la documentación del controlador correspondiente u observar los resultados del controlador utilizado probando estos dos modos diferentes. verdadero FALSO
utilizar claves generadas Permitir que JDBC admita la generación automática de claves primarias requiere compatibilidad de controladores. Si se establece en verdadero, esta configuración fuerza el uso de claves primarias generadas automáticamente, que seguirán funcionando a pesar de algunos controladores incompatibles (como Derby). verdadero FALSO
comportamiento de mapeo automático Especifica cómo MyBatis debería asignar automáticamente columnas a campos o propiedades. NONE significa cancelar la asignación automática; PARTIAL solo asignará automáticamente conjuntos de resultados que no definan la asignación de conjuntos de resultados anidados. FULL asigna automáticamente conjuntos de resultados arbitrariamente complejos (anidados o no). NINGUNO, PARCIAL, COMPLETO PARCIAL
autoMappingUnknownColumnBehavior Especifica el comportamiento de la asignación automática de descubrimiento dirigida a columnas desconocidas (o tipos de atributos desconocidos). NINGUNO: Sin respuesta ADVERTENCIA: Registro de recordatorio de salida (el nivel de registro de 'org.apache.ibatis.session.AutoMappingUnknownColumnBehavior' debe establecerse en ADVERTENCIA) FALLO: Error en la asignación (genera SqlSessionException) NINGUNO, ADVERTENCIA, FALLANDO NINGUNO
tipo de ejecutor predeterminado Configure el ejecutor predeterminado. SIMPLE es un ejecutor ordinario; el ejecutor REUSE reutilizará declaraciones preparadas; el ejecutor BATCH reutilizará declaraciones y realizará actualizaciones por lotes. LOTE DE REUTILIZACIÓN SIMPLE SIMPLE
defaultStatementTimeout Establezca el tiempo de espera, que determina la cantidad de segundos que el controlador espera una respuesta de la base de datos. cualquier entero positivo No establecido (nulo)
tamaño de recuperación predeterminado Establezca un valor de sugerencia para el tamaño de recuperación del conjunto de resultados del controlador (fetchSize). Este parámetro solo se puede anular en la configuración de consulta. cualquier entero positivo No establecido (nulo)
safeRowBoundsEnabled Permite el uso de paginación (RowBounds) en sentencias anidadas. Establecer en falso si se permite el uso. verdadero FALSO
safeResultHandlerEnabled Permitir paginación (ResultHandler) en declaraciones anidadas. Establecer en falso si se permite el uso. verdadero FALSO
mapUnderscoreToCamelCase Si se debe habilitar la asignación automática de casos de camello, es decir, una asignación similar del nombre de columna de base de datos clásico A_COLUMN al nombre de atributo Java clásico aColumn. verdadero| FALSO FALSO
localCacheScope MyBatis utiliza el mecanismo de caché local (Local Cache) para evitar referencias circulares y acelerar consultas anidadas repetidas. El valor predeterminado es SESSION, en cuyo caso todas las consultas ejecutadas en una sesión se almacenan en caché. Si el valor de configuración es STATEMENT, la sesión local solo se usa para la ejecución de declaraciones y diferentes llamadas a la misma SqlSession no compartirán datos. SESIÓN| DECLARACIÓN SESIÓN
jdbcTypeForNull Cuando no se proporciona ningún tipo JDBC específico para el parámetro, el tipo JDBC se especifica para el valor nulo. Algunos controladores necesitan especificar el tipo JDBC de la columna. En la mayoría de los casos, simplemente use el tipo general, como NULL, VARCHAR u OTHER. Constantes JdbcType. La mayoría son: NULL, VARCHAR y OTHER OTRO
métodos lazyLoadTrigger Especifique qué método de objeto desencadena una carga diferida. Lista de métodos separados por comas. es igual, clonar, hashCode, toString
idioma de scripting predeterminado Especifica el idioma predeterminado para la generación de SQL dinámico. Un alias de tipo o un nombre de clase completo. org.apache.ibatis.scripting.xmltags.XMLLanguageDriver
defaultEnumTypeHandler Especifica el TypeHandler predeterminado utilizado por Enum. (Desde 3.4.5) Un alias de tipo o nombre de clase completo. org.apache.ibatis.type.EnumTypeHandler
llamarSettersOnNulls Especifica si se debe llamar al método de establecimiento del objeto de mapa (poner para el objeto de mapa) cuando el valor en el conjunto de resultados es nulo. Esto es útil cuando hay una dependencia de Map.keySet() o una inicialización de valor nulo. Tenga en cuenta que los tipos básicos (int, boolean, etc.) no se pueden establecer en nulo. verdadero| FALSO FALSO
returnInstanciaParaEmptyRow Cuando todas las columnas de la fila devuelta están vacías, MyBatis devuelve nulo de forma predeterminada. Cuando esta configuración está activada, MyBatis devolverá una instancia vacía. Tenga en cuenta que también funciona con conjuntos de resultados anidados (es decir, recopilación y asociación). (Desde 3.4.2) verdadero| FALSO FALSO
prefijo de registro Especifique el prefijo que MyBatis agrega al nombre del registro. cualquier cuerda No establecido
logImpl Especifique la implementación específica del registro utilizado por MyBatis. Si no se especifica, se buscará automáticamente. SLF4J LOG4J| LOG4J2 | JDK_LOGGING | COMMONS_LOGGING\
fábrica de proxy Especifique la herramienta proxy utilizada por Mybatis para crear objetos con capacidades de carga diferida. CGLIB\ JAVASSIST
vfsImpl Especificar la implementación de VFS Nombres de clase completos de implementaciones VFS personalizadas, separados por comas. No establecido
useNombreParamActual 允许使用方法签名中的名称作为语句参数名称。 为了使用该特性,你的工程必须采用Java 8编译,并且加上-parameters选项。(从3.4.1开始) true| false true
configurationFactory 指定一个提供Configuration实例的类。 这个被返回的Configuration实例用来加载被反序列化对象的懒加载属性值。 这个类必须包含一个签名方法static Configuration getConfiguration(). (从 3.2.3 版本开始) 类型别名或者全类名. Not set

案例

    <settings>
        <!-- 打印查询语句 -->
        <setting name="logImpl" value="STDOUT_LOGGING" />

        <!-- 控制全局缓存(二级缓存),默认 true-->
        <setting name="cacheEnabled" value="false"/>

        <!-- 延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。默认 false  -->
        <setting name="lazyLoadingEnabled" value="true"/>
        <!-- 当开启时,任何方法的调用都会加载该对象的所有属性。默认 false,可通过select标签的 fetchType来覆盖-->
        <setting name="aggressiveLazyLoading" value="true"/>
        <!--  Mybatis 创建具有延迟加载能力的对象所用到的代理工具,默认JAVASSIST -->
        <!--<setting name="proxyFactory" value="CGLIB" />-->
        <!-- STATEMENT级别的缓存,使一级缓存,只针对当前执行的这一statement有效 -->
        <!--
                <setting name="localCacheScope" value="STATEMENT"/>
        -->
        <setting name="localCacheScope" value="SESSION"/>
    </settings>

typeAliases

TypeAlias是类型的别名,主要用来简化类名全路径的拼写。比如参数类型和返回值类型都可能会用到我们的Bean,如果每个地方都配置全路径的话,那么内容就比较多,还可能会写错。

可以为Bean创建别名,既可以指定单个类,也可以指定一个package,自动转换。

    <typeAliases>
        <typeAlias alias="user" type="com.domain.User" />
    </typeAliases>

MyBatis里面有很多系统预先定义好的类型别名,在TypeAliasRegistry中。所以可以用string代替java.lang.String。

  public TypeAliasRegistry() {
    
    
    registerAlias("string", String.class);

    registerAlias("byte", Byte.class);
    registerAlias("long", Long.class);
    registerAlias("short", Short.class);
    registerAlias("int", Integer.class);
    registerAlias("integer", Integer.class);
    registerAlias("double", Double.class);
    registerAlias("float", Float.class);
    registerAlias("boolean", Boolean.class);

    registerAlias("byte[]", Byte[].class);
    registerAlias("long[]", Long[].class);
    registerAlias("short[]", Short[].class);
    registerAlias("int[]", Integer[].class);
    registerAlias("integer[]", Integer[].class);
    registerAlias("double[]", Double[].class);
    registerAlias("float[]", Float[].class);
    registerAlias("boolean[]", Boolean[].class);

    registerAlias("_byte", byte.class);
    registerAlias("_long", long.class);
    registerAlias("_short", short.class);
    registerAlias("_int", int.class);
    registerAlias("_integer", int.class);
    registerAlias("_double", double.class);
    registerAlias("_float", float.class);
    registerAlias("_boolean", boolean.class);

    registerAlias("_byte[]", byte[].class);
    registerAlias("_long[]", long[].class);
    registerAlias("_short[]", short[].class);
    registerAlias("_int[]", int[].class);
    registerAlias("_integer[]", int[].class);
    registerAlias("_double[]", double[].class);
    registerAlias("_float[]", float[].class);
    registerAlias("_boolean[]", boolean[].class);

    registerAlias("date", Date.class);
    registerAlias("decimal", BigDecimal.class);
    registerAlias("bigdecimal", BigDecimal.class);
    registerAlias("biginteger", BigInteger.class);
    registerAlias("object", Object.class);

    registerAlias("date[]", Date[].class);
    registerAlias("decimal[]", BigDecimal[].class);
    registerAlias("bigdecimal[]", BigDecimal[].class);
    registerAlias("biginteger[]", BigInteger[].class);
    registerAlias("object[]", Object[].class);

    registerAlias("map", Map.class);
    registerAlias("hashmap", HashMap.class);
    registerAlias("list", List.class);
    registerAlias("arraylist", ArrayList.class);
    registerAlias("collection", Collection.class);
    registerAlias("iterator", Iterator.class);

    registerAlias("ResultSet", ResultSet.class);
  }

TypeHandler

由于Java类型和数据库的JDBC类型不是一一对应的(比如String与varchar、char、text),所以把Java对象转换为数据库的值,和把数据库的值转换成Java对象,需要经过一定的转换,这两个方向的转换就要用到TypeHandler。

我们可以自定义一个TypeHandler来帮助我们简单的处理数据,比如查询的结果的字段如果是一个字符串,且值为"zhangsan"就修饰下这个信息


/**
 * 自定义的类型处理器
 *    处理的字段如果是 String类型的话就 且 内容是 zhangsan 拼接个信息
 */

public class MyTypeHandler  extends BaseTypeHandler<String> {
    
    
    /**
     * 插入数据的时候回调的方法
     * @param ps
     * @param i
     * @param parameter
     * @param jdbcType
     * @throws SQLException
     */
    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType) throws SQLException {
    
    
        System.out.println("---------------setNonNullParameter1:"+parameter);
        ps.setString(i, parameter);
    }

    @Override
    public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
    
    
        String name = rs.getString(columnName);
        if("zhangsan".equals(name)){
    
    
            return name+"666";
        }
        return name;
    }

    @Override
    public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
    
    
        String name = rs.getString(columnIndex);
        if("zhangsan".equals(name)){
    
    
            return name+"666";
        }
        return name;
    }

    @Override
    public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
    
    
        String name = cs.getString(columnIndex);
        if("zhangsan".equals(name)){
    
    
            return name+"666";
        }
        return name;
    }
}

同时将我们的处理器在全局配置文件中注册下

<typeHandlers>
    <typeHandler handler="com.type.MyTypeHandler"></typeHandler>
</typeHandlers>

然后我们在映射文件中配置对应的处理器

image.png

objectFactory

当我们把数据库返回的结果集转换为实体类的时候,需要创建对象的实例,由于我们不知道需要处理的类型是什么,有哪些属性,所以不能用new的方式去创建,只能通过反射来创建。

在MyBatis里面,它提供了一个工厂类的接口,叫做ObjectFactory,专门用来创建对象的实例(MyBatis封装之后,简化了对象的创建),里面定义了4个方法。

public interface ObjectFactory {
    
    

  default void setProperties(Properties properties) {
    
    
    // NOP
  }
  <T> T create(Class<T> type);
  <T> T create(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> constructorArgs);
  <T> boolean isCollection(Class<T> type);

}
方法 作用
void setProperties(Properties properties); 设置参数时调用
T create(Class type); 创建对象(调用无参构造函数)
T create(Class type, List<Class<?>> constructorArgTypes, List constructorArgs); 创建对象(调用带参数构造函数)
boolean isCollection(Class type) 判断是否集合

ObjectFactory有一个默认的实现类DefaultObjectFactory。创建对象的方法最终都调用了instantiateClass(),这里面能看到反射的代码。

默认情况下,所有的对象都是由DefaultObjectFactory创建。

/**
 *
 * 自定义ObjectFactory,通过反射的方式实例化对象
 * 一种是无参构造函数,一种是有参构造函数——第一个方法调用了第二个方法
 */
public class MyObjectFactory extends DefaultObjectFactory {
    
    

    @Override
    public Object create(Class type) {
    
    
        System.out.println("创建对象方法:" + type);
        if (type.equals(User.class)) {
    
    
            User blog = (User) super.create(type);
            blog.setUserName("object factory");
            blog.setId(1111);
            blog.setRealName("张三");
            return blog;
        }
        Object result = super.create(type);
        return result;
    }

}

plugins

插件是MyBatis的一个很强大的机制。跟很多其他的框架一样,MyBatis预留了插件的接口,让MyBatis更容易扩展。详细内容

environments

environments标签用来管理数据库的环境,比如我们可以有开发环境、测试环境、生产环境的数据库。可以在不同的环境中使用不同的数据库地址或者类型。

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/><!-- 单独使用时配置成MANAGED没有事务 -->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>

environment

一个environment标签就是一个数据源,代表一个数据库。这里面有两个关键的标签,一个是事务管理器,一个是数据源。

transactionManager

如果配置的是JDBC,则会使用Connection对象的commit()、rollback()、close()管理事务。

如果配置成MANAGED,会把事务交给容器来管理,比如JBOSS,Weblogic。因为我们跑的是本地程序,如果配置成MANAGE不会有任何事务。

如果是Spring + MyBatis,则没有必要配置,因为会直接在applicationContext.xml里面配置数据源和事务,覆盖MyBatis的配置。

dataSource

数据源,顾名思义,就是数据的来源,一个数据源就对应一个数据库。在Java里面,它是对数据库连接的一个抽

一般的数据源都会包括连接池管理的功能,所以很多时候也把DataSource直接 称为连接池,准确的说法应该是:带连接池功能的数据源。

mappers

<mappers>标签配置的是映射器,也就是Mapper.xml的路径。这里配置的目的是让MyBatis在启动的时候去扫描这些映射器,创建映射关系。

有四种指定Mapper文件的方式:

  1. 使用相对于类路径的资源引用(resource)

     <mappers>
         <mapper resource="UserMapper.xml"/>
     </mappers>
    
  2. 使用完全限定资源定位符(绝对路径)(URL)

     <mappers>
         <mapper resource="file:///app/sale/mappers/UserMapper.xml"/>
     </mappers>
    
  3. 使用映射器接口实现类的完全限定类名

    <mappers>
       <mapper class="com.mapper.UserMapper"/>
    </mappers>
    
  4. 将包内的映射器接口实现全部注册为映射器(最常用)

    <mappers>
       <mapper class="com.mapper"/>
    </mappers>
    

映射文件

MyBatis 的真正强大在于它的语句映射,这是它的魔力所在。由于它的异常强大,映射器的 XML 文件就显得相对简单。如果拿它跟具有相同功能的 JDBC 代码进行对比,会发现省掉了将近 95% 的代码。MyBatis 致力于减少使用成本,让用户能更专注于 SQL 代码。

SQL 映射文件只有很少的几个顶级元素(按照应被定义的顺序列出):

  • cache – 该命名空间的缓存配置。
  • cache-ref – 引用其它命名空间的缓存配置。
  • resultMap – 描述如何从数据库结果集中加载对象,是最复杂也是最强大的元素。
  • parameterMap – 老式风格的参数映射。此元素已被废弃,并可能在将来被移除!请使用行内参数映射。文档中不会介绍此元素。
  • sql – 可被其它语句引用的可重用语句块。
  • insert – 映射插入语句。
  • update – 映射更新语句。
  • delete – 映射删除语句。
  • select – 映射查询语句。

resultMap

是最复杂也是最强大的元素,用来描述如何从数据库结果集中来加载对象。

<resultMap id="BaseResultMap" type="Employee">
   <id column="emp_id" jdbcType="INTEGER" property="empId"/>
   <result column="emp_name" jdbcType="VARCHAR" property="empName"/>
   <result column="gender" jdbcType="CHAR" property="gender"/>
   <result column="email" jdbcType="VARCHAR" property="email"/>
   <result column="d_id" jdbcType="INTEGER" property="dId"/>
</resultMap>

sql

<sql id="Base_Column_List">
emp_id, emp_name, gender, email, d_id
</sql>

增删改查标签

针对常用的增删改查操作提供的有对应的标签来处理

<insert> – 映射插入语句

<update> – 映射更新语句

<delete> – 映射删除语句

<select
 id="selectPerson"
 parameterType="int"
 parameterMap="deprecated"
 resultType="hashmap"
 resultMap="personResultMap"
 flushCache="false"
 useCache="true"
 timeout="10"
 fetchSize="256"
 statementType="PREPARED"
 resultSetType="FORWARD_ONLY">
属性 描述
id 在命名空间中唯一的标识符,可以被用来引用这条语句。
parameterType 将会传入这条语句的参数的类全限定名或别名。这个属性是可选的,因为 MyBatis 可以通过类型处理器(TypeHandler)推断出具体传入语句的参数,默认值为未设置(unset)。
parameterMap 用于引用外部 parameterMap 的属性,目前已被废弃。请使用行内参数映射和 parameterType 属性。
resultType 期望从这条语句中返回结果的类全限定名或别名。 注意,如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身的类型。 resultType 和 resultMap 之间只能同时使用一个。
resultMap 对外部 resultMap 的命名引用。结果映射是 MyBatis 最强大的特性,如果你对其理解透彻,许多复杂的映射问题都能迎刃而解。 resultType 和 resultMap 之间只能同时使用一个。
flushCache 将其设置为 true 后,只要语句被调用,都会导致本地缓存和二级缓存被清空,默认值:false。
useCache 将其设置为 true 后,将会导致本条语句的结果被二级缓存缓存起来,默认值:对 select 元素为 true。
timeout 这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数。默认值为未设置(unset)(依赖数据库驱动)。
fetchSize 这是一个给驱动的建议值,尝试让驱动程序每次批量返回的结果行数等于这个设置值。 默认值为未设置(unset)(依赖驱动)。
statementType 可选 STATEMENT,PREPARED 或 CALLABLE。这会让 MyBatis 分别使用 Statement,PreparedStatement 或 CallableStatement,默认值:PREPARED。
resultSetType FORWARD_ONLY,SCROLL_SENSITIVE, SCROLL_INSENSITIVE 或 DEFAULT(等价于 unset) 中的一个,默认值为 unset (依赖数据库驱动)。
databaseId 如果配置了数据库厂商标识(databaseIdProvider),MyBatis 会加载所有不带 databaseId 或匹配当前 databaseId 的语句;如果带和不带的语句都有,则不带的会被忽略。
resultOrdered 这个设置仅针对嵌套结果 select 语句:如果为 true,将会假设包含了嵌套结果集或是分组,当返回一个主结果行时,就不会产生对前面结果集的引用。 这就使得在获取嵌套结果集的时候不至于内存不够用。默认值:false
resultSets 这个设置仅适用于多结果集的情况。它将列出语句执行后返回的结果集并赋予每个结果集一个名称,多个名称之间以逗号分隔。

Supongo que te gusta

Origin blog.csdn.net/qq_28314431/article/details/133086274
Recomendado
Clasificación