Mybatis 核心配置

        在MyBatis中我们发现其实他最核心的应该是那两个配置文件,一个全局配置文件,一个映射文件。 我们只要把这两个文件弄清楚,其实对于MyBatis的使用就掌握了大部分。接下来我们详细的给大家来 介绍下这两个配置文件。

全局配置文件

        MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置和属性信息。 配置文档的顶层结构如 下:

标签描述
configuration配置
properties属性
settings设置
typeAliases类型别名
typeHandlers类型处理器
objectFactory对象工厂
plugins插件
environments环境配置
environment环境变量
transactionManager事务管理器
dataSource数据源
databaseIdProvider数据库厂商标识
mappers映射器

configuration

        configuration是整个配置文件的根标签,实际上也对应着MyBatis里面最重要的配置类Configuration。它贯穿MyBatis执行流程的每一个环节。我们打开这个类看一下,这里面有很多的属性,跟其他的子标签也能对应上。

properties

        第一个一级标签是properties,用来配置参数信息,比如最常见的数据库连接信息。为了避免直接把参数写死在xml配置文件中,我们可以把这些参数单独放在properties文件中,用 properties标签引入进来,然后在xml配置文件中用${}引用就可以了。可以用resource引用应用里面的 相对路径,也可以用url指定本地服务器或者网络的绝对路径。

settings

        这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。 下表描述了设置中各 项设置的含义、默认值等。

<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是类型的别名,跟Linux系统里面的alias一样,主要用来简化类名全路径的拼写。比如我 们的参数类型和返回值类型都可能会用到我们的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);
}

 TypeHandler

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

        当参数类型和返回值是一个对象的时候,没有做任何配置的情况下,为什么对象里面的一个String属性可以转换成数据库里面的varchar字段?

        这是因为mybatis已经内置了很多TypeHandler(在type包下),他们全都注册在TypeHandlerRegistry中,他们都继承了抽象类BaseTypeHandler,泛型就是要处理的Java数据类型。

        这个也是为什么大部分类型都不需要处理,当我们查询数据和登记数据,做数据类型转换的时候就会自动自动调用对应的TypeHandler方法。

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

package cloud2.outer.service.impl;

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * 自定义的类型处理器
 * 处理的字段如果是 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.gupaoedu.type.MyTypeHandler"></typeHandler>
</typeHandlers>

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> constructorArgTypes, List constructorArgs);创建对象(调用带参数构造函 数)
boolean isCollection(Class type)判断是否集合

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

plugins

        插件是MyBatis的一个很强大的机制。跟很多其他的框架一样,MyBatis预留了插件的接口,让 MyBatis更容易扩展。     mybatis – MyBatis 3 | 配置   具体的插件的原理使用后面的章节会详细介绍。

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

        标签配置的是映射器,也就是Mapper.xml的路径。这里配置的目的是让MyBatis在启动 的时候去扫描这些映射器,创建映射关系。 我们有四种指定Mapper文件的方式: mybatis – MyBatis 3 | 配置

  • 使用相对于类路径的资源引用(resource)
<mappers>
    <mapper resource="UserMapper.xml"/>
</mappers>
  • 使用完全限定资源定位符(绝对路径)(URL)
<mappers>
    <mapper resource="file:///app/sale/mappers/UserMapper.xml"/>
</mappers>
  • 使用映射器接口实现类的完全限定类名
<mappers>
    <mapper class="com.mapper.UserMapper"/>
</mappers>
  • .将包内的映射器接口实现全部注册为映射器(最常用)
<mappers>
    <mapper class="com.mapper"/>
</mappers>

映射文件

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

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

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

cache

        给定命名空间的缓存配置(是否开启二级缓存)。

cache-ref

        其他命名空间缓存配置的引用。缓存相关两个标签我们在讲解缓存的时候会详细讲到。

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。
resultSetTypeFORWARD_ONLY,SCROLL_SENSITIVE, SCROLL_INSENSITIVE 或DEFAULT(等价于 unset) 中的一个,默认值为 unset (依赖数据库驱动)。
databaseId如果配置了数据库厂商标识(databaseIdProvider),MyBatis 会加载所有不带 databaseId 或匹配当前 databaseId 的语句;如果带和不带的语句都有,则不带的会被忽略。
resultOrdered这个设置仅针对嵌套结果 select 语句:如果为 true,将会假设包含了嵌套结果集或是分组,当返回一个主结果行时,就不会产生对前面结果集的引用。这就使得在获取嵌套结果集的时候不至于内存不够用。默认值: false 。
resultSets这个设置仅适用于多结果集的情况。它将列出语句执行后返回的结果集并赋予每个结果集一个名称,多个名称之间以逗号分隔。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值