一、环境搭建
环境搭建已经在 “搭建 Mybatis 工作环境“ 中介绍了,这里不再过多介绍。
二、Mybatis 全局配置文件
1、properties 标签
用于引入外部properties文件
<!--
properties: 引入外部properties文件 必须放在最前面,否则会报错
resource: 类路径下
url: 磁盘路径或网络路径
-->
<properties resource="jdbc.properties"></properties>
jdbc.properties 用于配置数据库连接信息
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/***?serverTimezone=GMT&useSSL=false&useUnicode=true&characterEncoding=utf8
username=***
password=***
2、settings 标签
setting 配置也是 Mybatis 全局配置文件中比较重要的配置,它影响 Mybatis 框架在运行时的一些行为。setting 配置缓存、延迟加载、结果集控制、执行器、分页设置、命名规则等一系列控制性参数,与 Mybatis 的运行性能息息相关。所有的 setting 配置都别包裹在 settings 标签对中。
<!--
settings 包含很多重要的设置项
setting:用来设置每一个设置项
name:设置项ming
value:设置项值
-->
<settings>
<!-- 设置日志输出, 方便观察sql语句和参数 -->
<setting name="logImpl" value="LOG4J"/>
<!--开启自动驼峰命名-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
看下未开启驼峰命名的效果:
[main] [com.example.mapper.EmployeeMapper.findAllEmp]-[DEBUG] ==> Preparing: select * from tbl_employee
[main] [com.example.mapper.EmployeeMapper.findAllEmp]-[DEBUG] ==> Parameters:
[main] [com.example.mapper.EmployeeMapper.findAllEmp]-[DEBUG] <== Total: 4
Employee{id=1, lastName='null', email='tom@123.com', gender='0'}
Employee{id=2, lastName='null', email='jerry@123.com', gender='0'}
Employee{id=3, lastName='null', email='jack@123.com', gender='0'}
Employee{id=4, lastName='null', email='rose@123.com', gender='1'}
开启后效果:
[main] [com.example.mapper.EmployeeMapper.findAllEmp]-[DEBUG] ==> Preparing: select * from tbl_employee
[main] [com.example.mapper.EmployeeMapper.findAllEmp]-[DEBUG] ==> Parameters:
[main] [com.example.mapper.EmployeeMapper.findAllEmp]-[DEBUG] <== Total: 4
Employee{id=1, lastName='tom', email='tom@123.com', gender='0'}
Employee{id=2, lastName='jerry', email='jerry@123.com', gender='0'}
Employee{id=3, lastName='jack', email='jack@123.com', gender='0'}
Employee{id=4, lastName='rose', email='rose@123.com', gender='1'}
未开启驼峰命名时, tbl_employee 表中的 last_name 字段无法对应实体类 Employee 中的 lastName 属性。
3、typeAliases 别名处理器
typeAliases 可以为 Java 类型起别名。
3.1 typeAlias属性
可以单独为某一个类起别名
<!--typeAliases 别名处理器:可以为 Java 类型起别名-->
<typeAliases>
<!--
typeAlias:为某个 Java 类型起别名
type:指定要起别名的类型全类名,默认别名就是类名,不区分大小写 employee
alias:指定新的别名
-->
<typeAlias type="com.example.pojo.Employee" alias="emp"></typeAlias>
</typeAliases>
EmployeeMapper.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">
<mapper namespace="com.example.mapper.EmployeeMapper">
<!--执行结果类型使用别名-->
<select id="findAllEmp" resultType="emp">
select * from tbl_employee
</select>
</mapper>
运行 MybatisTest.java 中的 test01() 方法进行测试:
[main] [com.example.mapper.EmployeeMapper.findAllEmp]-[DEBUG] ==> Preparing: select * from tbl_employee
[main] [com.example.mapper.EmployeeMapper.findAllEmp]-[DEBUG] ==> Parameters:
[main] [com.example.mapper.EmployeeMapper.findAllEmp]-[DEBUG] <== Total: 4
Employee{id=1, lastName='tom', email='tom@123.com', gender='0'}
Employee{id=2, lastName='jerry', email='jerry@123.com', gender='0'}
Employee{id=3, lastName='jack', email='jack@123.com', gender='0'}
Employee{id=4, lastName='rose', email='rose@123.com', gender='1'}
使用默认别名和指定别名效果一样。
3.2 package 属性
可以批量起别名
<!--typeAliases 别名处理器:可以为 Java 类型起别名-->
<typeAliases>
<!--
package:为某个包下的所有类批量起别名
name:指定包名(为当前包以及下面所有的后代包的每一个类都起一个默认别名(即为类名,不区分小写)
-->
<package name="com.example.pojo"/>
</typeAliases>
测试结果同上
3.3 注解 @Alias
在批量起别名的情况下,可以使用 @Alias 注解为某个 Java 类指定新的类名
3.4 Java 常见类型别名
Mybatis 已经为 Java 的常见类型默认指定了别名,可以直接使用。这里要注意的是,有一些基本数据类型和包装数据类型的名称一样(除了包装类型中首字母大写的类),故在基本类型的前面加了下划线”_“作为区分。
别名 | 映射的类型 |
---|---|
_byte | byte |
_long | long |
_short | short |
_int | int |
_integer | int |
_double | double |
_float | float |
_boolean | boolean |
string | java.lang.String |
byte | java.lang.Byte |
long | java.lang.Long |
short | java.lang.Short |
int | java.lang.Integer |
integer | java.lang.Integer |
double | java.lang.Double |
boolean | java.lang.Boolean |
date | java.util.Date |
decimal | java.math.BigDecimal |
bigdecimal | java.math.BigDecimal |
object | java.lang.Object |
map | java.util.Map |
hashmap | java.util.HashMap |
list | java.util.List |
arraylist | java.util.ArrayList |
collection | java.util.Collection |
iterator | java.util.Iterator |
4、environments 标签
在 Mybatis 全局配置文件中,environments 是放置有关数据库连接数据的配置标签,所有与外部数据库进行交互的数据都配置在该标签中。在 environments 标签中可以配置多个数据库连接环境,以便 SQL 语句可以适用于多个数据库环境。
在 environments 中可以配置一个个单独的 environment,它们代表多个数据库环境的配置信息。每一个 environment 都包含事务管理器(transactionManager)和数据源(DataSource)信息。
<!--
environments 标签主要用于配置 Mybatis 的环境信息。
可以有多个 environment 标签,每一个单独的 environment 标签对代表一个单独的数据库配置环境。
在 environment 标签对中,transactionManager 标签配置的是 Mybaits 的事务控制类型,
而 dataSource 标签中配置的数据库连接信息,其中包含多个 property 标签,用于配置数据库驱动信息driver、
数据库连接地址 url、数据库用户名 username、数据库密码 password
environments:mybatis 可以配置多种环境,default 属性用于指定使用哪种环境。可以快速切换环境。
environment:配置一个具体的环境信息,id 代表当前环境的唯一标识。environment 中必须包含两个标签:
transactionManager:事务管理器
属性 type:事务管理器的类型;JDBC(JdbcTransactionFactory)| MANAGED(ManagedTransactionFactory)
自定义事务管理器:实现 TransactionFactory 接口,type 指定为实现类的全类名
dataSource:数据源
属性 type:数据源类型 :UNPOOLED(UnpooledDataSourceFactory)
|POOLED(PooledDataSourceFactory)
|JNDI(JndiDataSourceFactory)
自定义数据源类型:实现 DataSourceFactory 接口,type 指定为实现类的全类名
-->
<environments default="dev_mysql">
<environment id="dev_mysql">
<transactionManager type="JDBC"></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>
事务管理器(transactionManager)有两种类型:分别是 JDBC 和 MANAGED。配置为 JDBC 相当于直接使用 JDBC 的提交和回滚设置。配置为 MANAGED,则不提交和回滚连接,而是由容器来管理事务的生命周期。在默认情况下,MANAGED 会关闭连接,但是可以动态指定 closeConnection 参数,但设置为“false”时,在 MANAGED 类型下不会自动关闭连接:
<transactionManager type="MANAGED">
<property name="closeConnection" value="false"/>
</transactionManager>
Spring MVC 与 Mybatis 进行整合时,由于 Spring 框架的机制,其自带的管理器会覆盖 Mybatis 的配置,此时要单独设置事务管理器。
关于数据源(DataSource),在 Mybatis 中有三种内建的数据源类型:分别是“UNPOOLED”、“POOLED”、“JNDI”。其中,UNPOOLED 设置每次请求时打开和关闭连接,而 POOLED 可以设置一个管理数据库连接的资源池,用来合理控制数据库的连接和关闭次数,利用“池”的概念将 JDBC 连接对象组织起来。而 JNDI 则配置连接外部数据源(如服务器提供的数据源)的信息。
在 DataSource 中配置以 JDBC 标准连接数据库所需要的各项参数信息,根据 DataSource 的不同,可以设置如下所示的信息:
属性名称 | 作用 | 数据源类型 |
---|---|---|
driver | JDBC 驱动名称 | UNPOOLED¦POOLED |
url | 数据库的连接地址 | UNPOOLED¦POOLED |
username | 连接数据库的用户名 | UNPOOLED¦POOLED |
password | 连接数据库的密码 | UNPOOLED¦POOLED |
defaultTransactionIsolationLevel | 默认连接事物的隔离级别 | UNPOOLED¦POOLED |
poolMaximumActiveConnections | 数据库最大活动连接数 | UNPOOLED¦POOLED |
poolMaximumIdleConnections | 数据库最大空闲连接数 | UNPOOLED¦POOLED |
poolMaximumCheckoutTime | 连接的最大失效时间(默认为 2000 ms) | UNPOOLED¦POOLED |
poolTimetoWait | 对数据库进行连通检测(ping)时,如果数据库的连接等待时间过长,它会给连接池打印状态日志并重新尝试获取一个连接(默认为 2000 ms) | UNPOOLED¦POOLED |
poolPingQuery | 用来检测数据库是否可以连接查询,默认是“NO PING QUERY SET” | UNPOOLED¦POOLED |
poolPingEnabled | 是否开启数据库连通检测 | UNPOOLED¦POOLED |
poolPingConnectionNotUsedFor | 配置 poolPingQuery 的使用频率,默认是 0 | UNPOOLED¦POOLED |
initial_context | 用来设置在 initialContext 中寻找上下文。此属性为可选,若不设置,data_source 配置将会直接在 initialContext 中寻找 | JNDI |
data_source | 引用外部数据源信息的具体路径 | JNDI |
env.xxx | 通过前缀“env.”将后面的属性直接传给上下文(例如env.encoding=UTF-8) | JNDI |
当然,也可以自己设置数据源,通过实现 DataSourceFactory 接口来实现(也可以引入其他第三方数据源)
5、databaseIdProvider 多数据库支持
Mybatis 支持配置多个数据库连接环境,但在多个数据库中执行 SQL 语句时,某些规则是不一样的,如果要兼容各个数据库厂商的 SQL 语言规则,则需要配置“databaseIdProvider”参数。
jabc.properties
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/test?serverTimezone=GMT&useSSL=false&useUnicode=true&characterEncoding=utf8
jdbc.username=***
jdbc.password=***
orcl.driver=oracle.jdbc.OracleDriver
orcl.url=jdbc:oracle:thin:@localhost:1521/orclpdb1
orcl.username=test
orcl.password=123456
mybatis全局配置文件
<environments default="dev_oracle">
<environment id="dev_mysql">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
<!--Oracle数据源配置-->
<environment id="dev_oracle">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${orcl.driver}"/>
<property name="url" value="${orcl.url}"/>
<property name="username" value="${orcl.username}"/>
<property name="password" value="${orcl.password}"/>
</dataSource>
</environment>
</environments>
<!--
databaseIdProvider:支持多数据库厂商
属性 type:默认值为 DB_VENDOR,为 VendorDatabaseIdProvider 类的别名
作用就是得到数据库厂商的标识(驱动,通过方法 getDatabaseProductName()方法获取),
mybatis 就能根据数据库厂商标识来执行不同的 SQL
数据库厂商标识:MySQL、Oracle、SQL Server
-->
<databaseIdProvider type="DB_VENDOR">
<!--为不同的数据库厂商起别名-->
<property name="MySQL" value="mysql"/>
<property name="Oracle" value="oracle"/>
<property name="SQL Server" value="sqlserver"/>
</databaseIdProvider>
EmployeeMapper.xml
select 标签中的 databaseId 可用于指定当前查询使用哪种类型的数据库,从而实现多数据库查询
<?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">
<mapper namespace="com.example.mapper.EmployeeMapper">
<!--执行结果类型使用默认别名-->
<select id="findAllEmp" resultType="employee" databaseId="oracle">
select * from tbl_employee
</select>
<select id="findAllEmp" resultType="employee" databaseId="mysql">
select * from tbl_employee
</select>
</mapper>
6、mappers 标签
6.1 配置文件方式以及注解方式
<!--mappers:将 SQL 映射注册到全局配置中-->
<mappers>
<!--
mapper:注册一个SQL映射
注册配置文件:
1)属性 resource:引用类路径下的 SQL 映射文件
2)属性 url:引用网络路径或者磁盘路径下的 SQL 映射文件
例如:file://var/mappers/AuthorMapper.xml
注册接口:
属性 class:引用接口
1、有 SQL 映射文件,映射文件名必须和接口同名,并且放在与接口同一目录下;
2、没有 SQL 映射文件,所有的 SQL 都是利用注解写在接口上
-->
<mapper resource="com/example/mapper/EmployeeMapper.xml"></mapper>
<mapper class="com.example.mapper.EmployeeMapperAnnotation"></mapper>
</mappers>
测试注解方式
新建 EmployeeMapperAnnotation.java
package com.example.mapper;
import com.example.pojo.Employee;
import org.apache.ibatis.annotations.Select;
public interface EmployeeMapperAnnotation {
@Select("select * from tbl_employee where id = #{id}")
public Employee getEmployeeById(Integer id);
}
测试方法:
@Test
public void test02() throws IOException {
SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
SqlSession sqlSession = sqlSessionFactory.openSession();
try{
EmployeeMapperAnnotation mapper = sqlSession.getMapper(EmployeeMapperAnnotation.class);
Employee employee = mapper.getEmployeeById(1);
System.out.println(employee);
} finally {
sqlSession.close();
}
}
返回结果:
[main] [com.example.mapper.EmployeeMapperAnnotation.getEmployeeById]-[DEBUG] ==> Preparing: select * from tbl_employee where id = ?
[main] [com.example.mapper.EmployeeMapperAnnotation.getEmployeeById]-[DEBUG] ==> Parameters: 1(Integer)
[main] [com.example.mapper.EmployeeMapperAnnotation.getEmployeeById]-[DEBUG] <== Total: 1
Employee{id=1, lastName='tom', email='tom@123.com', gender='0'}
6.2 package 属性
<mappers>
<!--批量注册-->
<package name="com/example/mapper"/>
</mappers>
该方式可批量注册 com/example/mapper 路径下的所有配置文件