MyBatis从0开始学习目录
MyBatis-1-简介
MyBatis-2-HelloWorld
MyBatis-3-全局配置
MyBatis-4-映射文件
MyBatis-5-源码分析
MyBatis-6-#{}和$区别
MyBatis-X-面试题
MyBatis-全局配置文件
1.MyBatis的配置文件包含了影响MyBatis行为甚深的设置(setting)和属性(properties)信息。文档的顶层结构如下:
— configuration 配置
— properties 属性
— settings 设置
— typeAliases 类型命名
— typeHandlers 类型处理器
— ObjectFactory 对象工厂
— plugins 插件
— environment 环境
— environment 环境变量
— transactionManager 事务管理器
— dataSource 数据源
— databaseIdProvider 数据库厂商标识
— mappers 映射器
Mybatis的 properties配置
<!--
1.mybatis可以使用properties来引用外部properties配置文件的内容
resource ,引入类路径下的资源
url,引入网络路径或磁盘路径下的资源
-->
<properties resource="application.properties"></properties>
mybatis的setting配置
这式MyBatis中极为重要的调整配置,他们会改变MyBatis的运行时行为
设置参数 | 描述 | 有效值 | 默认值 |
---|---|---|---|
cacheEnabled | 该配置影响的所有映射器中配置的缓存的全局开关 | true/false | true |
lazyLoadingEnabled | 延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。 特定关联关系中可通过设置fetchType属性来覆盖该项的开关状态 | true/false | false |
aggressiveLazyLoading | 当启用时,对任意延迟属性的调用会使带有延迟加载属性的对象完整加载;反之,每种属性将会按需加载。 | true/false | 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 |
defaultExecutorType | 配置默认的执行器。SIMPLE 就是普通的执行器;REUSE 执行器会重用预处理语句(prepared statements); BATCH 执行器将重用语句并执行批量更新。 | SIMPLE REUSE BATCH | SIMPLE |
defaultStatementTimeout | 设置超时时间,它决定驱动等待数据库响应的秒数。 | Any positive integer | Not Set (null) |
defaultFetchSize | Sets the driver a hint as to control fetching size for return results. This parameter value can be override by a query setting. | Any positive integer | Not Set (null) |
safeRowBoundsEnabled | 允许在嵌套语句中使用分页(RowBounds)。 | true/false | False |
mapUnderscoreToCamelCase | 是否开启自动驼峰命名规则(camel case)映射,即从经典数据库列名 A_COLUMN 到经典 Java 属性名 aColumn 的类似映射。 | true/false | False |
localCacheScope | MyBatis 利用本地缓存机制(Local Cache)防止循环引用(circular references)和加速重复嵌套查询。 默认值为 SESSION,这种情况下会缓存一个会话中执行的所有查询。 若设置值为 STATEMENT,本地会话仅用在语句执行上,对相同 SqlSession 的不同调用将不会共享数据。 | SESSION / STATEMENT | SESSION |
jdbcTypeForNull | 当没有为参数提供特定的 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 | 指定当结果集中值为 null 的时候是否调用映射对象的 setter(map 对象时为 put)方法,这对于有 Map.keySet() 依赖或 null 值初始化的时候是有用的。注意基本类型(int、boolean等)是不能设置成 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 JAVASSIST (MyBatis 3.3 or above) |
<!--
2.settings包含很多重要的设置项
setting:用来设置每一个设置项
name:设置项名
value:设置取值
-->
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
TypeAliases
别名处理器,就是给java bean别名
<!--
3.typeAliases:别名处理器,可以为我们java类型起别名
别名不区分大小写
-->
<typeAliases>
<!--1.typeAlias: 为某个Java类型起别名
type:指定要起别名的类型全类名;默认别名就是类名小写
alias:指定新别名
-->
<!--<typeAlias type="com.wxl.springbootmybatis.bean.Employee" alias="employee"></typeAlias>-->
<!--2.package:为某个包下所有类批量起别名
name :指定包(为当前包以及下面所有的后代包的每一个类都起一个默认别名(类名小写))
-->
<package name="com.wxl.springbootmybatis.bean"/>
<!--3.批量起别名的情况下,使用@Alias注解为某个类型指定新的别名-->
</typeAliases>
//包下注解指定别名
/*@Alias("emp")*/
public class Employee {
TypeHandlers
1:标签介绍
在 MyBatis 的 sql 映射配置文件中,为 sql 配置的输入参数最终要从 java 类型转换成数据库能识别的类型,而从 sql 的查询结果集中获取的数据,也要从数据库的数据类型转换为对应的 Java 类型。
在 MyBatis 中,使用类型处理器(TypeHandler)将数据库获取的值以合适的方式转换为 Java 类型,或者将 Java 类型的参数转换为数据库对应的类型。
在 MyBatis 中有许多自带的类型处理器,但有时候也会满足不了开发的需求,这时候就需要配置自己的类型处理器了,而 typeHandlers 标签就是用来声明自己的类型处理器的。
2:编写说明
使用 typeHandlers 标签配置一个自己的类型处理器,一般需要三个步骤:编写类型处理器类,在 MyBatis 全局配置文件中配置该类型处理器,在 sql 映射配置文件中使用。
例如要编写一个将 JDBC 的 timestamp 类型与 Date 类型相互转换的类型处理器配置示例。首先编写类型处理器,一般要实现 org.apache.ibatis.type.TypeHandler 接口,接口的泛型指定要转换的 Java 参数类型,若不指定则默认为 Object 类,实现 TypeHandler 接口主要改写四个方法,如下:
public void setParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType)
public String getResult(ResultSet rs,String columnName)
public String getResult(ResultSet rs,int columnIndex)
public String getResult(CallableStatement cs,int columnIndex)
setParameter 方法是在 sql 配置传入参数时(新增、删除、修改、查询)执行的操作,可以在将参数传入数据库之前在该方法中对数据类型做处理。
另外三个 getResult 方法则在数据库返回结果时,将结果信息转换为相应的 Java 类型。区别在于前两个 getResult 方法供普通 select 方法使用,一个根据字段名,一个根据字段下标来获取数据,最后一个 getResult 方法供存储过程使用,根据字段下标获取数据。
Plugins
1:标签介绍
在某种情况下,需要在执行程序的过程中对某一点进行拦截,并在拦截后做出一系列处理,此时就需要使用一种拦截器。在 MyBatis 中,对某种方法进行拦截调用的机制,被称为 plugin 插件。使用 plugin 可以很好地对方法地调用进行监控,而且还可以修改或重写方法的行为逻辑。在 MyBatis 中允许使用 plugin 来拦截的方法如下:
Executor(update,query,flushStatements,commit,rollback,getTransaction,close,isClosed)
ParameterHandler(getParameterObject,setParameters)
ResultSetHandler(handleResultSets,handleOutputParameters)
StatementHandler(prepare,parameterize,batch,update,query)
其中,Executor 是 MyBatis 对外提供的一个操作接口类,其中包含了 query 查询、update 修改、commit 提交、rollback 回滚等核心方法。ParameterHandler、ResultSetHandler 及 StatementHandler 分别是处理参数、结果集、预编译状态的接口,里面的一些方法也可以使用 plugin 进行拦截。
2:代码示例
实现一个 plugin 只需要继承 Interceptor 接口,并且指定需要拦截的方法的签名信息即可。例如以下的示例:
package cn.com.mybatis.test;
import java.util.Properties;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
@Intercepts({
@Signature(
type=Executor.class,
method="query",
args={MappedStatement.class,Object.class,RowBounds.class,ResultHandler.class}
)
})
public class QueryPlugin implements Interceptor {
public Object intercept(Invocation invocation) throws Throwable {
return invocation.proceed();
}
public Object plugin(Object target) {
return Plugin.wrap(target,this);
}
public void setProperties(Properties arg0) {}
}
类头部添加了 @Intercepts 拦截器注解,此注解声明此类是一个插件类。其中可以声明多个 @Signature 签名信息注解,type 为拦截的方法所属的接口类型,method 为拦截的方法名称,args 是参数信息。
intercept 方法是一个对目标方法进行拦截的抽象方法,而 plugin 方法的作用是将拦截器插入目标对象。
setProperties 方法的作用是将全局配置文件中的参数注入插件类中。
然后,在 MyBatis 全局配置文件中配置该插件即可,这样插件就会起到拦截作用,示例代码如下:
<plugins>
<plugin interceptor="cn.com.mybatis.test.QueryPlugin">
<property name="someProperty" value="100"/>
</plugin>
</plugins>
此时,就可以拦截 Executor 的 query 方法了,也就是默认执行的查询方法,可以在重写的插件类的 intercept 方法中添加拦截逻辑。
3:总结
插件使用的场景有:日志记录、权限控制、缓存控制等。使用 plugin 拦截和覆盖 MyBatis 的核心方法时,建议谨慎使用,否则会影响 MyBatis 的核心功能。
Environments
<!--environments,环境们,mybatis可以配置多种环境,default指定使用某种环境。可以达到快速切换环境。
environment,配置一个具体的环境信息,必须有两个标签,id代表当前环境的唯一标识
transactionManager,事务管理器
type,事务管理器类型,JDBC(JdbcTransactionFactory)|MANAGED (ManagedTransactionFactory)
自定义事务管理器,实现TransactionFactory结构,type指定全类名
dataSource,数据源;
type:数据类型,JNDI(JndiDataSourceFactory)
|POOLED(PooledDataSourceFactory)
|UNPOOLED(UnpooledDataSourceFactory)
自定义数据源;实现DateSourceFactory接口,type是全类名
-->
<environments default="deveLopment">
<environment id="deveLopment">
<!--指定事务管理的类型,这里简单使用Java的JDBC的提交和回滚设置-->
<transactionManager type="JDBC"></transactionManager>
<!--dataSource 指连接源配置,POOLED是JDBC连接对象的数据源连接池的实现-->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</dataSource>
</environment>
</environments>
DatabaseIdProvider
<!--5.databaseIdProvider,支持多数据数据库厂商
type="DB_VENDOR";VendorDatabaseIdProvider
作用就是得到数据库厂商的标识(驱动getDatabaseProductName()),
mybatis就能根据数据库厂商标识来执行不同的sql
MySQL,Orace,SQL Server,xxxx
-->
<databaseIdProvider type="DB_VENDOR">
<!--为不同数据库厂商起别名-->
<property name="Mysql" value="mysql"/>
<property name="Oracle" value="oracle"/>
<property name="SQL Server" value="sqlserver"/>
</databaseIdProvider>
<select id="getEmpById" resultType="employee" databaseId="mysql">
select * from tb1_employee where id = #{id}
</select>
Mappers
<!--这是告诉Mybatis区哪找持久化类的映射文件,对于在src下的文件直接写文件名,
如果在某包下,则要写明路径,如:com/mybatistest/config/User.xml-->
<!--6.mappers,将sql映射注册到全局配置钟-->
<mappers>
<!--
mapper:注册一个sql映射
注册配置文件
resource,引用类路径下sql映射文件
url,应用网络路径下或磁盘路径下的sql映射文件
file:///var/mappers/AutorMapper.xml
注册接口
class,引用(注册)接口
1.sql映射文件,映射文件名必须和接口同名,并且放在与接口同一目录下;
2.没有sql映射文件,所有的sql都是利用注解写在接口上
推荐,比较重要的,复杂的DAO接口我们来写sql映射文件
不重要,简单的DAO接口为了开发快速可以使用注解模式
-->
<mapper resource="bayis.mapper/EmployeeMapper.xml"></mapper>
<mapper class="com.wxl.springbootmybatis.dao.EmployeeMapperAnnotation"/>
<!--批量注册-->
<!--<package name=""/>-->
</mappers>
注解模式
public interface EmployeeMapperAnnotation {
@Select("select * from tb1_employee where id=#{id}")
public Employee getEmpById(Integer id);
}
调用注解
@Test
public void Test02() throws IOException {
SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
SqlSession openSession = sqlSessionFactory.openSession();
try {
EmployeeMapperAnnotation mapper = openSession.getMapper(EmployeeMapperAnnotation.class);
Employee empById = mapper.getEmpById(1);
System.out.println(empById);
} finally {
openSession.close();
}
}