MyBatis入门及全局配置
初识Mybatis
ORM概览
在了解ORM之前我们先了解什么是持久化,因为所有的ORM框架所做的事情无非就是将对象映射成数据库中的数据,以及将数据库中的对象映射成数据。
什么是持久化
所谓持久化就是把数据(内存中的对象)保存到可永久存储的存储设备中(例如:硬盘),持久化的主要应用是将内存中的数据存储在关系型数据库中。当然也可以保存在磁盘文件中,XML数据文件,JSON文件中等的。
什么是ORM
ORM(Object-Relational Mapping),对象关系映射,它的作用是在关系型数据库和对象之间做一个映射,这样,我们在具体的操作数据库时,就不需要和复杂的SQL语句打交道,像平时操作对象操作数据即可。
在目前的企业应用系统设计中,MVC,即 Model(模型)- View(视图)- Control(控制)为主要的系统架构模式。MVC 中的 Model 包含了复杂的业务逻辑和数据逻辑,以及数据存取机制(如 JDBC的连接、SQL生成和Statement创建、还有ResultSet结果集的读取等)等。将这些复杂的业务逻辑和数据逻辑分离,以将系统的紧耦合关系转化为松耦合关系(即解耦合),是降低系统耦合度迫切要做的,也是持久化要做的工作。MVC 模式实现了架构上将表现层(即View)和数据处理层(即Model)分离的解耦合,而持久化的设计则实现了数据处理层内部的业务逻辑和数据逻辑分离的解耦合。 而 ORM 作为持久化设计中的最重要也最复杂的技术,也是目前业界热点技术。
简单来说,按通常的系统设计,使用 JDBC 操作数据库,业务处理逻辑和数据存取逻辑是混杂在一起的。
一般基本都是如下几个步骤:
- 建立数据库连接,获得 Connection 对象。
- 根据用户的输入组装查询 SQL 语句。
- 根据 SQL 语句建立 Statement 对象 或者 PreparedStatement 对象。
- 用 Connection 对象执行 SQL语句,获得结果集 ResultSet 对象。
- 然后一条一条读取结果集 ResultSet 对象中的数据。
- 根据读取到的数据,按特定的业务逻辑进行计算。
- 根据计算得到的结果再组装更新 SQL 语句。
- 再使用 Connection 对象执行更新 SQL 语句,以更新数据库中的数据。
- 最后依次关闭各个 Statement 对象和 Connection 对象。
由上可看出代码逻辑非常复杂,这还不包括某条语句执行失败的处理逻辑。其中的业务处理逻辑和数据存取逻辑完全混杂在一块。而一个完整的系统要包含成 千上万个这样重复的而又混杂的处理过程,假如要对其中某些业务逻辑或者一些相关联的业务流程做修改,要改动的代码量将不可想象。另一方面,假如要换数据库产品或者运行环境也可能是个不可能完成的任务。而用户的运行环境和要求却千差万别,我们不可能为每一个用户每一种运行环境设计一套一样的系统。
所以就要将一样的处理代码即业务逻辑和可能不一样的处理即数据存取逻辑分离开来,另一方面,关系型数据库中的数据基本都是以一行行的数据进行存取的,而程序 运行却是一个个对象进行处理,而目前大部分数据库驱动技术(如ADO.NET、JDBC、ODBC等等)均是以行集的结果集一条条进行处理的。所以为解决 这一困难,就出现 ORM 这一个对象和数据之间映射技术。常用的ORM框架有Hibernate、Mybatis、Mybatis-plus等,接下来我们以Mybatis为例深入学习。
Mybatis概览
MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
下面我们先了解一下Mybatis架构:
- mybatis-config.xml: Mybatis全局配置文件,用于配置数据库、数据库连接池、POJO别名、映射文件等信息
- mapper.xml:该文件中用于编写处理数据的SQL语句。并且通过此文件可以将SQL语句与Java代码完全分离
- SqlSessionFactory:用于创建Java和数据库会话的Session对象
- Session:与数据库建立会话对象
- Executor:真正执行Sql语句的对象
- Statement:mapper文件对应的Statement,因为mapper文件是相互隔离的,可以理解为一个mapper文件就对应一个Statement对象。
Mybatis入门
在本小节内,将使用Mybatis框架搭建开发环境,并使用Mybatis进行单表的增删改查,其中涉及到的一些概念会在后续章节中陆续讲解。
新建Mybaits项目
在前面的课程中,已经学习了Maven的基础知识,使用Maven可以更好的管理和构建项目,因此使用Maven构建项目。项目结构如下:
首先准数据库:
1 | CREATE DATABASE MYBATIS_DEMO; |
第一步:在pom.xml中导入依赖
1 | <dependency> |
第二步:在resource目录下新建mybatis-config.xml全局配置文件
1 | <?xml version="1.0" encoding="UTF-8" ?> |
第三步:创建SQL语句映射文件StudentMapper.xml
1 | <!DOCTYPE mapper |
第四步:在java目录下,新建包cn.bytecollege.entity,并在包中新建实体类Student
1 | package cn.bytecollege.entity; |
第五步:在java目录下新建cn.bytecollege.mapper包,并在包中新建接口StudentMapper
1 | package cn.bytecollege.mapper; |
第六步:新建测试类查询所有信息
1 | package cn.bytecollege; |
运行上面的程序结果如下图:
从上面的代码可以看出使用Mybatis的整个过程可以分为以下 步:
- 读取Mybatis全局配置文件
- 构建SqlSessionFactory对象
- 创建SqlSession对象
- 获取自定义Mapper
- 执行SQL语句
- 获取执行结果
Mybatis对象简介
在上面步骤中出现了SqlSessionFactory、SqlSession等对象,下面就这些对象进行简单的介绍。
- SqlSessionFactory:每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为核心的。SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。而 SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先配置的 Configuration 实例来构建出 SqlSessionFactory 实例。需要注意SqlSessionFactory是一个工厂接口而不是现实类,它的任务是创建SqlSession。
- SqlSession:SqlSession类似于一个JDBC的Connection对象。MyBatis提供了两种模式去创建SqlSessionFactory:一种是XML配置的方式,另一种是代码的方式。为了避免硬编码以及利于项目维护,通常推荐使用第一种方式,将配置和代码进行分离。
- Mapper(映射器):映射器是由Java接口和XML文件(或注解)共同组成的,它的作用有:定义参数类型、描述缓存、描述SQL语句、
Mybatis全局配置
在第一章中粗浅地讨论了MyBatis的组成和它们大致的用法,这章的任务是详细讨论MyBatis的配置。
先来看一下MyBatis配置XML文件的层次结构。注意,这些层次是不能够颠倒顺序的,如果颠倒顺序,MyBatis在解析XML文件的时候就会出现异常。先来了解一下MyBatis配置XML文件的层次结构。
1 |
|
需要注意的是在上面的配置文件中所有属性的层次顺序是不能颠倒的,也就是说在configuration标签中第一个必须是properties标签,其他的标签依次向下不能调换顺序。这是因为当使用Mybatis时,Mybatis会先读取该配置文件并按照顺序依次解析将配置值封装进Configuration对象,如果顺序不对,则会导致Mybatis解析配置文件异常。
下面将接每个属性进行解释。
Properties属性
Properties属性用于配置连接数据库的信息,在JDBC的学习中可以知道在开发过程中为了方便程序维护及扩展,通常将数据库连接信息单独写在配置文件中,Properties属性为开发者提供了2种方式,用于配置数据库连接信息。
Properties子元素
通过Properties子元素可以配置数据库连接信息,由于项目打包时会将配置文件拷贝到classes目录下,当需要更换数据库或者项目维护时就需要重写修改该文件,并重写打包,因此并不推荐使用这种方式。
1 | <properties> |
在上面的代码中已经配置好了数据库连接信息,这些信息一般会在datasource标签中使用,使用方式如下:
1 | <dataSource type="POOLED"> |
Properties配置文件
更多的时候会使用Properties配置文件来配置属性,以方便程序的扩展和维护,配置文件中内容如下:
1 | url = jdbc:mysql://localhost:3306/mybatis_demo?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai |
配置文件编写完毕后,将该文件放置在resource目录下(Maven项目中resource目录专门用于存放配置文件)。并在properties标签中进行配置:
1 | <properties resource="data.properties"></properties> |
当Mybatis运行时会自动寻找该文件,并解析文件中配置的数据。使用时同上一小节的使用方式一致。
在上述的两种配置方式中使用resource/url属性中指定的配置文件的优先级要高于properties元素中指定的属性。
从Mybatis 3.4.2开始,可以为占位符指定一个默认值。
1 | <dataSource type="POOLED"> |
这个特性默认是关闭的。要启用这个特性,需要添加一个特定的属性来开启这个特性。例如:
1 | <properties resource="org/mybatis/example/config.properties"> |
Settings设置属性
Settings是Mybatis中最重要的配置内容之一,它会改变Mybatis运行时的行为,即使不配置settings,Mybatis也可以正常的工作,但是了解Settings的配置内容以及作用是十分必要的。
设置名 | 描述 | 有效值 | 默认值 |
---|---|---|---|
cacheEnabled | 全局性地开启或关闭所有映射器配置文件中已配置的任何缓存。 | true | false | true |
lazyLoadingEnabled | 延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。 特定关联关系中可通过设置 fetchType 属性来覆盖该项的开关状态。 | true | false | false |
aggressiveLazyLoading | 开启时,任一方法的调用都会加载该对象的所有延迟加载属性。 否则,每个延迟加载属性会按需加载(参考 lazyLoadTriggerMethods)。 | true | false | false (在 3.4.1 及之前的版本中默认为 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: 输出警告日志(’org.apache.ibatis.session.AutoMappingUnknownColumnBehavior’ 的日志等级必须设置为 WARN)FAILING: 映射失败 (抛出 SqlSessionException) | NONE, WARNING, FAILING | NONE |
defaultExecutorType | 配置默认的执行器。SIMPLE 就是普通的执行器;REUSE 执行器会重用预处理语句(PreparedStatement); BATCH 执行器不仅重用语句还会执行批量更新。 | SIMPLE REUSE BATCH | SIMPLE |
defaultStatementTimeout | 设置超时时间,它决定数据库驱动等待数据库响应的秒数。 | 任意正整数 | 未设置 (null) |
defaultFetchSize | 为驱动的结果集获取数量(fetchSize)设置一个建议值。此参数只可以在查询设置中被覆盖。 | 任意正整数 | 未设置 (null) |
defaultResultSetType | 指定语句默认的滚动策略。(新增于 3.5.2) | FORWARD_ONLY | SCROLL_SENSITIVE | SCROLL_INSENSITIVE | DEFAULT(等同于未设置) | 未设置 (null) |
safeRowBoundsEnabled | 是否允许在嵌套语句中使用分页(RowBounds)。如果允许使用则设置为 false。 | true | false | False |
safeResultHandlerEnabled | 是否允许在嵌套语句中使用结果处理器(ResultHandler)。如果允许使用则设置为 false。 | true | false | True |
mapUnderscoreToCamelCase | 是否开启驼峰命名自动映射,即从经典数据库列名 A_COLUMN 映射到经典 Java 属性名 aColumn。 | true | false | False |
localCacheScope | MyBatis 利用本地缓存机制(Local Cache)防止循环引用和加速重复的嵌套查询。 默认值为 SESSION,会缓存一个会话中执行的所有查询。 若设置值为 STATEMENT,本地缓存将仅用于执行语句,对相同 SqlSession 的不同查询将不会进行缓存。 | SESSION | STATEMENT | SESSION |
jdbcTypeForNull | 当没有为参数指定特定的 JDBC 类型时,空值的默认 JDBC 类型。 某些数据库驱动需要指定列的 JDBC 类型,多数情况直接用一般类型即可,比如 NULL、VARCHAR 或 OTHER。 | JdbcType 常量,常用值:NULL、VARCHAR 或 OTHER。 | OTHER |
lazyLoadTriggerMethods | 指定对象的哪些方法触发一次延迟加载。 | 用逗号分隔的方法列表。 | equals,clone,hashCode,toString |
defaultScriptingLanguage | 指定动态 SQL 生成使用的默认脚本语言。 | 一个类型别名或全限定类名。 | org.apache.ibatis.scripting.xmltags.XMLLanguageDriver |
defaultEnumTypeHandler | 指定 Enum 使用的默认 TypeHandler 。(新增于 3.4.5) | 一个类型别名或全限定类名。 | org.apache.ibatis.type.EnumTypeHandler |
callSettersOnNulls | 指定当结果集中值为 null 的时候是否调用映射对象的 setter(map 对象时为 put)方法,这在依赖于 Map.keySet() 或 null 值进行初始化时比较有用。注意基本类型(int、boolean 等)是不能设置成 null 的。 | true | false | false |
returnInstanceForEmptyRow | 当返回行的所有列都是空时,MyBatis默认返回 null。 当开启这个设置时,MyBatis会返回一个空实例。 请注意,它也适用于嵌套的结果集(如集合或关联)。(新增于 3.4.2) | true | false | false |
logPrefix | 指定 MyBatis 增加到日志名称的前缀。 | 任何字符串 | 未设置 |
logImpl | 指定 MyBatis 所用日志的具体实现,未指定时将自动查找。 | SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING | 未设置 |
proxyFactory | 指定 Mybatis 创建可延迟加载对象所用到的代理工具。 | CGLIB | JAVASSIST | JAVASSIST (MyBatis 3.3 以上) |
vfsImpl | 指定 VFS 的实现 | 自定义 VFS 的实现的类全限定名,以逗号分隔。 | 未设置 |
useActualParamName | 允许使用方法签名中的名称作为语句参数名称。 为了使用该特性,你的项目必须采用 Java 8 编译,并且加上 -parameters 选项。(新增于 3.4.1) | true | false | true |
configurationFactory | 指定一个提供 Configuration 实例的类。 这个被返回的 Configuration 实例用来加载被反序列化对象的延迟加载属性值。 这个类必须包含一个签名为static Configuration getConfiguration() 的方法。(新增于 3.2.3) | 一个类型别名或完全限定类名。 | 未设置 |
shrinkWhitespacesInSql | 从SQL中删除多余的空格字符。请注意,这也会影响SQL中的文字字符串。 (新增于 3.5.5) | true | false | false |
defaultSqlProviderType | Specifies an sql provider class that holds provider method (Since 3.5.6). This class apply to the type(or value) attribute on sql provider annotation(e.g. @SelectProvider), when these attribute was omitted. | A type alias or fully qualified class name | Not set |
一个完整的settings元素的示例如下:
1 | <settings> |
关于Settings的常用配置,会在后续的章节中讲解,此处做了解即可。
typeAliases别名属性
别名是一个指代的名称,因为在开发中在很多地方需要配置类的全限定名,例如在使用Mybatis做查询时需要告诉Mybatis将查询结果映射成哪个实体类对象。但是通常类的全限定名比较长,需要有一个简短的名称来替代这全限定名。别名在Mybatis中分为系统定义别名和自定义别名两类。需要注意的是Mybatis中别名是不区分大小写的。一个typeAliases的实例是在解析配置文件时生成的,然后长期保存在Configuration对象中。
系统定义别名
Mybatis系统定义了一些常用的类型的别名,例如:数值、字符串、日期和集合等,可以在Mybatis中直接使用。
首先来看一下Mybatis已经定义好的别名(数组类型的只要加“[]”即可),如下表所示:
别名 | 映射的类型 |
---|---|
_byte | byte |
_long | long |
_short | short |
_int | int |
_integer | int |
_double | double |
_float | float |
_boolean | boolean |
string | String |
byte | Byte |
long | Long |
short | Short |
int | Integer |
integer | Integer |
double | Double |
float | Float |
boolean | Boolean |
date | Date |
decimal | BigDecimal |
bigdecimal | BigDecimal |
object | Object |
map | Map |
hashmap | HashMap |
list | List |
arraylist | ArrayList |
collection | Collection |
iterator | Iterator |
这些配置信息都在Mybatis源码org.apache.ibatis.type.TypeAliasRegistry中。
1 | public class TypeAliasRegistry { |
自定义别名
系统定义的别名通常是不够用的,因为不同的应用有不同的需要,Mybatis也允许自定义别名,配置方式如下,例如第一章中的查询,就可以使用别名来替代全限定名。配置方式如下:
1 | <typeAliases> |
为了方便开发,通常会为所有的实体类定义别名,如果实体类较少的情况下使用上述方式配置别名不会有任何问题,但是当实体类较多时上述的配置方式就显得很烦琐,因此Mybatis又提供了一种配置方式,可以直接指定一个包名,Mybatis会为配置包下所有类自动定义别名,别名为类名首字母小写。配置方式如下:
1 | <typeAliases> |
如果通过上述方式配置了别名,会为cn.bytecollege.entity
包下的所有的类定义别名,例如cn.bytecollege.entity.Student
类的别名就是student。
除此以外,Mybatis还提供了注解的方式配置别名,配置方式如下:
1 | @Alias("student") |
虽然Mybatis提供了以上3种方式配置类的别名,但是切记不要混用,否则很容易导致映射文件解析异常。
typeHandlers属性
在前面的章节中知道Mybatis可以将查询出的数据自动映射进配置文件中绑定的实体类对象,在映射的过程中就存在一个问题,如何将数据库的数据类型和Java类型对应起来,并将数据库的数据类型转换成Java的数据类型,而typeHandlers的作用就是将从数据库取出的数据以合适的方式转换成Java类型。Mybatis自带了一些默认的类型处理器,如下表所示:
类型处理器 | Java 类型 | JDBC 类型 |
---|---|---|
BooleanTypeHandler | java.lang.Boolean, boolean | 数据库兼容的 BOOLEAN |
ByteTypeHandler | java.lang.Byte, byte | 数据库兼容的 NUMERIC 或 BYTE |
ShortTypeHandler | java.lang.Short, short | 数据库兼容的 NUMERIC 或 SMALLINT |
IntegerTypeHandler | java.lang.Integer, int | 数据库兼容的 NUMERIC 或 INTEGER |
LongTypeHandler | java.lang.Long, long | 数据库兼容的 NUMERIC 或 BIGINT |
FloatTypeHandler | java.lang.Float, float | 数据库兼容的 NUMERIC 或 FLOAT |
DoubleTypeHandler | java.lang.Double, double | 数据库兼容的 NUMERIC 或 DOUBLE |
BigDecimalTypeHandler | java.math.BigDecimal | 数据库兼容的 NUMERIC 或 DECIMAL |
StringTypeHandler | java.lang.String | CHAR, VARCHAR |
ClobReaderTypeHandler | java.io.Reader | - |
ClobTypeHandler | java.lang.String | CLOB, LONGVARCHAR |
NStringTypeHandler | java.lang.String | NVARCHAR, NCHAR |
NClobTypeHandler | java.lang.String | NCLOB |
BlobInputStreamTypeHandler | java.io.InputStream | - |
ByteArrayTypeHandler | byte[] | 数据库兼容的字节流类型 |
BlobTypeHandler | byte[] | BLOB, LONGVARBINARY |
DateTypeHandler | java.util.Date | TIMESTAMP |
DateOnlyTypeHandler | java.util.Date | DATE |
TimeOnlyTypeHandler | java.util.Date | TIME |
SqlTimestampTypeHandler | java.sql.Timestamp | TIMESTAMP |
SqlDateTypeHandler | java.sql.Date | DATE |
SqlTimeTypeHandler | java.sql.Time | TIME |
ObjectTypeHandler | Any | OTHER 或未指定类型 |
EnumTypeHandler | Enumeration Type | VARCHAR 或任何兼容的字符串类型,用来存储枚举的名称(而不是索引序数值) |
EnumOrdinalTypeHandler | Enumeration Type | 任何兼容的 NUMERIC 或 DOUBLE 类型,用来存储枚举的序数值(而不是名称)。 |
SqlxmlTypeHandler | java.lang.String | SQLXML |
InstantTypeHandler | java.time.Instant | TIMESTAMP |
LocalDateTimeTypeHandler | java.time.LocalDateTime | TIMESTAMP |
LocalDateTypeHandler | java.time.LocalDate | DATE |
LocalTimeTypeHandler | java.time.LocalTime | TIME |
OffsetDateTimeTypeHandler | java.time.OffsetDateTime | TIMESTAMP |
OffsetTimeTypeHandler | java.time.OffsetTime | TIME |
ZonedDateTimeTypeHandler | java.time.ZonedDateTime | TIMESTAMP |
YearTypeHandler | java.time.Year | INTEGER |
MonthTypeHandler | java.time.Month | INTEGER |
YearMonthTypeHandler | java.time.YearMonth | VARCHAR 或 LONGVARCHAR |
JapaneseDateTypeHandler | java.time.chrono.JapaneseDate | DATE |
自定义typeHandlers
通常而言,Mybatis系统提供使用的TypeHandler已经能给应对绝大部分使用场景,但是并不能保证不会出现不够用的情况,如果出现这种情况,开发者就可以自定义typeHandler进行转换,自定义typeHandler通常需要继承TypeHandler
1 | package cn.bytecollege.typeHandler; |
在上例中自定义了String类型的转换器,为了简单起见,方法内只是进行了简单标记,并调用了父类的同名方法。代码注释处方法含义如下:
- 根据占位符的索引,为占位符赋值
- 根据数据库字段名称从结果集中获取值
- 根据字段索引从结果集中获取数据
- 根据字段索引从存储过程结果中获取值
在定义完typeHandler后该typeHandler并不能正常工作,还需要进行配置,配置有两步:
- 在自定义typeHandler类上添加注解@MappedJdbcTypes,注解内的值是该typeHandler可以转换的数据库数据类型
- 在全局配置文件中进行配置,告诉Mybatis自定义的typeHandler可以将数据库的数据类型转换成Java的何种类型。
1 | <typeHandlers> |
ObjectFactory对象工厂属性
在第一章的示例中可以看出,当要做查询操作时,只需要在
1 | package cn.bytecollege.factory; |
当创建完对象工厂后,还需要在Mybatis配置文件中进行配置:
1 | <!-- mybatis-config.xml --> |
当查询数据时,Mybatis会将结果集映射到实体类对象,此时就需要创建实体类对象,Mybatis会通过ObjectFactory来创建对象。
在上述示例中只是简单查看了Mybatis创建实体类对象的过程,通常开发者并不需要重新定义对象工厂。
plugins插件属性
MyBatis 允许你在映射语句执行过程中的某一点进行拦截调用。默认情况下,MyBatis 允许使用插件来拦截的方法调用包括:
●Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
●ParameterHandler (getParameterObject, setParameters)
●ResultSetHandler (handleResultSets, handleOutputParameters)
●StatementHandler (prepare, parameterize, batch, update, query)
通过 MyBatis 提供的强大机制,使用插件是非常简单的,只需实现 Interceptor 接口,并指定想要拦截的方法签名即可。
environment环境属性
配置环境可以注册多个数据源,例如,日常开发中通常会有开发库、测试库、生产库、并且需要在这几个库中切换,此时配置多个数据源就非常有必要。每个数据源大概分为:数据库连接信息的配置和数据库事务的配置。
一份完整的配置示例如下:
1 | <environments default="development"> |
注意一些关键点:
- 默认使用的环境 ID(比如:default=”development”)。
- 每个 environment 元素定义的环境 ID(比如:id=”development”)。
- 事务管理器的配置(比如:type=”JDBC”)。
- 数据源的配置(比如:type=”POOLED”)。
默认环境和环境 ID 顾名思义。 环境可以随意命名,但务必保证默认的环境 ID 要匹配其中一个环境 ID。
事务配置
在 MyBatis 中有3种类型的事务管理器(也就是 type=”[JDBC|MANAGED]”):
- JDBC – 这个配置直接使用了 JDBC 的提交和回滚设施,它依赖从数据源获得的连接来管理事务作用域。
- MANAGED – 这个配置几乎没做什么。它从不提交或回滚一个连接,而是让容器来管理事务的整个生命周期(比如 JEE 应用服务器的上下文)。
- 自定义:开发者自定义数据库事务的管理办法
1 | import cn.bytecollege.entity.Student; |
从上例代码中可以看出当执行完数据库操作后,调用session对象的commit()方法提交事务,如果发生异常时则调用rollback()方法进行事务回滚。
数据源
dataSource 元素使用标准的 JDBC 数据源接口来配置 JDBC 连接对象的资源。Mybatis提供了3种数据源类型,下面就这种类型进行简单介绍:
- UNPOOLED– 这个数据源的实现会每次请求时打开和关闭连接。虽然有点慢,但对那些数据库连接可用性要求不高的简单应用程序来说,是一个很好的选择。 性能表现则依赖于使用的数据库,对某些数据库来说,使用连接池并不重要,这个配置就很适合这种情形。
- POOLED– 这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来,避免了创建新的连接实例时所必需的初始化和认证时间。这种方式是开发中常用的方式。
- JNDI – 这个数据源实现是为了能在如 EJB 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI 上下文的数据源引用。
开发者只需要把数据源的属性type定义为:UNPOOLEN、POOLED、JNDI即可。
如果需要使用自定义数据源,需要实现org.apache.ibatis.datasource.DatatSourceFactory接口,例如要是用Druid数据源,就需要自定义数据源。
1 | package cn.bytecollege.datasource; |
数据源定义完毕后还需要在全局配置文件中进行配置,配置完成后就可以使用自定义数据源了,配置如下:
1 | <!--1--> |
在上述配置中注释1处,只需要将type修改为自定义数据源的全限定名即可。
databaseIdProvider数据库厂商标识属性
在相同数据库厂商的环境下,数据库厂商标识没有任何意义,在实际开发中使用的较少。如果使用了不同厂商的数据库,Mybatis可以根据不同的数据库厂商执行不同的语句。这种支持是基于配置文件中的databaseId属性。Mybatis会加载带有匹配当前数据库databaseId属性的语句。
mappers映射器属性
映射器是Mybatis最核心的组件之一,在本小节内主要讨论如何在全局配置文件中引入映射器,映射器中的参数类型、动态SQL、缓存等内容将会在第3章及第4章中详细讲解。
Mybatis提供了4种映射器的引入方式
resource引入
resource导入是使用mapper标签的resource属性引入映射器。这种方式也是使用最多的方式。配置如下:
1 | <mappers> |
如果是使用Maven构建的项目,为了方便管理映射器,通常在resource目录下新建mapper目录,然后将映射器放入该目录中,resource只需配置相对路径即可完成映射。
class引入
class引入则是使用mapper标签的class属性引入映射器,这种方式通常需要将映射器放在Mapper接口相同的目录中(Eclipse项目),如果是Maven项目,则需要在resource目录中新建和包名相同的路径,然后将映射器放入。配置如下:
1 | <mappers> |
url引入
url引用方式在开发中使用的较少,因为这种方式是使用映射器的绝对路径进行引入,引入方式如下:
1 | <mappers> |
需要注意的是这种引入方式需要在文件的路径前添加“file:///”,否则会引发异常。
package引入
package引入方式也是开发中比较常用的一种引入方式,此种方式是使用package标签配置映射器所在的路径。这种方式只需要配置包名,Mybatis即可扫描到该路径下的映射器。需要注意的是这种方式也需要在resource目录下建立和Mapper接口相同的路径名,并将映射器放入才能使用。配置方式如下:
1 | <mappers> |