一 Mapper代理
之前的形式开发不方便,也不利于维护。mybatis提供了Mapper动态代理
我们只需要写dao接口(Mapper)
,而不需要
写dao实现类,由mybatis根据dao接口和映射文件中statement的定义生成接口实现类代理对象
。
规范
- 在XXXmapper.xml中
namespace
等于mapper接口地址
(即mapper.xml文件中的namespace与mapper.java接口的类路径
相同) - XXXmapper.java接口中的
方法
和mapper.xml中的statement的Id
一致。 - mapper.java接口中的方法
输入参数
和mapper.xml中statement的parameterType
指定的类型
一致。 - mapper.java接口中的方法的
返回值类型
和mapper.xml中statement的resultType
指定的类型一致。
接口
public interface UserMapper {
/** 根据ID查询用户信息 */
public User findUserById(int id);
/** 根据用户名称模糊查询用户信息 */
public List<User> findUserByName(String username);
/** 添加用户 */
public void insertUser(User user);
/** 根据ID删除用户 */
public void deleteUser(Integer id);
/** 根据ID更新用户 */
public void updateUser(User user);
}
sql语句文件
只需要修改文件名
和namesapce
即可。(测试得:文件名和接口名不是必须一致,但为了程序清晰,最好一致)
SqlMapConfig.xml
添加配置文件
<mappers>
<mapper resource="com/zyc/mapping/User.xml"/>
<mapper resource="com/zyc/mapping/UserMapper.xml"/>
</mappers>
测试
@Test
public void testFindUserById() {
// 创建Usermapper对象,mybatis自动生成mapper代理对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.findUserById(2);
System.out.println(user);
sqlSession.close();
}
小结
- 代理对象内部调用
selectOne
()和selectList
():
如果mapper对象返回单个pojo对象(非集合对象)代理对象内部通过selectOne查询数据库,如果mapper方法返回集合对象,代理对象内部通过selectList查询数据库。 - 由于mapper接口中方法的参数要根据映射文件中的
parameterType
来指定,而parameterType只有一个
,所以mapper接口中所有方法的参数
都只有一个.可以使用包装类型
的pojo满足不同的业务方法的需求。
二 MyBatis-全局配置文件
MyBatis 的配置文件包含了影响 MyBatis 行为甚深的设置
(settings)和属性
(properties)信息。文档的
顶层结构如下:

properties
作用:将数据连接单独配置在db.properties中,只需要在SqlMapConfig.xml中加载db.properties的属性值,在SqlMapConfig.xml中就不需要对数据库连接参数进行硬编码
<!-- 加载数据库文件db.properties -->
<properties resource="db.properties">
<!-- properties中还可以配置一些属性名和属性值,此处的优先加载 -->
<!-- <property name="driver" value=""/> -->
</properties>
....
<property name="driver" value="${jdbc.driver}" />
properties特性
注意:
(1)在properties元素体内定义的属性优先
读取。
(2)然后读取properties元素中resource或url加载的属性
,它会覆盖
已读取的同名属性。
(3)最后读取parameterType
传递的属性,它会覆盖
已读取的同名属性。
建议:
(1)不要在properties元素体内添加任何属性值,只将属性值定义在properties文件中。
(2)在properties文件中定义属性名要有一定的特殊性,如xxxx.xxxx(jdbc.driver)。
settings设置
这是 MyBatis 中极为重要的调整设置,它们会改变MyBatis 的运行时行为
部分设置如下图:

setting(设置) | Description(描述) | valid Values(验证值组) | Default(默认值) |
---|---|---|---|
cacheEnabled | 在全局范围内启用或禁用缓存 配置 任何映射器在此配置下。 |
true | false | TRUE |
lazyLoadingEnabled | 在全局范围内启用或禁用延迟加载 。禁用时,所有相关联的将热加载。 |
true | false | TRUE |
aggressiveLazyLoading | 启用时,有延迟加载属性的对象将被完全加载后调用懒惰的任何属性。否则,每一个属性是按需加载。 | true | false | TRUE |
multipleResultSetsEnabled | 允许或不允许从一个单独的语句(需要兼容的驱动程序)要返回多个结果集。 | true | false | TRUE |
useColumnLabel | 使用列标签,而不是列名。在这方面,不同的驱动有不同的行为。参考驱动文档或测试两种方法来决定你的驱动程序的行为如何。 | true | false | TRUE |
useGeneratedKeys | 允许JDBC支持生成的密钥。兼容的驱动程序是必需的。此设置强制生成的键被使用,如果设置为true,一些驱动会不兼容性,但仍然可以工作。 | true | false | FALSE |
autoMappingBehavior | 指定MyBatis的应如何自动映射列到字段/属性。NONE自动映射。 PARTIAL只会自动映射结果没有嵌套结果映射定义里面。 FULL会自动映射的结果映射任何复杂的(包含嵌套或其他)。 | NONE,PARTIAL,FULL | PARTIAL |
defaultExecutorType | 配置默认执行人。SIMPLE执行人确实没有什么特别的。 REUSE执行器重用准备好的语句。 BATCH执行器重用语句和批处理更新。 | SIMPLE,REUSE,BATCH | SIMPLE |
safeRowBoundsEnabled | 允许使用嵌套的语句RowBounds。 | true | false | FALSE |
mapUnderscoreToCamelCase | 从经典的数据库列名A_COLUMN启用自动映射到骆驼标识的经典的Java属性名aColumn。 | true | false | FALSE |
localCacheScope | MyBatis的使用本地缓存,以防止循环引用,并加快反复嵌套查询。默认情况下(SESSION)会话期间执行的所有查询缓存。如果localCacheScope=STATMENT本地会话将被用于语句的执行,只是没有将数据共享之间的两个不同的调用相同的SqlSession。 | SESSION | SESSION |
STATEMENT | |||
dbcTypeForNull | 指定为空值时,没有特定的JDBC类型的参数的JDBC类型。有些驱动需要指定列的JDBC类型,但其他像NULL,VARCHAR或OTHER的工作与通用值。 | JdbcType enumeration. Most common are: NULL, VARCHAR and OTHER | OTHER |
lazyLoadTriggerMethods | 指定触发延迟加载的对象的方法。 | A method name list separated by commas | equals,clone,hashCode,toString |
defaultScriptingLanguage | 指定所使用的语言默认为动态SQL生成。 | A type alias or fully qualified class name. | org.apache.ibatis.scripting.xmltags |
.XMLDynamicLanguageDriver | |||
callSettersOnNulls | 指定如果setter方法或地图的put方法时,将调用检索到的值是null。它是有用的,当你依靠Map.keySet()或null初始化。注意原语(如整型,布尔等)不会被设置为null。 | true | false | FALSE |
logPrefix | 指定的前缀字串,MyBatis将会增加记录器的名称。 | Any String | Not set |
logImpl | 指定MyBatis的日志实现 使用。如果此设置是不存在的记录的实施将自动查找。 |
SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING | Not set |
proxyFactory | 指定代理工具 ,MyBatis将会使用创建懒加载能力的对象。 |
CGLIB | JAVASSIST | CGLIB |
官方文档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="autoMappingBehavior" value="PARTIAL"/>
<setting name="defaultExecutorType" value="SIMPLE"/>
<setting name="defaultStatementTimeout" value="25"/>
<setting name="safeRowBoundsEnabled" value="false"/>
<setting name="mapUnderscoreToCamelCase" value="false"/>
<setting name="localCacheScope" value="SESSION"/>
<setting name="jdbcTypeForNull" value="OTHER"/>
<setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
</settings>
typeAliases别名处理器
- 类型别名是为 Java 类型设置一个短的名字,可以方便我们引用某个类。
<typeAliases>
<package type="com.mybatis.entity.User" alias="user" />
</typeAliases>
- 类很多的情况下,可以批量设置别名这个包下的每一个类.创建一个默认的别名,就是
简单类名小写
。
<typeAliases>
<package name="com.mybatis.entity"/>
</typeAliases>
- 也可以使用@Alias注解为其指定一个别名
@Alias("user")
public class User {
...
默认支持的别名
别名 | 映射的类型 |
---|---|
_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 |
typeHandlers类型处理器
无论是 MyBatis 在预处理语句(PreparedStatemen
)中设置一个参数
时,还是从结果集
中取出一个值时, 都会
用类型处理器
将获取的值
以合适的方式转换成 Java 类型
。
类型处理器 | Java 类型 | JDBC 类型 |
---|---|---|
BooleanTypeHandler | java.lang.Boolean, boolean | 数据库兼容的 BOOLEAN |
ByteTypeHandler | java.lang.Byte, byte | 数据库兼容的 NUMERIC 或 BYTE |
ShortTypeHandler | java.lang.Short, short | 数据库兼容的 NUMERIC 或 SHORT INTEGER |
IntegerTypeHandler | java.lang.Integer, int | 数据库兼容的 NUMERIC 或 INTEGER |
LongTypeHandler | java.lang.Long, long | 数据库兼容的 NUMERIC 或 LONG INTEGER |
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 |
日期类型的处理
- 日期时间处理上,我们可以使用MyBatis基于JSR310(
Date and Time
API)编写的各种日期
时间类型处理器。 -
MyBatis3.4
以前的版本需要我们手动注册这些处理器,以后的版本都是自动注册的
自定义类型处理器
我们可以重写类型处理器或创建自己的类型处理器来处理不支持的或非标准的类型。
步骤
- 1)、实现org.apache.ibatis.type.TypeHandler接口或者继承org.apache.ibatis.type.BaseTypeHandler
- 2)、指定其映射某个JDBC类型(可选操作)
- 3)、在mybatis全局配置文件中注册
plugins插件
插件是MyBatis提供的一个非常强大的机制,我们可以通过插件来修改MyBatis的一些核心行为
。 插
件通过动态代理
机制,可以介入四大对象
的任何一个方法的执行。后面会有专门的章节我们来介
绍mybatis运行原理以及插件
• Executor
(update, query, flushStatements, commit, rollback,getTransaction, close, isClosed)
• ParameterHandler
(getParameterObject, setParameters)
• ResultSetHandler
(handleResultSets, handleOutputParameters)
• StatementHandler
(prepare, parameterize, batch, update, query)
environments环境
MyBatis可以配置多种环境,比如开发、测试和生产环境需要有不同的配置。
• 每种环境使用一个environment
标签进行配置并指定唯一标识
符
• 可以通过environments
标签中的default
属性指定一个环境的标识符来快速的切换环境
• id:指定当前环境的唯一标识
• transactionManager、和dataSource都必须有
<environments default="dev_mysql">
<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>
<environment id="dev_oracle">
<transactionManager type="JDBC" />
<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
场景:databaseIdProvider元素主要是为了支持不同厂商的数据库,比如有时候我们在公司内部开发使用的数据库都是PG(Postgresql),但是客户要求使用MySql,那就麻烦了是吧?其实在mybatis中我们可以使用databaseIdProvider这个元素实现数据库兼容不同厂商,即配置多中数据库。
参考: MyBatis配置文件(八)--databaseIdProvider数据库厂商标识
mapper映射
- mapper逐个注册SQL映射文件
<mappers>
<mapper resource="org/mybatis/mappers/UserMapper.xml"/>
<mapper url="file:///var/mappers/UserMapper.xml"/>
<mapper class="org.mybatis.mappers.UserMapper"/>
</mappers>
- 或者使用批量注册
这种方式要求SQL映射文件名必须和接口名相同
并且在同一目录下
<mappers>
<package name="org.mybatis.mappers"/>
<package name="org.mybatis"/>
</mappers>
网友评论