9.4 深入Mapper XML映射文件

MyBatis的真正强大之处在于它的映射语句,这也是它的魔力所在。由于它的功能异常强大,映射器的XML文件就显得相对简单。如果拿它跟具有相同功能的JDBC代码进行对比,你会立即发现省掉了将近95%的代码。MyBatis就是针对SQL构建的,并且比普通的方法做得更好。

SQL映射文件的常用元素

SQL映射文件常用的元素如下

  • <select>,映射查询语句
  • <insert>,映射插入语句。
  • <update>,映射更新语句。
  • <delete>,映射删除语句。
  • <sql>,可被其他语句引用的可重用语句块。
  • <cache>,给定命名空间的缓存配置。
  • <cache-ref>,其他命名空间缓存配置的引用。
  • <resultMap>,最复杂也是最强大的元素,用来描述如何从数据库结果集中加载对象。

提示
parameterMap已废弃!它是老式风格的参数映射。

9.4.1 select

select元素用来映射查询语句,它是MyBatis中最常用的元素之一。

select元素示例

执行简单查询的select元素是非常简单的。例如:

1
2
3
4
5
6
7
8
<!-- select操作
parameterType="int"表示该查询语句需要一个int类型的参数
resultType="user"表示返回的是一个user对象 -->
<select
id="selectUser"
parameterType="int"
resultType="hashmap"> select * from tb_user where id = #{id}
</select>

这个语句被称作selectUser,其接受一个int(或Integer)类型的参数,并返回一个HashMap类型的对象,HashMap中的是查询语句结果集的列名,便是结果行中的对应值。
注意参数符号#{id},这是告诉MyBatis创建一个预处理语句参数。通过JDBC,这样的一个参数在SQL中会由一个”?“来标识,并被传递到一个新的预处理语句中。以上MyBatis配置文件执行时会生成如下JDBC代码:

1
2
3
String selectUser="select * from tb_user where id=?";
PrepareStatement ps=conn.prepareStatement(selectUser);
ps.setInt(1,id);

select元素的属性

select元素有很多属性可以配置,它们用来决定每条语句的作用细节。例如

1
2
3
4
5
6
7
8
9
10
11
<select
id="selectUser"
parameterType="int"
resultType="hashmap"
resultMap="userResultMap"
flushCache="false"
useCacher="true"
timeout="10000"
fetchSize="256"
statementType="PREPARED"
resultSetType="FORWARD_ONLY">

select元素的属性描述如下:

id

在命名空间中唯一的标识符,可以被用来引用这条语句。

parameterType

将会传入这条语句的参数类的完全限定名或别名。这个属性是可选的,因为MyBatis可以通过TypeHandler推断出具体传入语句的参数,默认值为unset

resultType

从这条语句中返回的期望类型的类的完全限定名或别名。注意如果是集合情形,那应该是集合可以包含的类型,而不能是集合本身。返回时可以使用resultTyperesultMap,但不能同时使用。

resultMap

外部resultMap的命名引用。结果集的映射是MyBatis最强大的特性,对其有一个很好的理解的话,许多复杂映射的情形都能迎刃而解。返回时可以使用resultMapresultType,但不能同时使用。

flushCache

如果设置为true,则任何时候只要语句被调用,都会导致本地缓存和二级缓存都被清空,默认值为false

useCache

如果设置为true,将会导致本条语句的结果被二级缓存,在select元素当中默认值为true

timeout

这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数默认值为unset(依赖驱动)。

fetchSize

其尝试使得驱动程序每次批量返回的结果行数和这个设置值相等。默认值为unset(依赖驱动)。

statementType

值为STATEMENTPREPAREDCALLABLE。这会让MyBatis分别使用JDBC中的Statement,PreparedStatementCallableStatement,默认值为PREPARED

resultSetType

结果集的类型,值为FORWARDONLYSCROLLSENSITIVESCROLL_INSENSITIVE,默认值为unset(依赖驱动)。

databased

如果配置了databaseldProvider,MyBatis会加载所有的不带databased或匹配当前databased的语句;如果带或者不带的语句都有,则不带的会被忽略。

resultOrdered

这个设置仅针对嵌套结果select语句适用:如果为true,就是假设包含了嵌套结果集或分组,这样的话当返回一个主结果行的时候,就不会发生对前面结果集引用的情况。这就使得在获取嵌套的结果集时不至于导致内存不够用。默认值为false

resultSets

这个设置仅对多结果集的情况适用,它将列出语句执行后返回的结果集并给每个结果集起一个名称,名称是逗号分隔的。

9.3.2 log4j.xml配置日志

之前的Java项目都是采取properties文件作为配置文件,而最新的项目大多采用XML文件作为配置文件。

对mapper接口的日志配置

在应用的CLASSPATH中增加一个名称为log4j.xml的文件

文件的具体内容如下:

D:\Desktop\随书源码\Spring+Mybatis企业应用实战(第2版)\codes\09\DMLTest\src\log4j.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?xml version="1.0" encoding="UTF-8"?>
<!-- <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> -->
<!DOCTYPE log4j:configuration
PUBLIC "-//LOG4J//DTD LOG4J//EN"
"https://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd" >
<log4j:configuration
xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="STDOUT"
class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%5p [%t] %m%n" />
</layout>
</appender>
<logger name="org.fkit.mapper.UserMapper">
<level value="TRACE" />
</logger>
<root>
<level value="ERROR" />
<appender-ref ref="STDOUT" />
</root>
</log4j:configuration>

类级别的日志

添加以上配置后,Log4j就会把org.fkit.mapper.UserMapperTRACE(详细执行)日志记录下来,对于应用中的其他类则仅仅记录ERROR(错误信息)。

语句级别的日志

也可以将日志从整个mapper接口级别调整到语句级别,从而实现更细粒度的控制。如下配置只记录selectUser语句的日志:

<logger name="org.fkit.mapper.UserMapper.selectUser">
    <level value="TRACE" />
</logger>

包级别的日志

也可以对一组mapper接口记录日志,只要对mapper接口所在的包开启日志功能即可:

1
2
3
<logger name="org.fkit.mapper">
<level value="TRACE" />
</logger>

日志只记录执行的SQL语句

某些查询可能会返回大量的数据,如果只想记录其执行的SQL语句该怎么办? 为此,

  • MyBatisSQL语句的日志级别被设为DEBUGJDK Logging中为FINE),
  • 结果日志的级别为TRACEJDK Logging中为FINER)。

所以,只要将日志级别调整为DEBUG即可:

1
2
3
<logger name="org.fkit.mapper">
<level value="DEBUG" />
</logger>

如果要记录日志的是类似下面的mapper文件而不是mapper接口又该怎么办呢?

对mapper文件的日志配置

如果要记录日志的是类似下面的mapper文件而不是接口又该怎么办呢?

<?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">
<!-- namespace指用户自定义的命名空间。 -->
<mapper namespace="org.fkit.mapper.UserMapper">
    <insert
        id="saveUser"
        parameterType="user"
        useGeneratedKeys="true"
        keyProperty="id"> insert into tb_user(name,sex,age) values(#{name},#{sex},#{age})
    </insert>
</mapper>

只要对命名空间增加日志记录功能即可:

类级别的日志

1
2
3
<logger name="org.fkit.mapper.UserMapper">
<level value="DEBUG" />
</logger>

9.3 MyBatis日志信息配置

使用MyBatis的时候,经常需要输出SQL语句、参数信息、查询结果等日志信息,为此MyBatis也提供了非常简单有效的解决方案。

MyBatis内容的日志功能

MyBatis内置的日志工厂提供日志功能,具体的日志实现有以下几种工具

  • SLF4J
  • Apache Commons Logging
  • Log4j2
  • Log4j
  • JDK logging

具体选择哪个日志实现工具由MyBatis的内置日志工厂决定。它会使用最先找到的按上文列举的顺序查找)。如果一个都未找到,日志功能就会被禁用。

不少应用服务器的classpath中己经包含Apache Commons Logging,如TomcatWebShpere,所以MyBatis会把它作为具体的日志实现。记住这点非常重要。这将意味着在诸如WebSphere的环境中WebSphere提供了Apache Commons Logging的私有实现,你的Log4j配置将被忽略。
不过,如果你的应用部署在一个包含Apache Commons Logging的环境里,而你又想用其他的日志框架比如Log4j,可以通过在MyBatis的配置文件mybatis-config.xml里面添加一项setting(配置)来选择一个不同的日志实现。这也是MyBatis推荐的做法

使用Log4j

mybatis的配置文件mybatis-config.xml中添加如下配置:

1
2
3
4
5
6
7
8
9
10
11
12
<?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">
<!-- XML 配置文件包含对 MyBatis 系统的核心设置 -->
<configuration>
......
<settings>
<setting name="logImpl" value="LOG4J"/>
</settings>
......
</configuration>

这样就是告诉MyBatis当前项目的日志实现使用Log4j,Log4j的配置信息就会起作用。

logImpl属性值

logImpl可选的值有:SLF4JLOG4JLOG4J2JDK_LOGINGCOMMONS_LOGINGSTDOUT_LOGGINGNO_LOGGING或者是实现了接口org.apache.ibatis.logging.Log的类的完全限定类名,并且这个类的构造函数需要以一个字符串(String类型)为参数。具体可以参考org.apache.ibatis.logging.slf4j.Slf4jImpl.java的实现。

下载log4j的jar包

从mybatis-版本解压目录下的lib目录中找到

log4j.jar可以直接在mybatis-版本解压文件夹下的lib文件夹中找到:

G:\Desktop\随书源码\库文件\mybatis-3.5.2\lib
├─ant-1.10.3.jar
├─ant-launcher-1.10.3.jar
├─asm-7.0.jar
├─cglib-3.2.10.jar
├─commons-logging-1.2.jar
├─javassist-3.24.1-GA.jar
├─log4j-1.2.17.jar
├─log4j-api-2.11.2.jar
├─log4j-core-2.11.2.jar
├─ognl-3.2.10.jar
├─slf4j-api-1.7.26.jar
└─slf4j-log4j12-1.7.26.jar

官网下载

也可以自己去官网下载.

Mybatis配置log4j日志步骤

MyBatis可以对包、类、命名空间和全限定的语句记录日志.
具体怎么做,视使用的日志框架而定,这里以Log4j为例。配置日志功能非常简单:

  • 首先增加依赖的jar包,如log4j.jar
  • 再添加配置文件,有log4j.propertieslog4j.xml两种,下面分别讲解两种配置文件。

添加log4j的配置文件

添加配置文件,有log4j.propertieslog4j.xml两种,下面分别讲解两种配置文件

9.3.1 log4j.properties配置日志

对mapper接口的日志配置

比如需要记录org.fkit.mapper包下的这个UserMapper接口的日志:

1
2
3
4
5
package org.fkit.mapper;
public interface UserMapper{
@Select("select FROM tb_user where id =#{id}")
User selectUser(int id);
}

在应用的CLASSPATH中增加一个名称为log4j.properties的文件,文件的具体内容如下:

# 全局日志环境配置
log4j.root.Logger=ERROR, stdout
# MyBatis日志环境配置...
log4j.logger.org.fkit.mapper.UserMapper=TRACE
# 控制台输出...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

类级别的日志

添加以上配置后,Log4j就会把org.fkit.mapper.UserMapperTRACE(详细执行)日志记录下来,对于应用中的其他类则仅仅记录ERROR(错误信息)。

语句级别的日志

也可以将日志从整个mapper接口级别调整到语句级别,从而实现更细粒度的控制。如下配置只记录selectUser语句的日志:

1
log4j.logger.org.fkit.mapper.UserMapper.selectUser=TRACE

包级别的日志

也可以对一组mapper接口记录日志,只要对mapper接口所在的包开启日志功能即可:

1
log4j.logger.org.fkit.mapper=TRACE

某些查询可能会返回大量的数据,如果只想记录其执行的SQL语句该怎么办? 为此,MyBatisSQL语句的日志级别被设为DEBUGJDK Logging中为FINE),结果日志的级别为TRACEJDK Logging中为FINER)。所以,只要将日志级别调整为DEBUG即可:

1
log4j.logger.org.fkit.mapper=DEBUG

对mapper文件的日志配置

如果要记录日志的是类似下面的mapper文件而不是接口又该怎么办呢?

<?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">
<!-- namespace指用户自定义的命名空间。 -->
<mapper namespace="org.fkit.mapper.UserMapper">
    <insert
        id="saveUser"
        parameterType="user"
        useGeneratedKeys="true"
        keyProperty="id"> insert into tb_user(name,sex,age) values(#{name},#{sex},#{age})
    </insert>
</mapper>

只要对命名空间增加日志记录功能即可:

log4j.logger.org.fkit.mapper=TRACE

9.2 深入Mybatis配置文件 9.2.8 mapper映射器

MyBatis需要开发者自己写SQL语句,mapper映射器告诉MyBatis到哪里去找映射文件,进而找到这些SQL语句。在实际开发中可以使用相对于类路径的资源引用或完全限定资源定位符(包括file:///URL),以及类名和包名等。

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<!-- mappers告诉了MyBatis去哪里找持久化类的映射文件 -->
<!-- 使用类路径查找资源文件 -->
<mappers>
<mapper resource="org/fkit/mapper/UserMapper.xml"/>
</mappers>
<!-- 使用本地文件 -->
<mappers>
<mapper url="file:///C:/mapper/UserMapper.xml"/>
</mappers>
<!-- 使用接口类 -->
<mappers>
<mapper class="org.fkit.mapper.UserMapper"/>
</mappers>
<!-- 使用包名 -->
<mappers>
<package resource="org.fkit.mapper"/>
</mappers>

mapper映射器会告诉MyBatis去哪里找映射文件,剩下的细节就是每个SQL映射文件了也就是接下来我们要重点讨论的.

9.2 深入Mybatis配置文件 9.2.7 environments配置环境

MyBatis的环境配置实际就是数据源的配置。MyBatis可以配置多种环境,这种机制使得MyBatis可以将SQL映射应用于多种数据库中。例如,开发、测试和生产环境需要有不同的配置;多个生产数据库想使用相同的SQL映射等等。

每个数据库对应一个SqlSessionFactory

尽管可以配置多个环境,但是每个SqlSessionFactory实例只能选择一个环境,即每个数据库对应一个SqlSessionFactory实例。所以,如果你想连接两个数据库,就需要创建两个SqlSessionFactory实例,每个数据库对应一个。而如果是三个数据库,就需要三个实例,依此类推。

环境配置示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<!-- 环境配置,即连接的数据库。 -->
<environments default="development">
<environment id="development">
<!-- 指定事务管理类型,type="JDBC"指直接简单使用了JDBC的提交和回滚设置 -->
<transactionManager type="JDBC">
<property
name="..."
value="..."/>
</transactionManager>
<!-- dataSource指数据源配置,POOLED是JDBC连接对象的数据源连接池的实现。 -->
<dataSource type="POOLED">
<!-- 使用配置文件db.properties中设置的driver属性值给该driver属性赋值 -->
<property
name="driver"
value="${driver}"/>
<!-- 使用配置文件db.properties中设置的url属性值给该url属性赋值 -->
<property
name="url"
value="${url}"/>
<!-- 使用配置文件db.properties中设置的username属性值给该username属性赋值 -->
<property
name="username"
value="${username}"/>
<!-- 使用配置文件db.properties中设置的password属性值给该password属性赋值 -->
<property
name="password"
value="${password}"/>
</dataSource>
</environment>
</environments>

环境配置关键点

注意这里的关键点:

  • 默认的环境id(比如:<environments default="development">)
  • 每个<environment>元素定义的环境id(比如:<environment id="development">
    • 事务管理器<transactionManager>的配置(比如:<transactionManager type="JDBC">)。
    • 数据源<dataSource>的配置(比如:<dataSource type="POOLED">)

environment配置

环境<environment>id可以随意命名,建议简洁有意义,而environments的默认环境一定要匹配定义的其中一个环境

transactionManager配置

事务管理器类型

<transactionManager>标签,表示事务管理器配置,在MyBatis中有JDBCMANAGED两种类型的事务管理器:

  • JDBC,这个配置直接使用了JDBC的提交和回滚设置,它依赖于从数据源得到的连接来管理事务范围。
  • MANAGED(managed),这个配置几乎没做什么。它从来不提交或回滚一个连接,而是让容器来管理事务的整个生命周期(比如Java EE应用服务器的上下文)。默认情况下它会关闭连接然而一些容器并不希望这样,可以将closeConnection属性设置为false来阻止它默认的关闭行为:
managed类型事务管理示例

<transactionManager>MANAGED配置示例如下

1
2
3
4
5
<transactionManager type="managed">
<property
name="closeConnection"
value="false"/>
</transactionManager>

使用Spring+MyBatis不需要配置事务管理器

如果开发者使用Spring+MyBatis,则没有必要配置事务管理器,因为Spring模块会使用自带的管理器来覆盖MyBatis的事务管理器配置

dataSource配置

<dataSource>标签表示数据源配置,在MyBatis中有UNPOOLEDPOOLEDJNDI种数据源类型

UNPOOLED数据源类型

UNPOOLED这个数据源的实现只是每次被请求时打开和关闭连接。它对没有性能要求的简单应用程序是一个很好的选择。不同的数据库在这方面表现也是不一样的。
UNPOOLED类型的数据源仅仅需要配置以下5种属性

  • driver。这是JDBC驱动的Java类的完全限定名( 并不是JDBC驱动中可能包含的数据源类)。
  • url。这是数据库的JDBC URL地址。
  • username。登录数据库的用户名。
  • password。登录数据库的密码。
  • defaultTransactionIsolationLevel。默认的连接事务隔离级别。

POOLED数据源类型

POOLED: 这种数据源的实现利用“池” 的概念将JDBC连接对象组织起来,避免了创建新的连接实例时所必需的初始化和认证时间。这是一种使得并发Web应用快速响应请求的流行处理方式。除了上述提到的UNPOOLED的5种属性外,还可以使用更多属性来配置POOLED的数据源:

  • poolMaximumActiveConnections。在任意时间可以存在的活动( 也就是正在使用) 连接数量,默认值是 10。
  • poolMaximumIdleConnections。任意时间可能存在的空闲连接数。
  • poolMaximumCheckoutTime。在被强制返回之前,池中连接被检出(checked out) 时间,默认值为 20000ms( 即 20 s)poolTimeToWait。这是一个底层设置,如果获取连接花费相当长的时间,它会给连接池打印状态日志并重新尝试获取一个连接( 避免在误配置的情况下一直安静地失败),默认值为 20000ms( 即 20 s)。
  • poolPingQuery。发送到数据库的侦测查询,用来检验连接是否处在正常工作秩序中并准备接受请求。默认是“NO PING QUERY SET”,这会导致多数数据库驱动失败时带有一个恰当的错误消息。
  • poolPingEnabled。是否启用侦测查询。若开启,也必须使用一个可执行的SQL语句设置poolPingQuery属性(最好是一个非常快的SQL),默认值为false
  • poolPingConnectionsNotUsedFor。配置poolPingQuery的使用频度。其可以被设置成匹配具体的数据库连接超时时间,来避免不必要的侦测,默认值为0(即所有连接每一时刻都被侦测,当然仅当poolPingEnabledtrue时适用)。
  • JNDI。这个数据源的实现是为了能在如EJB或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个JNDI上下文的引用。这种数据源配置只需要两个属性:
    • initial_context。这个属性用来在InitialContext中寻找上下文(即initialContext.lookup(initial_context))。这是个可选属性,如果忽略,那么data_source属性将会直接从InitialContext中寻找。
    • data_source。这是引用数据源实例位置的上下文路径。若提供了initial_context配置则会在其返回的上下文中进行查找,没有提供则直接在InitialContext中查找dataSourceJDNI配置示例如下:
1
2
3
4
<dataSource type="JNDI">
<property name="initial_context" value="java:/comp/env"/>
<property name="data_source" value="fkjavads"/>
</dataSource>

其中“java:/comp/env”是Tomcat服务器的前缀,每个Web服务器的前缀都不一样,具体请査看Web服务器相关文档。

9.2 深入Mybatis配置文件 9.2.6 objectFactory对象工厂

MyBatis每次创建结果对象的新实例时,它都会使用一个对象工厂(ObjectFactory) 实例来完成。默认的对象工厂需要做的仅仅是实例化目标类,要么通过默认构造方法,要么在参数映射存在的时候通过参数构造方法来实例化。如果想覆盖对象工厂的默认行为,则可以通过创建自己的对象工厂来实现。

实例

自定义对象工厂

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//自定义对象工厂
public class ExampleObjectFactory extends DefaultobjectFactory {
public Object create(Class type){
return super.create(type);
}
public Object create(Class type, List<Class> constructorArgTypes, List<Object> constructorArgs){
return super.create(type, constructorArgTypes, constructorArgs);
}
public void setProperties(Properties propertiessuper)
{
super.setProperties(properties);
}
public <T> boolean isCollection(Class<T> type) {
return Collection.class.isAssignableFrom(type);
}
}

在MyBatis配置文件中配置自定义对象工厂

1
2
3
<objectFactory type="org.kit.factory.ExampleobjectFactory">
<property name="some Property" value="100"/>
</objectFactory>

ObjectFactory接口很简单,它包含两个创建方法:

  • 一个是处理默认构造方法的;
  • 另外一个是处理带参数的构造方法的。

最后,setProperties方法可以被用来配置ObjectFactory,在初始化ObjectFactory实例后,objectFactory元素体中定义的属性会被传递给setProperties方法。

9.2 深入Mybatis配置文件 9.2.5 typeHandlers类型处理器

无论是MyBatis在预处理语句(PreparedStatement)中设置一个参数时,还是从结果集中取出一个值时,都会用类型处理器将获取的值以合适的方式转换成Java类型。表9.3描述了一些默认的类型处理器。

表9.3 MyBatis默认的类型处理器

9.2 深入Mybatis配置文件 9.2.4 typeAliases标签

MyBatis的配置文件包含了影响MyBatis行为的信息。文档的结构如下:

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

类型别名的作用

类型别名用来减少类完全限定名的冗余,可以为Java类型设置的一个短的名字。它只和XML配置有关。存在的意义仅在于用来减少类完全限定名的冗余。

实例 为类的完全限定名取别名

mybatis-config.xml中的配置如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?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>
......
<!-- 设置类别名 -->
<typeAliases>
<typeAlias
alias="user"
type="org.fkit.domain.User"/>
</typeAliases>
......
</configuration>

org.fkit.domain.User类设置别名为user。当在MyBatis配置文件中这样配置后,在其他Mappper XML配置文件中,任何使用org.fkit.domain.User的地方,就可以使用user替代。

在其他MyBatis的xml中使用别名

UserMapper.xml文件中使用user来替代全限定名org.fkit.domain.User

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<?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">
<!-- namespace指用户自定义的命名空间。 -->
<mapper namespace="org.fkit.mapper.UserMapper">
<!-- 以前的配置 -->
<!--
<insert
id="saveUser"
parameterType="org.fkit.domain.User"
useGeneratedKeys="true"
keyProperty="id"> insert into tb_user(name,sex,age) values(#{name},#{sex},#{age})
</insert> -->

<!--
parameterType="user"表示该插入语句需要一个user对象作为参数
这个user对象就是org.fkit.domain.User的别名
-->
<insert
id="saveUser"
parameterType="user"
useGeneratedKeys="true"
keyProperty="id"> insert into tb_user(name,sex,age) values(#{name},#{sex},#{age})
</insert>
......
</mapper>

实例 给一个包下的类批量取别名

1
2
3
<typeAliases>
<package name="org.fkit.domain"/>
</typeAliases>

每一个在包org.fkit.domain中的JavaBean,在没有注解的情况下,会使用Bean的首字母小写的非限定类名来作为它的别名。比如org.fkit.domain.User的别名为user;若有注解,则别名为其注解值。

1
2
3
4
@Alias("user")
public class User{
...
}

MyBatis默认别名

MyBatis已经为许多常见的Java类型内建了相应的类型别名(见表9.2)。它们都是大小写不敏感的,需要注意的是由基本类型名称重复导致的特殊处理。

引用类型都是其类名的全小写形式

基本数据类型对应的包装类型的别名是基本类型的名称,例如Integer的别名为int,Double的别名为double,ArrayList的别名是arraylist

包装类型的别名 映射的类型
byte Byte
short Short
int Integer
long Long
float Float
double Double
常用引用类型的别名 映射的类型
string String
date Date
bigdecimal BigDecimal
object Object
map Map
hashmap HashMap
list List
arraylist ArrayList
collection Collection
iterator Iterator

基本类型前面多一个下划线

需要注意的是基本数据类型,为了避免和包装类型的别名重名,基本类型的别名前面多了一个下划线,也就是基本数据类型的别名是:下划线基本类型名,例如int类型的别名为_int,double的别名为_double

基本类型的别名 映射的类型
_byte byte
_short short
_int int
_long long
_float float
_double double

9.2 深入Mybatis配置文件 9.2.3 settings设置

MyBatis的配置文件包含了影响MyBatis行为的信息。文档的结构如下:

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

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

表9.1 settings设置的详细说明


设置参数 描述 有效值 默认值
cacheEabled 该配置影响所有映射器中配置的缓存的全局开关 true|false true
lazyLoadingEnabled 延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。特定关联关系中可通过设置fetchType属性来覆盖该项的开关状态 true,false false
aggressiveLazyLoading 当启用时,对任意延迟属性的调用会使带有延迟加载属性的对象完整加载:反之,每种属性将会按需加载 true,false true
multipleResultSetsEnabled 是否允许单一语句返回多结果集(需要兼容驱动) true|false true
useColumnLabel 使用列标签代替列名。不同的驱动在这方面会有不同的表现,具体可参考相关驱动文档或通过测试这两种不同的模式来观察所用驱动的结果 true|false true
useGeneratedKeys 允许JDBC支持自动生成主键,需要驱动兼容。如果设置为true则这个设置强制使用自动生成主键,尽管一些驱动不能兼容但仍可正常工作(比如Derby) true|false false
autoMappingBehavior 指定MyBatis应如何自动映射列到字段或属性。NONE表示取消自动映射;PARTIAL只会自动映射没有定义嵌套结果集映射的结果集。FULL会自动映射任意复杂的结果集(无论是否嵌套) NONE|PARTIAL|FULL PARTIAL
autoMappingUnknownColumnBehavior NONE:什么都不做;WARNING:输出警告;FAILING:映射失败,抛出SqlSessionException; NONE|WARNING|FAILING NONE
defaultExecutorType 配置默认的执行器。SIMPLE就是普通的执行器;REUSE执行器会重用预处理语句(prepared statements);BATCH执行器将重用语句并执行批量更新 SIMPLE|REUSE|BATCH SIMPLE
defaultStatementTimeout 设置超时时间,它决定驱动等待数据库响应的秒数 integer 没有设置(null)
defaultFetchSize 默认返回的结果集的大小 integer 没有设置(null)
safeRowBoundsEnabled 允许在嵌套语句中使用分页(RowBounds) true|false false
mapUnderscoreToCamelCase 是否开启自动驼峰命名规则(camelcase)映射 true|false false
localCacheScope MyBatis利用本地缓存机制(LocalCache)防止循环引用(circularreferences)和加速重复嵌套查询。默认值为SESSION,这种情况下会缓存一个会话中执行的所有查询。若设置值为STATEMENT,则本地会话仅用在语句执行上,对相同SqlSession的不同调用将不会共享数据 SESSION|STATEMENT SESSION
jdbcTypeForNull 当没有为参数提供特定的JDBC类型时,为空值指定JDBC类型。某些驱动需要指定列的DBC类型,多数情况直接用一般类型即可,比如NULL、VARCHAR或OTHER NULL|VARCHAR|OTHER OTHER
lazyLoadTriggerMethods 指定哪个对象的方法触发一次延迟加载 方法名的list集合 equals,clone,hashCode,toString
defaultScriptingLanguage 指定动态SQL生成的默认语言 一个类型别名或完全限定类名 org.apache.ibatis.scripting.xmltags.XMLDynamicLanguageDriver
callSettersOnNulls 指定当结果集中值为null时是否调用映射对象的setter(map对象时为put)方法,这对于有Map.keySetO依赖或null值初始化时是有用的。注意基本类型(int、boolean等)是不能设置成null的 true|false false
logPrefix 指定MyBatis增加到日志名称的前缀 String 没有设置(null)
logImpl 指定MyBatis所用日志的具体实现未指定时将自动查找 SLF4J
|LOG4J
|LOG4J2
|JDK_LOGGING
|COMMONS_LOGGING
|STDOUT_LOGGING
|NO_LOGGING
没有设置(null)
proxyFactory 指定MyBatis创建具有延迟加载能力的对象所用到的代理工具 CGLIB|JAVASSIST JAVASSIST(MyBatis 3.3 or above)

实例

MyBatis配置文件mybatis-config.xml中设置日志实现,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?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">
<!-- XML 配置文件包含对 MyBatis 系统的核心设置 -->
<configuration>
......
<!-- 指定 MyBatis 所用日志的具体实现 -->
<settings>
<setting
name="logImpl"
value="LOG4J"/>
</settings>
......
</configuration>

9.2 深入Mybatis配置文件 9.2.2 properties属性

MyBatis的配置文件包含了影响MyBatis行为的信息。文档的结构如下:

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

properties元素

项目结构

D:\Desktop\随书源码\Spring+Mybatis企业应用实战(第2版)\codes\09\DMLTest
├─src
│ ├─db.properties
│ ├─mybatis-config.xml
│ └─省略java代码,省略其他配置
└─WebContent
  ├─省略其他目录
  └─WEB-INF
    ├─lib
    │ ├─省略jar文件
    └─web.xml

这些属性都是可外部配置且可动态替换的,既可以在典型的Java属性文件中配置,亦可通过 properties元素的子元素来传递。

创建自定义properties配置文件

可以在CLASSPATH中增加一个db.properties的属性文件

1
2
3
4
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/mybatis
username=root
password=root

在MyBatis根配置文件中使用上述属性

引入配置文件

1
2
<!-- 引入properties资源文件,以便后面使用 -->
<properties resource="db.properties"/>

使用配置文件中设置好的属性

引入类db.properties后,使用的格式为:

1
${properties配置文件中设置的属性}

例如:使用配置文件db.properties中设置的username属性值。

1
2
3
4
<!-- 使用配置文件db.properties中设置的username属性值给该username属性赋值 -->
<property
name="username"
value="${username}"/>

具体如下代码所示:

mybatis-config.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<?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">
<!-- XML 配置文件包含对 MyBatis 系统的核心设置 -->
<configuration>
<!-- 引入properties资源文件,以便后面使用 -->
<properties resource="db.properties"/>
<!-- 指定 MyBatis 所用日志的具体实现 -->
<!-- 环境配置,即连接的数据库。 -->
<environments default="mysql">
<environment id="mysql">
<!-- 指定事务管理类型,type="JDBC"指直接简单使用了JDBC的提交和回滚设置 -->
<transactionManager type="JDBC"/>
<!-- dataSource指数据源配置,POOLED是JDBC连接对象的数据源连接池的实现。 -->
<dataSource type="POOLED">
<!-- 使用配置文件db.properties中设置的driver属性值给该driver属性赋值 -->
<property
name="driver"
value="${driver}"/>
<!-- 使用配置文件db.properties中设置的url属性值给该url属性赋值 -->
<property
name="url"
value="${url}"/>
<!-- 使用配置文件db.properties中设置的username属性值给该username属性赋值 -->
<property
name="username"
value="${username}"/>
<!-- 使用配置文件db.properties中设置的password属性值给该password属性赋值 -->
<property
name="password"
value="${password}"/>
</dataSource>
</environment>
</environments>
</configuration>