Mapper XML配置
MyBatis的XML配置文件包含了设置和影响MyBatis行为的属性。XML配置文件的层次结构如下:
- configuration
- properties
- settings
- typeAliases
- typeHandlers
- objectFactory
- plugins
- environments
- environment
- transactionManager
- dataSource
- mappers
properties元素
它们都是外部化,可替代的属性。可以配置在一个典型的Java属性文件中,或者通过
properties元素的子元素进行配置。例如:
<properties resource="org/mybatis/example/config.properties">
<property name="username" value="dev_user"/>
<property name="password" value="F2Fa3!33TYyg"/>
</properties>
在整个配置文件中,这些属性能够被可动态替换(即使用占位符)的属性值引用,例如:
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/> </dataSource>
示例中的username和password将会被替换为配置在properties元素中的相应值。driver和 url属性则会被config.properties文件中的相应值替换。这里提供了大量的配置选项。这些属性也可以传递给sqlSessionFactoryBuilder.build()方法。例如:
SqlSessionFactory factory = sqlSessionFactoryBuilder.build(reader, props);
// ... or ...
SqlSessionFactory factory = sqlSessionFactoryBuilder.build(reader, environment, props);
如果一个属性存在于多个地方,MyBatis将使用下面的顺序加载:
• 首先读入properties元素主体中指定的属性。
• 然后会加载类路径或者properties元素中指定的url的资源文件属性。它会覆盖前面已经读入的重复属性。
• 通过方法参数来传递的属性将最后读取(即通过sqlSessionFactoryBuilder.build),同样也会覆盖从properties元素指定的和resource/url指定的重复属性。
因此最优先的属性是通过方法参数来传递的属性,然后是通过resource/url配置的属性,最后是在MyBatis的Mapper配置文件中,properties元素主体中指定的属性。
Settings元素
Setting元素下是些非常重要的设置选项,用于设置和改变MyBatis运行中的行为。下面的表格列出了Setting元素支持的属性、默认值及其功能。
设置选项 | 描述 | 可用值 | 默认值 |
---|---|---|---|
cacheEnabled | 全局性地启用或禁用所有在mapper 配置文件中配置的缓存。 | true|false | true |
lazyLoadingEnabled | 全局性地启用或禁用延迟加载。当禁用时,所有关联的配置都会立即加载。 | true|false | true |
aggressiveLazyLoading | 当启用后,一个有延迟加载属性的对象的任何一个延迟属性被加载时,该对象的所有的属性都会被加载。否则,所有属性都是按需加载。 | true|false | true |
multipleResultSetsEnabled | 允许或禁止从单一的语句返回多个结果集(需要驱动程序兼容)。 | true|false | true |
useColumnLabel | 使用列的标签而不是列的名称。在这方面,不同的驱动程序可能有不同的实现。参考驱动程序的文档或者进行测试来确定您所使用的驱动程的行为 | true|false | true |
useGeneratedKeys | 允许JDBC 自动生成主键。需要驱动程序兼容。如果设置为true则会强行自动生成主键,然而有些则不会自动生成主键(驱动程序不兼容),但依旧会工作(如Derby)。 | true|false | false |
autoMappingBehavior | 指定MyBatis是否以及如何自动将列映射到字段/属性。 PARTIAL: 只是自动映射简单、非嵌套的结果集。 FULL: 将会自动映射任何复杂的(嵌套或非嵌套)的结果集。 | NONE,PARTIAL,FULL | PARTIAL |
defaultExecutorType | 配置默认的执行器(executor)。 SIMPLE :简单的执行器。 REUSE :重用prepared statements的执行器。 BATCH:重用statements并且进行批量更新的执行器。 | SIMPLE,REUSE,BATCH | SIMPLE |
defaultStatementTimeout | 设置查询数据库超时时间。 | 任何正整数 | Not Set (null) |
一个Settings元素完整的配置例子如下:
<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="enhancementEnabled" value="false"/>
<setting name="defaultExecutorType" value="SIMPLE"/>
<setting name="defaultStatementTimeout" value="25000"/> </settings>
typeAliases元素
别名是一个较短的Java类型的名称。这只是与XML配置文件相关联,减少输入多余的完整类名。例如:
<typeAliases>
<typeAlias alias="Author" type="domain.blog.Author"/>
<typeAlias alias="Blog" type="domain.blog.Blog"/>
<typeAlias alias="Comment" type="domain.blog.Comment"/>
<typeAlias alias="Post" type="domain.blog.Post"/>
<typeAlias alias="Section" type="domain.blog.Section"/>
<typeAlias alias="Tag" type="domain.blog.Tag"/> </typeAliases>
在这个配置中,您就可以在想要使用"domain.blog.Blog"的地方使用别名“Blog”了。
对常用的java类型,已经内置了一些别名支持。这些别名都是不区分大小写的。注意java 的基本数据类型,它们进行了特别处理,加了“_”前缀
Environments元素
MyBatis能够配置多套运行环境,这有助于将您的SQL映射到多个数据库上。例如,在您的开发、测试、生产环境中,您可能有不同的配置。或者您可能有多个共享同一schema的生产用数据库,或者您想将相同的SQL映射应用到两个数据库等等许多用例。
但是请记住:虽然您可以配置多个运行环境,但是每个SqlSessionFactory实例只能选择一
个运行环境。
因此,如果您想连接两个数据库,就需要创建两个SqlSessionFactory实例,一个数据库对应一个SqlSessionFactory实例。如果是三个数据库,那就创建三个实例,如此类推。这真的非常容易记住:
每个数据库对应一个SqlSessionFactory实例。
要指定哪个运行环境被创建,只需要简单地将运行环境作为可选参数传递给
SqlSessionFactoryBuilder,下面是两个接受运行环境的方法:
SqlSessionFactory factory = sqlSessionFactoryBuilder.build(reader, environment);
SqlSessionFactory factory = sqlSessionFactoryBuilder.build(reader, environment,properties);
如果环境参数被忽略,那默认的环境配置将被加载,如下面:
SqlSessionFactory factory = sqlSessionFactoryBuilder.build(reader);
SqlSessionFactory factory = sqlSessionFactoryBuilder.build(reader,properties);
environments 元素定义了运行环境是怎么配置的:
<environments default="development">
<environment id="development">
<transactionManager type="JDBC">
<property name="..." value="..."/>
</transactionManager>
<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>
注意这里关键的部分:
• 默认的运行环境ID,引用一个已经定义好的运行环境ID(例如: default=“development”)
• 每个定义的运行环境ID(例如:id=“development”)
• 事务管理器配置(例如: type=“JDBC”) • 数据源配置(例如:type=“POOLED”)
默认的环境和环境ID是自解(self explanatory)的,只要您喜欢,就可以随意取一个名字,只要确保默认的运行环境引用一个已定义的运行环境就可以了。
注:
<environments default="test">
<environment id="development">
……
</environment>
<environment id="production">
……
</environment>
<environment id="test">
……
</environment>
</environments>
上面例子中,配置表明,目前使用的是test的运行环境。当然,您也可以修改为使用production的运行环境:。
事务管理器
MyBatis有两种事务管理类型(即type=”[JDBC|MANAGED]”):
• JDBC – 这个配置直接使用JDBC的提交和回滚功能。它依赖于从数据源获得连接来管理事务的生命周期。
• MANAGED – 这个配置基本上什么都不做。它从不提交或者回滚一个连接的事务。而是让容器(例如:Spring或者J2EE应用服务器)来管理事务的生命周期 。默认情况下,它会关闭连接,但是一些容器并不会如此,因此,如果您需要通过关闭连接来停止事务,将属性closeConnection设置为false。例如:
<transactionManager type="MANAGED">
<property name="closeConnection" value="false"/> </transactionManager>
这两个事务管理类型都不需要任何属性。然而它们都是类型别名,换句话说,您可以设置成指向己实现了TransactionFactory接口的完整类名或者别名。
public interface TransactionFactory {
void setProperties(Properties props);
Transaction newTransaction(Connection conn, boolean autoCommit); }
实例化后,任何在XML文件配置的属性都将传递给setProperties()方法。在您的实现中还
需要创建一个非常简单的Transaction接口的实现:
public interface Transaction { Connection getConnection(); void commit() throws SQLException; void rollback() throws SQLException; void close() throws SQLException; }
通过这两个接口,您能够完全自定义MyBatis如何来处理事务。
dataSource元素
dataSource元素使用标准的JDBC数据源接口来配置JDBC连接对象源。
大部分MyBatis应用都像上面例子那样配置一个数据源,但这不是必须的。需要认清的是,只有使用了延迟加载才需要数据源。
MyBatis内置了三种数据源类型 (如: type=”???”):
UNPOOLED – 这个类型的数据源实现只是在每次需要的时候简单地打开和关闭连接。虽然有点慢,但是对于不需要立即响应的简单的应用来说,不失为一种好的选择。不同的数据库在性能方
面也会有所不同,因此对于一些数据库,不使用连接池时,这个配置就是比较理想的。
UNPOOLED数据源有四个配置属性:
• driver – 指定JDBC驱动器。
• url – 连接数据库实例的JDBC URL。
• username –登陆数据库的用户名。
• password - 登陆数据库的密码。
• defaultTransactionIsolationLevel – 指定连接的默认事务隔离级别。
另外,您也可以通过在属性前加前缀“driver”的方式,把属性传递给数据库驱动器,例如:
• driver.encoding=UTF8
这将会通过DriverManager.getConnection(url, driverProperties) 方法,将值是
“UTF8”的属性“encoding”传递给数据库驱动器。
POOLED – 这个数据源的实现缓存了JDBC连接对象,用于避免每次创建新的数据库连接时都初始化和进行认证,加快程序响应。并发WEB应用通常通过这种做法来获得快速响应。
另外,除了上面(UNPOOLED)的属性外,对POOLED数据源,还有很多属性可以设置。
• poolMaximumActiveConnections – 在任何特定的时间内激活(能够被使用)的连接数量,默认是10。
• poolMaximumIdleConnections –在任何特定的时间内空闲的连接数。
• poolMaximumCheckoutTime – 在连接池被强行返回前,一个连接能够“检出”的总时间。默认是20000ms(20秒)。
• poolTimeToWait – 这是一上比较底层的设置,如果连接占用了很长时间,能够给连接池一个机会去打印日志,并重新尝试连接。默认是20000ms(20秒)。
• poolPingQuery –Ping Query 是发送给数据库的Ping 信息,测试数据库连接是否良好和是否准备好了接受请求。默认值是“NO PING QUERY SET”,让大部分数据库都不使用 Ping,返回一个友好的错误信息(译者注:MyBatis通过向数据执行SQL语句来确定与数据库连接状况)。
• poolPingEnabled – 这是允许或者禁ping query 的开关。如果允许,您同时也要用一条可用的(并且应该是最高效的)SQL语句来设置poolPingQuery 属性的值。默认是: false(即禁止)。
• poolPingConnectionsNotUsedFor – 这个属性配置执行poolPingQuery 的间隔时间。通常设置为与数据库连接的超时时间,来避免不必要的pings 。默认是:0(允许所有连接随时进行ping测试,当然只有poolPingEnabled设置为true才会生效)。
JNDI – 这个数据源的配置是为了准备与像Spring或应用服务器能够在外部或者内部配置数据源的容器一起使用,然后在JNDI上下文中引用它。这个数据源只需配置两个属性:
• initial_context – 这个属性被用来从InitialContext 中查找一个上下文。如:
initialContext.lookup(initial_context)
这个属性是可选的,如果忽略,那么数据源就会直接从InitialContext中查找。
• data_source – 这个属性是引用一个能够被找到的数据源实例的上下文路径。它会查找根据initial_context 从initialContext中搜寻返回的上下文。或者在 initial_context没有提供的情况下直接在InitialContext 中进行查找。
注:
Context context = (Context) initialContext.lookup(initial_context);//返回
一个上下文
//Context context = (Context)initContext.lookup("java:/comp/env");
DataSource ds = (DataSource) context.lookup(data_source); //返回一个数据源
Connection conn = ds.getConnection();
//DataSource ds = (DataSource)context.lookup("jdbc/myoracle"); 如果initial_context没有配置,那么数据源就会直接从InitialContext进行查
找,如:
DataSource ds = (DataSource) initialContext.lookup(data_source);
跟数据源的其它属性配置一样,可以通过在属性名前加“env.”的方式直接传递给
InitialContext。例如:
• env.encoding=UTF8
这将会把属性“encoding”及它的值“UTF8”在InitialContext实例化的时候传递给它的构造器。
Mappers元素
现在,MyBatis的行为属性都已经在上面的配置元素中配置好了,接下来开始定义映射SQL
语句。但首先,我们需要告诉MyBatis在哪里能够找到我们定义的映射SQL语句。在这方面, JAVA自动发现没有提供好的方法,因此最好的方法是告诉MyBatis在哪里能够找到这些映射文件。您可以使用类资源路径或者URL(包括file:/// URLs),例如:
<!-- Using classpath relative resources -->
<mappers>
<mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
<mapper resource="org/mybatis/builder/BlogMapper.xml"/>
<mapper resource="org/mybatis/builder/PostMapper.xml"/>
</mappers>
<!-- Using url fully qualified paths -->
<mappers>
<mapper url="file:///var/sqlmaps/AuthorMapper.xml"/>
<mapper url="file:///var/sqlmaps/BlogMapper.xml"/>
<mapper url="file:///var/sqlmaps/PostMapper.xml"/> </mappers>
这些配置告诉MyBatis在哪里找到SQL映射文件。而其它的更详细的信息配置在每一个SQL映射文件里。
SQL 映射 XML 文件
MyBatis真正强大之处就在这些映射语句,也就是它的魔力所在。对于它的强大功能,SQL映射文件的配置却非常简单。如果您比较SQL映射文件配置与JDBC代码,您很快可以发现,使用 SQL映射文件配置可以节省95%的代码量。MyBatis被创建来专注于SQL,但又给您自己的实现极大的空间。
SQL映射XML文件只有一些基本的元素需要配置,并且要按照下面的顺序来定义(in the order that they should be defined):
• cache –在特定的命名空间配置缓存。
• cache-ref – 引用另外一个命名空间配置的缓存.
• resultMap – 最复杂也是最强大的元素,用来描述如何从数据库结果集里加载对象。
例:
接口
public interface ClassesMapper {
//根据班级id查询对应的学生信息 以及班级信息
public Classes getClasses(int cid);
}
mapper映射
<select id="getClasses" resultMap="getc" parameterType="int">
select * from classes c,student s where s.c_id=c.c_id and c.c_id=#{c_id}
</select>
<resultMap type="Classes" id="getc">
<id column="c_id" property="cid"/>
<result column="c_name" property="cname"/>
<collection property="students" ofType="Student">
<id column="s_id" property="sid"/>
<result column="s_name" property="sname"/>
</collection>
</resultMap>
接口
public interface StudentMapper {
//根据学生id去查询对应的班级形象
public Student getStu(int sid);
}
mapper映射
<select id="getStu" resultMap="getS" parameterType="int">
select * from student s,classes c where s.c_id=c.c_id and s.s_id=#{s_id}
</select>
<resultMap type="Student" id="getS">
<id column="s_id" property="sid"/>
<result column="s_name" property="sname"/>
<association property="classes" javaType="Classes">
<id column="c_id" property="cid"/>
<result column="c_name" property="cname"/>
</association>
</resultMap>
• parameterMap – 不推荐使用! 在旧的版本里使用的映射配置,这个元素在将来可能会被删除,因此不再进行描述。
• sql – 能够被其它语句重用的SQL块。
• insert –INSERT映射语句
• update –UPDATE映射语句
• delete –DELEETE映射语句
=“s_id” property=“sid”/>
• parameterMap – 不推荐使用! 在旧的版本里使用的映射配置,这个元素在将来可能会被删除,因此不再进行描述。
• sql – 能够被其它语句重用的SQL块。
• insert –INSERT映射语句
• update –UPDATE映射语句
• delete –DELEETE映射语句
• select –SELECT 映射语句