Mybatis - 核心配置文件Mybatis-config.xml标签详解(上)

前言

Mybatis是基于XML配置或者注解完成数据库操作
前面入门了Mybatis,完成了CRUD

现在仔细了解mybatis-config.xml中的配置


官网

先看官网:Mybatis官网

一切以官网为准,补充说明官网

在这里插入图片描述

配置有上述这些

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

配置文件

<?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>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&amp;useUnicode=true&amp;characterEncoding=UTF8&amp;serverTimezone=Asia/Shanghai"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>
    <!--每一个mapper.xml都需要在mybatis的核心配置文件注册-->
    <mappers>
        <mapper resource="com/learn/dao/UserMapper.xml"/>
    </mappers>
</configuration>

约束

其中xml配置信息的约束文件,应该都很熟悉

这是主配置文件约束:configuration

<?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">

而我们的mapper.xml文件是这种约束:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

这是一种XML的Schema约束
不了解的可以看:真的了解XML吗? - XML 基础

这些约束限制了标签,可以查看有什么标签

从约束文件
在这里插入图片描述

中可以看到:这些标签是有顺序的,如果顺序错了会报错

configuration (properties?, settings?, typeAliases?, typeHandlers?, objectFactory?, objectWrapperFactory?, reflectorFactory?, plugins?, environments?, databaseIdProvider?, mappers?)

最外层是configuration 根标签,表示这是Mybatis核心配置文件mybatis-config.xml


属性(properties)

properties标签提供了引入外部文件或者设置变量的方法

在这个标签内定义的属性可以在该xml文件引用(就会Java的全局变量一样)

如:

    <properties>
        <property name="id" value="zhangsan"/>
    </properties>

这样是设置了一个id = zhangsan 键值对,在该xml使用时直接引用id即可,取值直接${id}就可以取出,这就让我们可以动态配置信息,在后面就可以用外部文件配置数据库连接信息
(和Map类似)

可以引入外部文件

在这里插入图片描述

提供了两种方法:

  • resource:读取相对地址文件
  • url:读取绝对地址文件

如:

<properties resource="db.properties"/>
<properties  url="file:D:\JavaProject\mybatis\mybatis-cache\src\main\resources\db.properties"/>

如果是绝对路径:url前要加上file:,这是只是windows帮我们省略了

读取的文件也得以键值对(a:b或者a=b)的方式存储数据,不然就读不出(Java的properties文件)

不以name=value的形式,IDEA也会提醒你

如:在db.properties文件编写(也可以用:分隔,不过IDEA会警告)

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
username=root
password=root

在这里插入图片描述
然后把以前的配置改变:

<?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"/>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED" >
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <package name="com.learn.dao"/>
    </mappers>
</configuration>

这样一样可以完成数据库的连接,这就是获取了配置文件中是键值对属性

Java传值

很明显,如果是XML或者properties文件中配置,就无法对数据加密
加密就需要Java程序
除了在XML或者properties文件中配置,也可以在Java程序中配置

SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, props);

// ... 或者 ...

SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environment, props);

这个涉及到Mybatis工作流程,后面再细说

如果数据很重要,可以选择Java加密传输

配置读取顺序

如果一个属性在不只一个地方进行了配置,那么,MyBatis 将按照下面的顺序来加载:

  • 首先读取在 properties 元素体内指定的属性
  • 然后根据 properties 元素中的 resource 属性读取类路径下属性文件,或根据 url属性指定的路径读取属性文件,并覆盖之前读取过的同名属性
  • 最后读取作为方法参数传递的属性(Java传值),并覆盖之前读取过的同名属性

因此,通过方法参数传递的属性具有最高优先级,resource/url 属性中指定的配置文件次之,最低优先级的则是 properties 元素中指定的属性

占位符

从 MyBatis 3.4.2 开始,你可以为占位符指定一个默认值

<dataSource type="POOLED">
  <!-- 如果属性 'username' 没有被配置,'username' 属性的值将为 'ut_user' -->
  <property name="username" value="${username:ut_user}"/> 
</dataSource>

这个特性默认是关闭的,需要在属性中打开

<properties resource="org/mybatis/example/config.properties">
	<!-- 启用默认值特性 -->
  <property name="org.apache.ibatis.parsing.PropertyParser.enable-default-value" value="true"/> 
</properties>

可以看出,它也是引用了外部配置文件

属性名

可以看出,Mybatis读取键值对是以:或者=为分割
所以,如果属性名存在冒号、等号,或者在 SQL 映射中使用了 OGNL 表达式的三元运算符(如: ${tableName != null ? tableName :'global_constants'}

需要修改默认值的分隔符

<properties resource="org/mybatis/example/config.properties">
  <!-- ... -->
  <property name="org.apache.ibatis.parsing.PropertyParser.default-value-separator" value="?:"/> <!-- 修改默认值的分隔符 -->
</properties>

最好还是别瞎写

只能引入一个外部文件

在这里插入图片描述
很明显,一个xml里只能有一个properties标签,标签中也只能有一个resource

所以,如果想要配不同环境的话,需要写多个核心配置文件


设置(settings)

这是一个很重要的标签,通过该标签改变Mybatis的内部配置

在这里插入图片描述

有很多属性,可以自行查看官网

常用的有:

  • cacheEnabled :开启全局缓存(后面缓存在介绍)
  • logImpl :日志配置(后面日志工厂介绍)
  • defaultStatementTimeout:数据库驱动连接数据库响应时间
  • defaultResultSetType:语句默认回滚策略
  • mapUnderscoreToCamelCase:将数据库取出的带下划线的数据名改为驼峰命名
<settings>
  <setting name="cacheEnabled" value="true"/>
  <setting name="lazyLoadingEnabled" value="true"/>
  <setting name="multipleResultSetsEnabled" value="true"/>
  <setting name="useColumnLabel" value="true"/>
  <setting name="useGeneratedKeys" value="false"/>
  <setting name="autoMappingBehavior" value="PARTIAL"/>
  <setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>
  <setting name="defaultExecutorType" value="SIMPLE"/>
  <setting name="defaultStatementTimeout" value="25"/>
  <setting name="defaultFetchSize" value="100"/>
  <setting name="safeRowBoundsEnabled" value="false"/>
  <setting name="mapUnderscoreToCamelCase" value="false"/>
  <setting name="localCacheScope" value="SESSION"/>
  <setting name="jdbcTypeForNull" value="OTHER"/>
  <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
</settings>

其实大部分都用不到,settings标签改变的是Mybatis内置的一些属性


类型别名(typeAliases)

还记得我们前面配置mapper.xml时resultType

标签里的这个resultType,如果输出结果是某个类的对象时,就需要写完整的包名

<select id="getUserList" resultType="com.learn.pojo.User">
        select * from mybatis.user
</select>

很繁琐,通过类型别名可以解决

类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写

有多种配置方法:

  1. typeAlias 子标签直接配置
<typeAliases>
    <typeAlias type="com.learn.pojo.User" alias="User"/>
</typeAliases>

这样就设置好了一个别名

在mapper.xml中就可以直接使用User

<select id="getUserList" resultType="User">
    select * from mybatis.user
</select>
  1. 扫描包
    对于整个pojo包有多个实体类,有上面的方法就比较繁琐,可以直接扫描整个pojo包
<typeAliases>
        <package name="com.learn.pojo"/>
</typeAliases>

不过,因为是自动扫描的,类的别名就是该类名(大小写都可以),不能取其他别名

  1. 在实体类上注释
    这是在以后全面抛弃xml时使用的方法,如果还需要XML就没必要用这种方法
    在这里插入图片描述

上面的我们自己的类需要别名,Mybatis内置了一些常用属性的别名

别名映射的类型
_bytebyte
_longlong
_shortshort
_intint
_integerint
_doubledouble
_floatfloat
_booleanboolean
stringString
byteByte
longLong
shortShort
intInteger
integerInteger
doubleDouble
floatFloat
booleanBoolean
dateDate
decimalBigDecimal
bigdecimalBigDecimal
objectObject
mapMap
hashmapHashMap
listList
arraylistArrayList
collectionCollection
iteratorIterator

可以看到,基本类型是前面加了下划线的,和封装类型不同


类型处理器(typeHandlers)

MyBatis 在设置预处理语句(PreparedStatement)中的参数或从结果集中取出一个值时, 都会用类型处理器将获取到的值以合适的方式转换成 Java 类型

这是Mybatis对javaType和jdbcType类型之间的转换

比如,Java实体类中用Date型表示时间,数据库中用varchar型表示,就需要用类型处理器,把实体类中的时间数据转换后放入数据库

Mybatis内置了很多类型处理器,详情看官网

在这里插入图片描述

绝大多数的类型转换Mybatis都考虑到了
如果想自定义类型处理器,有两种方法:

  • 继承BaseTypeHandler类
  • 实现TypeHandler接口

例如,前面说的javaType中的Date类型与jdbcType中的varchar类型之间的转化

package com.learn.util;

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

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class Myhandler implements TypeHandler<Date> {
    @Override
    // 设置sql中指定索引的参数,即将javaType转化为jdbcType
    public void setParameter(PreparedStatement ps, int i, Date parameter, JdbcType jdbcType) throws SQLException {
        //设置数据存储到数据库中的格式
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        ps.setString(i, sdf.format(parameter));
    }

    @Override
    // 根据列名称从结果集获取值,并将jdbcType转换成javaType
    public Date getResult(ResultSet rs, String columnName) throws SQLException {
        String columnValue = rs.getString(columnName);
        if (null != columnValue) {
            return new Date(Long.valueOf(columnValue));
        }
        return null;
    }

    @Override
    // 根据列名称从结果集获取值,并将jdbcType转换成javaType
    public Date getResult(ResultSet rs, int columnIndex) throws SQLException {
        String columnValue = rs.getString(columnIndex);
        if (null != columnValue) {
            return new Date(Long.valueOf(columnValue));
        }
        return null;
    }

    @Override
    public Date getResult(CallableStatement cs, int columnIndex) throws SQLException {
        String columnValue = cs.getString(columnIndex);
        if (null != columnValue) {
            return new Date(Long.valueOf(columnValue));
        }
        return null;
    }
}

然后在核心配置文件上加入:

<!--类型处理器 -->
<typeHandlers>
    <!-- 注册自定义handler,说明它作用的jdbcType和javaType -->
     <typeHandler jdbcType="VARCHAR" javaType="date" handler="com.learn.util.Myhandler" />
</typeHandlers>

然后在Mapper.xml中引入,就配置完成了

这位大佬写的挺好的:MyBatis配置文件(四)--typeHandlers

没必要自定义类型处理器


后续

Mybatis-config.xml配置文件有很多属性,这一篇详细介绍了约束、properties、settings、typeAliases、typeHandlers

后续还有objectFactory(对象工厂)、plugins(插件) environment(环境变量) transactionManager(事务管理器)
dataSource(数据源)databaseIdProvider(数据库厂商标识)mappers(映射器)

学海无涯苦作舟

看到这了,点个赞呗(^_−)☆

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值