MyBatis官方文档摘要
MyBatis官方文档摘要
- 食用声明:仅记录我认为可以用得上的信息,其中包括自我总结(小部分)和官方文档原文(大部分),如须更多内容详见官方文档
入门
其实映射的语句可以不用XML配置,而可以使用Java注解来配置,例如
1
2
3
4
5package org.mybatis.example;
public interface BlogMapper {
Blog selectBlog(int id);
}使用注解来映射诶简单的语句会事代码简洁,但是对于复杂的语句会更加混乱。因此复杂的语句最好还是用XML配置
XML配置
- MyBatis的配置文件会深深的影响MyBatis的设置和属性信息,其常用配置如下(摘取部分)
设置(settings)
- useGeneratedKeys:允许 JDBC 支持自动生成主键,需要驱动支持。 如果设置为 true 则这个设置强制使用自动生成主键,尽管一些驱动不能支持但仍可正常工作(比如 Derby)
- cacheEnable:全局地开启或关闭配置文件中的所有映射器已经配置的任何缓存
- multipleResultSetsEnabled:是否允许单一语句返回多结果集(需要驱动支持)
- mapUnderscoreToCamelCase:是否开启自动驼峰命名规则(camel case)映射,即从经典数据库列名 A_COLUMN 到经典 Java 属性名 aColumn 的类似映射
环境配置(environments)
MyBatis可以配置成多种环境,这在现实环境中有多种使用理由,例如,开发 ,测试和生产环境需要不同的配置
不过要记住:尽管可以配置多个环境,但每个 SqlSessionFactory 实例只能选择一种环境。
每个数据库对应一个 SqlSessionFactory 实例
```Java
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environment);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environment, properties);1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
## XML映射文件
- MyBatis真正的强大在于它的映射诶语句,它相比有相同功能的JDBC代码相比节约了近95%的代码,MyBatis为聚焦SQL构建,尽可能的减少你的麻烦
- SQL映射文件中的定义元素(按照应被定义的顺序列出)
1. `cache` – 对给定命名空间的缓存配置。
2. `cache-ref` – 对其他命名空间缓存配置的引用。
3. `resultMap` – 是最复杂也是最强大的元素,用来描述如何从数据库结果集中来加载对象。
4. `parameterMap` – 已被废弃!老式风格的参数映射。更好的办法是使用内联参数,此元素可能在将来被移除。文档中不会介绍此元素。
5. `sql` – 可被其他语句引用的可重用语句块。
6. `insert` – 映射插入语句
7. `update` – 映射更新语句
8. `delete` – 映射删除语句
9. `select` – 映射查询语句
### select
```XML
<select id="selectPerson" parameterType="int" resultType="hashmap">
SELECT * FROM PERSON WHERE ID = #{id}
</select>
- 其中
#{id}
告诉MyBatis创建一个预处理语句(PreparedStatement)参数,在 JDBC 中,这样的一个参数在 SQL 中会由一个“?”来标识,并被传递到一个新的预处理语句中,类似PreparedStatement ps = conn.prepareStatement(selectPerson);
- 默认情况下,使用
#{}
格式的语法会导致 MyBatis 创建PreparedStatement
参数占位符并安全地设置参数(就像使用 ? 一样)。 这样做更安全,更迅速,通常也是首选做法,不过有时你就是想直接在 SQL 语句中插入一个不转义的字符串。 比如,像 ORDER BY,你可以这样来使用:ORDER BY ${columnName}
- 用这种方式接受用户的输入,并将其用于语句中的参数是不安全的,会导致潜在的 SQL 注入攻击,因此要么不允许用户输入这些字段,要么自行转义并检验。
属性 | 描述 |
---|---|
id |
在命名空间中唯一的标识符,可以被用来引用这条语句。 |
parameterType |
将会传入这条语句的参数类的完全限定名或别名。这个属性是可选的,因为 MyBatis 可以通过类型处理器(TypeHandler) 推断出具体传入语句的参数,默认值为未设置(unset)。 |
parameterMap | 这是引用外部 parameterMap 的已经被废弃的方法。请使用内联参数映射和 parameterType 属性。 |
resultType |
从这条语句中返回的期望类型的类的完全限定名或别名。 注意如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身。可以使用 resultType 或 resultMap,但不能同时使用。 |
resultMap |
外部 resultMap 的命名引用。结果集的映射是 MyBatis 最强大的特性,如果你对其理解透彻,许多复杂映射的情形都能迎刃而解。可以使用 resultMap 或 resultType,但不能同时使用。 |
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 |
这个设置仅对多结果集的情况适用。它将列出语句执行后返回的结果集并给每个结果集一个名称,名称是逗号分隔的。 |
insert,update和delete:和SQL中的同名语句实现非常接近,不再赘述
sql
- 这个元素可以被用来定义可重用的 SQL 代码段,这些 SQL 代码可以被包含在其他语句中。它可以(在加载的时候)被静态地设置参数。 在不同的包含语句中可以设置不同的值到参数占位符上
1 | <sql id="userColumns"> ${alias}.id,${alias}.username,${alias}.password </sql> |
1 | <select id="selectUsers" resultType="map"> |
结果映射
resultMap
元素是 MyBatis 中最重要最强大的元素。它可以让你从 90% 的 JDBCResultSets
数据提取代码中解放出来,并在一些情形下允许你进行一些 JDBC 不支持的操作。实际上,在为一些比如连接的复杂语句编写映射代码的时候,一份resultMap
能够代替实现同等功能的长达数千行的代码。ResultMap 的设计思想是,对于简单的语句根本不需要配置显式的结果映射,而对于复杂一点的语句只需要描述它们的关系就行了。
1 | <select id="selectUsers" resultType="map"> |
- 假设具有一个User类,类中有三个属性:id,username和hashedPassword,这样的一个JavaBean可以被映射到
ResultSet
1 | <select id="selectUsers" resultType="com.someapp.model.User"> |
ResultMap
最优秀的地方在于,虽然你已经对它相当了解了,但是根本就不需要显式地用到他们。 上面这些简单的示例根本不需要下面这些繁琐的配置。 但出于示范的原因,让我们来看看最后一个示例中,如果使用外部的resultMap
会怎样,这也是解决列名不匹配的另外一种方式。
1 | <resultMap id="userResultMap" type="User"> |
- 而在引用它的语句中使用
resultMap
属性就行了(注意我们去掉了resultType
属性)。比如:
1 | <select id="selectUsers" resultMap="userResultMap"> |
- 如果世界总是这么简单就好了。
缓存
- MyBatis 内置了一个强大的事务性查询缓存机制,它可以非常方便地配置和定制。 为了使它更加强大而且易于配置,我们对 MyBatis 3 中的缓存实现进行了许多改进。
- 默认情况下,只启用了本地的会话缓存,它仅仅对一个会话中的数据进行缓存。 要启用全局的二级缓存,只需要在你的 SQL 映射文件中添加一行:
<cache/>
- 基本上就是这样。这个简单语句的效果如下:
- 映射语句文件中的所有 select 语句的结果将会被缓存。
- 映射语句文件中的所有 insert、update 和 delete 语句会刷新缓存。
- 缓存会使用最近最少使用算法(LRU, Least Recently Used)算法来清除不需要的缓存。
- 缓存不会定时进行刷新(也就是说,没有刷新间隔)。
- 缓存会保存列表或对象(无论查询方法返回哪种)的 1024 个引用。
- 缓存会被视为读/写缓存,这意味着获取到的对象并不是共享的,可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改。
动态SQL
- MyBatis 的强大特性之一便是它的动态 SQL。如果你有使用 JDBC 或其它类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句的痛苦。例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL 这一特性可以彻底摆脱这种痛苦。
if
1 | <select id="findActiveBlogWithTitleLike" |
- 这条语句提供了一种可选的查找文本功能。如果没有传入“title”,那么所有处于“ACTIVE”状态的BLOG都会返回;反之若传入了“title”,那么就会对“title”一列进行模糊查找并返回 BLOG 结果(细心的读者可能会发现,“title”参数值是可以包含一些掩码或通配符的)。
choose,when,otherwise
- 有时我们不想应用所有条件语句,这时可以使用choose元素,它有点像Java中的switch
1 | <select id="findActiveBlogLike" |
foreach
- 动态 SQL 的另外一个常用的操作需求是对一个集合进行遍历,通常是在构建 IN 条件语句的时候。比如:
1 | <select id="selectPostIn" resultType="domain.blog.Post"> |
foreach 元素的功能非常强大,它允许你指定一个集合,声明可以在元素体内使用的集合项(item)和索引(index)变量。它也允许你指定开头与结尾的字符串以及在迭代结果之间放置分隔符。这个元素是很智能的,因此它不会偶然地附加多余的分隔符。
注意 你可以将任何可迭代对象(如 List、Set 等)、Map 对象或者数组对象传递给 foreach 作为集合参数。当使用可迭代对象或者数组时,index 是当前迭代的次数,item 的值是本次迭代获取的元素。当使用 Map 对象(或者 Map.Entry 对象的集合)时,index 是键,item 是值。
Java API:MyBatis目录结构,SqlSessions
- 使用 MyBatis 的主要 Java 接口就是 SqlSession。你可以通过这个接口来执行命令,获取映射器和管理事务。我们会概括讨论一下 SqlSession 本身,但是首先我们还是要了解如何获取一个 SqlSession 实例。SqlSession 是由 SqlSessionFactory 实例创建的。SqlSessionFactory 对象包含创建 SqlSession 实例的所有方法。而 SqlSessionFactory 本身是由 SqlSessionFactoryBuilder 创建的,它可以从 XML、注解或手动配置 Java 代码来创建 SqlSessionFactory。
- 注意 当 Mybatis 与一些依赖注入框架(如 Spring 或者 Guice)同时使用时,SqlSession 将被依赖注入框架所创建,所以你不需要使用 SqlSessionFactoryBuilder 或者 SqlSessionFactory,可以直接看 SqlSession 这一节。请参考 Mybatis-Spring 或者 Mybatis-Guice 手册了解更多信息。
SQL语句构建器类
- Java程序员面对的最痛苦的事情之一就是在Java代码中嵌入SQL语句。这么来做通常是由于SQL语句需要动态来生成-否则可以将它们放到外部文件或者存储过程中。正如你已经看到的那样,MyBatis在它的XML映射特性中有一个强大的动态SQL生成方案。但有时在Java代码内部创建SQL语句也是必要的。此时,MyBatis有另外一个特性可以帮到你,在减少典型的加号,引号,新行,格式化问题和嵌入条件来处理多余的逗号或 AND 连接词之前。事实上,在Java代码中来动态生成SQL代码就是一场噩梦。
- MyBatis 3提供了方便的工具类来帮助解决该问题。使用SQL类,简单地创建一个实例来调用方法生成SQL语句。
1 | private String selectPersonSql() { |
end
MyBatis官方文档摘要