本文是本人专栏【Java开发后端系列框架】里的文章,文章根据各框架官网与网上资料加上本人工作经验,进行修改总结发布在这个专栏,主要目的是用于自我提升,不用于获取利益。如果系列文章能到帮到您本人将感到荣幸,如果有侵权请联系我删除修,祝各位都能在编程这条路越走越远,早日暴富。
文章目录
- 一、Mybatis配置文件
- **1、properties(属性)**
- 2、settings(设置)
- 3、typeAliases(类型别名)
- 4、typeHandlers(类型处理器)
- 5、objectFactory(对象工厂)
- 6、plugins(插件)
- 7、environments(环境配置)
- 8、transactionManager(事务管理器)
- 9、mappers(映射器)
- 二、Mapper映射文件
- 1、namespace 命名空间
- 2、映射文件里的九大顶级元素
一、Mybatis配置文件
在本专栏Mybatis的第一篇文章中,里面的Mybatis-config.xml即为Mybatis配置文件。
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/jf?useUnicode=true&characterEncoding=utf8" />
<property name="username" value="root" />
<property name="password" value="123456" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="UserMapper.xml" />
</mappers>
</configuration>
在配置文件里, configuration(配置)作为最顶级节点,其余属性都必须嵌套在其内。这些属性能够影响Mybatis的的行为,各属性如下:
configuration(配置)
properties(属性)
settings(设置)
typeAliases(类型别名)
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境配置)
environment(环境变量)
transactionManager(事务管理器)
dataSource(数据源)
databaseIdProvider(数据库厂商标识)
mappers(映射器)
需要注意的是,配置文件里的属性在配置时必须按照上面的顺序,否则框架会抛出异常,下面对其中比较重要的属性进行解析。
1、properties(属性)
提供属性配置,可进行动态替换,一般在 Java 属性文件中配置,例如 jdbc.properties 配置文件 ,或通过 properties 元素标签中的子元素 property 来指定配置。
如:
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/jf?useUnicode=true&characterEncoding=utf8" />
<property name="username" value="root" />
<property name="password" value="123456" />
</dataSource>
如果使用配置文件,则先创建properties配置文件
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jf?useUnicode=true&characterEncoding=utf8
username=root
password=123456
在Mybatis配置文件引入
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 引入属性配置文件 -->
<properties resource="jdbc.properties"></properties>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<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>
<mappers>
<mapper resource="UserMapper.xml" />
</mappers>
</configuration>
需要注意的是,如果既引入了配置文件,又在 property 自行配置了其他的,那么框架还是会使用你引入的 properties 配置文件的信息,而不是在Mybatis配置文件里你自行配置的信息。
2、settings(设置)
<settings>
<!--以下配置的value值均为默认值-->
<!--全局开启或关闭所有映射器配置文件中已配置的任何缓存-->
<setting name="cacheEnabled" value="true"/>
<!--懒加载。开启后所有关联对象都会延迟加载。特定关联关系中可通过设置 fetchType 属性来覆盖该项的开关状态-->
<setting name="lazyLoadingEnabled" value="true"/>
<!--是否允许单个语句返回多结果集-->
<setting name="multipleResultSetsEnabled" value="true"/>
<!--使用列标签代替列名-->
<setting name="useColumnLabel" value="true"/>
<!--允许 JDBC 支持自动生成主键-->
<setting name="useGeneratedKeys" value="false"/>
<!--指定 MyBatis 应如何自动映射列到字段或属性
NONE:关闭自动映射 PARTIAL:自动映射没有定义嵌套结果映射的字段 FULL:会自动映射任何复杂的结果集-->
<setting name="autoMappingBehavior" value="PARTIAL"/>
<!--指定发现自动映射目标未知列(或未知属性类型)的行为
NONE: 不做任何反应 WARNING: 输出警告日志 AILING: 映射失败 (抛出 SqlSessionException)-->
<setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>
<!--配置默认的执行器。SIMPLE:普通执行器 REUSE:执行器会重用预处理语句(PreparedStatement)
BATCH:执行器不仅重用语句还会执行批量更新。-->
<setting name="defaultExecutorType" value="SIMPLE"/>
<!--设置超时时间,决定数据库驱动等待数据库响应的秒数-->
<setting name="defaultStatementTimeout" value=""/>
<!--获取结果集数量的建议值,支持任何正整数-->
<setting name="defaultFetchSize" value=""/>
<!--是否允许在嵌套语句中使用分页(RowBounds),允许则设置为false-->
<setting name="safeRowBoundsEnabled" value="false"/>
<!--是否开启驼峰命名自动映射-->
<setting name="mapUnderscoreToCamelCase" value="false"/>
<!--防止循环引用和加速重复的嵌套查询的一种本地缓存机制。SESSION:会缓存一个会话中执行的所有查询
STATEMENT,本地缓存将仅用于执行语句,对相同 SqlSession 的不同查询将不会进行缓存-->
<setting name="localCacheScope" value="SESSION"/>
<!--当没有为参数指定特定的 JDBC 类型时,空值的默认 JDBC 类型 常用值:NULL、VARCHAR 或 OTHER-->
<setting name="jdbcTypeForNull" value="OTHER"/>
<!--指定对象的哪些方法触发一次延迟加载-->
<setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
</settings>
3、typeAliases(类型别名)
<!--配置别名-->
<typeAliases>
<typeAlias type="top.jf.pojo.User" alias="User"/>
</typeAliases>
配置完别名后可以再所有地方将top.jf.pojo.User
改为User
,如,修改UserMapper.xml配置文件
<!--查询所有用户-->
<select id="findAllUser" resultType="User">
select * from USER
</select>
运行查询测试类,查询结果符合预期
4、typeHandlers(类型处理器)
主要用于处理 Java 类型与 JDBC 类型的映射关系。
MyBatis 在设置预处理SQL语句(PreparedStatement)中所需要的参数或从结果集ResultSet 中获取对象时, 都会用类型处理器将获取到的值以合适的方式转换成 Java 类型。
5、objectFactory(对象工厂)
MyBatis 每次创建结果对象的新实例时,它都会使用一个对象工厂(ObjectFactory)实例来完成。
6、plugins(插件)
MyBatis 允许你在映射语句执行过程中的某一点进行拦截调用。默认情况下,MyBatis 允许使用插件来拦截的方法调用包括:
- Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
- ParameterHandler (getParameterObject, setParameters)
- ResultSetHandler (handleResultSets, handleOutputParameters)
- StatementHandler (prepare, parameterize, batch, update, query)
使用插件,只需实现 Interceptor 接口。
举例:编写插件拦截在 Executor 实例中所有的 “update” 方法。
创建实体类
package top.jf.interceptor;
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.Signature;
import java.util.Properties;
/**
* @author : JF
* @date: 2022/12/29 17:56
*/
@Intercepts({
@Signature(
type= Executor.class,
method = "insert",
args = {MappedStatement.class,Object.class})})
public class MybatisPlugin implements Interceptor {
private Properties properties = new Properties();
@Override
public Object intercept(Invocation invocation) throws Throwable {
Object returnObject = invocation.proceed();
return returnObject;
}
@Override
public void setProperties(Properties properties) {
this.properties = properties;
}
}
配置Mybatis配置文件
<!--拦截插件-->
<plugins>
<plugin interceptor="top.jf.interceptor.MybatisPlugin">
<property name="someProperty" value="100"/>
</plugin>
</plugins>
7、environments(环境配置)
配置MyBatis的多套运行环境,将SQL映射到多个不同的数据库上,但得通过default指定其中一个为默认运行环境。
8、transactionManager(事务管理器)
在 MyBatis 中有两种类型的事务管理器
- JDBC – 这个配置直接使用了 JDBC 的提交和回滚设施,它依赖从数据源获得的连接来管理事务作用域。
- MANAGED – 它从不提交或回滚一个连接,而是让容器来管理事务的整个生命周期。
9、mappers(映射器)
有如下几种映射方式
<!-- 使用相对于类路径的资源引用 -->
<mappers>
<mapper resource="top/jf/mapper/UserMapper.xml"/>
</mappers>
<!-- 使用完全限定资源定位符(URL) -->
<mappers>
<mapper url="file:///var/mappers/UserMapper.xml"/>
</mappers>
<!-- 使用映射器接口实现类的完全限定类名 -->
<mappers>
<mapper class="top.jf.mapper.UserMapper"/>
</mappers>
<!-- 将包内的映射器接口实现全部注册为映射器 -->
<mappers>
<package name="top.jf.mapper"/>
</mappers>
二、Mapper映射文件
1、namespace 命名空间
- 一个完整的mppper文件里有有约束头 xml 与 !DOCTYPE, mapper 根元素与顶级元素,而 namespace 属性是 mapper 的唯一标识。
- 在 Mybatis 中每一段 SQL 语句,同样有唯一的代表方式,那就是「 命名空间标识 + 语句id 」。组合之后在 Mybatis 二级缓存中可以作为本地 map 集合 缓存 的唯一Key ,也可以用于 Dao 接口的 映射 绑定,还能作为唯一 代理标识。
2、映射文件里的九大顶级元素
- select : 用于查询,支持传参,返回指定结果集;
- insert : 用于新增,支持传参,返回指定结果集;
- update : 用于更新,支持传参,返回指定结果集;
- delete : 用于删除,支持传参,返回指定结果集;
- sql : 被其它语句引用的 可复用 语句块;
- cache : 当前命名空间缓存配置;
- cache-ref : 引用其它命名空间的缓存配置;
- parameterMap : 参数映射,已弃用;
- resultMap : 结果集映射。
select、insert、update、delete
以select举例
<select id="selectUser" parameterType="int" resultType="hashmap">
select * from user where id = #{id}
</select>
- id属性:当前mapper.xml文件的唯一标识
- parameterType 属性:传入的参数类型
- resultType属性:返回结果类型,此处使用 hashMap 接收,也可以使用实体类接收,比如这里 用 top.jf.pojo.User , 但是查询返回的字段名需要与实体类的属性保持一致。
值得注意的是,这里的占位符#{id}
会被翻译成 ‘id’,相比于${id}
,能有效防止sql注入,${id}
会直接翻译成 id 。
cache 缓存
默认情况下,只启用了本地的会话缓存(即一级缓存,sqlSession级别 ),它仅仅对一个会话中的数据进行缓存。 要启用全局的二级缓存,首先在全局配置文件config.xml文件中加入如下代码:
<!--开启二级缓存-->
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
其次在UserMapper.xml文件中开启缓存:
<!--开启二级缓存-->
<cache></cache>
缓存只作用于 cache 标签所在的映射文件中的语句。缓存开启有如下等效果
- 映射语句文件中的所有 select 语句的结果将会被缓存。
- 映射语句文件中的所有 insert、update 和 delete 语句会刷新缓存。
- 缓存会使用最近最少使用算法(LRU, Least Recently Used)算法来清除不需要的缓存。
- 缓存不会定时进行刷新(也就是说,没有刷新间隔)。