mybatis - [08] mybatis-config.xml 详解
mybatis-config.xml中的标签需要按照一定顺序配置,否则会有以下提示。
- configuration(配置)
- properties(属性)
- settings(设置)
- typeAliases(类型别名)
- typeHandlers(类型处理器)
- objectFactory(对象工厂)
- plugins(插件)
- environments(环境配置)
- databaseIdProvider(数据库厂商标识)
- mappers(映射器)
001 || properties(属性)
(1)属性可以放在jdbc.properties中,也可以写在<property>标签中
<!-- 第一种写法 -->
<properties resource="jdbc.properties"/>
<!-- 第二种写法 -->
<properties resource="jdbc.properties">
<property name="username" value="harley686"/>
<property name="password" value="harley666"/>
</properties>
(2)jdbc.properties中进行如下配置
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
jdbc.username=root
jdbc.password=123456
(3)无论在<properties>标签中引入.properties配置文件还是使用<property>标签设置的属性,都使用${value}的方式取值
<?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"/>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<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>
</environments>
<!-- 配置mapper.xml -->
<mappers>
<mapper resource="com/harley/dao/UserMapper.xml"/>
</mappers>
</configuration>
(4)测试结果

002 || settings(设置)
参考:https://mybatis.org/mybatis-3/zh_CN/configuration.html#settings
<settings>
<setting name="cacheEnabled" value="true"/> <!-- 缓存是否开启 -->
<setting name="lazyLoadingEnabled" value="true"/> <!--懒加载是否开启-->
<setting name="aggressiveLazyLoading" value="true"/> <!--开启时,任何方法的调用都会加载该对象的所有延迟加载属性。否则,每个延迟加载属性会按需加载。-->
<setting name="multipleResultSetsEnabled" value="true"/> <!--允许或禁止使用多结果集-->
<setting name="useColumnLabel" value="true"/> <!--使用列标签代替列名-->
<setting name="useGeneratedKeys" value="false"/> <!--自动生成主键是否开启,需要驱动支持-->
<setting name="autoMappingBehavior" value="PARTIAL"/><!--MyBatis 自动映射行为-->
<setting name="autoMappingUnknownColumnBehavior" value="WARNING"/><!--指定发现自动映射目标未知列(或未知属性类型)的行为-->
<setting name="defaultExecutorType" value="SIMPLE"/><!--配置默认的执行器。SIMPLE是普通的执行器;REUSE会复用预处理语句;BATCH可以实现批处理。-->
<setting name="defaultStatementTimeout" value="25"/><!--设置超时时间,它决定驱动等待数据库响应的秒数。-->
<setting name="defaultFetchSize" value="100"/><!--为驱动设置默认的fetchSize-->
<setting name="safeRowBoundsEnabled" value="false"/><!--允许在嵌套语句中使用分页-->
<setting name="safeResultHandlerEnabled" value="true"/><!--允许在嵌套语句中使用结果处理器-->
<setting name="mapUnderscoreToCamelCase" value="false"/> <!--是否开启自动驼峰命名规则映射-->
<setting name="localCacheScope" value="SESSION"/><!--利用本地缓存机制(Local Cache)防止循环引用和加速重复嵌套查询-->
<setting name="jdbcTypeForNull" value="OTHER"/><!--指定当JDBC参数为null时使用的JDBC类型-->
<setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/><!--指定哪些方法触发延迟加载-->
<setting name="defaultScriptingLanguage" value="org.apache.ibatis.scripting.xmltags.XMLLanguageDriver"/><!--指定默认的脚本语言-->
<setting name="defaultEnumTypeHandler" value="org.apache.ibatis.type.EnumTypeHandler"/><!--指定默认的枚举类型处理器-->
<setting name="callSettersOnNulls" value="false"/><!--指定当结果集中值为null时,是否调用对象的 setter 方法-->
<setting name="returnInstanceForEmptyRow" value="false"/><!--当查询结果为空时,是否返回对象实例-->
<setting name="logPrefix" value="exampleLogPreFix_"/><!--指定 MyBatis 日志的前缀-->
<setting name="logImpl" value="SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING"/><!--指定 MyBatis 的日志实现-->
<setting name="proxyFactory" value="CGLIB | JAVASSIST"/><!--指定 MyBatis 创建动态代理对象的工厂-->
<setting name="vfsImpl" value="org.mybatis.example.YourselfVfsImpl"/><!--指定自定义的VFS实现类,默认为null-->
<setting name="useActualParamName" value="true"/><!--允许使用方法参数的真实名称-->
<setting name="configurationFactory" value="org.mybatis.example.ConfigurationFactory"/><!--指定一个ConfigurationFactory类,用于创建Configuration对象-->
</settings>
003 || typeAliases(类型别名)
mapper.xml中会有很多resultType="com.harley.pojo.User",结果集类型填写的是Pojo类的全限定名,全限定名比较长,为了使用方便,为Pojo类设置类型别名。
(1)在mybatis-config.xml中为Pojo类配置别名
<typeAliases>
<typeAlias alias="User" type="com.harley.pojo.User"/>
</typeAliases>
(2)在mapper.xml中使用别名
<select id="getUserLike" resultType="User">
select * from user where name like '%${value}%'
</select>
(3)测试结果

除了可以给类设置别名,还可以为包名设置别名
(1)为pojo类所在包设置别名
<typeAliases>
<package name="com.harley.pojo"/>
</typeAliases>
(2)可以在mapper.xml中resultType="User"(User必须和类名一致),也可以使用@Alias("harleyUser")为pojo包下的实体类设置别名

注:使用lombok的注解
@AllArgsConstructor、@NoArgsConstructor、@Data、@ToString,可以省略getter/setter、有参/无参构造方法、toString方法的编写
(3)mapper.xml中resultType="User"需要和@Alias("User")对应,别名是小写,mapper.xml中使用时也必须是小写!
<select id="getUserLike" resultType="harleyUser">
select * from user where name like '%${value}%'
</select>
(4)测试结果

总结:
(1)如果实体类数量比较少,使用第一种方式;如果实体类数量比较多,则使用第二种方式。
(2)第一种可以自定义别名,第二种不行。如果非要改,需要在实体类上加注解
@Alias("别名")
004 || typeHandlers(类型处理器)
用于实现Java类型和JDBC类型之间的相互转换。当Mybatis从数据库中读取数据或将数据写入数据库时,它会使用类型处理器来完成这些转换。
step1:自定义类型处理器
实现org.apache.ibatis.type.TypeHandler接口或者继承org.apache.ibatis.type.BaseTypeHandler抽象类
以下是将Java的LocalDate类型与JDBC的DATE类型进行转换的示例:
package com.harley.utils;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
import java.sql.*;
import java.time.LocalDate;
/**
* @author harley
* @since 2025-02-15 21:33:11
*/
// 标记Java类型
@MappedTypes(LocalDate.class)
// 标记JDBC类型
@MappedJdbcTypes(JdbcType.DATE)
public class LocalDateTypeHandler extends BaseTypeHandler<LocalDate> {
@Override
public void setNonNullParameter(PreparedStatement ps, int i, LocalDate parameter, JdbcType jdbcType) throws SQLException {
ps.setDate(i, Date.valueOf(parameter));
}
@Override
public LocalDate getNullableResult(ResultSet rs, String columnName) throws SQLException {
Date date = rs.getDate(columnName);
return date != null ? date.toLocalDate() : null;
}
@Override
public LocalDate getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
Date date = rs.getDate(columnIndex);
return date != null ? date.toLocalDate() : null;
}
@Override
public LocalDate getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
Date date = cs.getDate(columnIndex);
return date != null ? date.toLocalDate() : null;
}
}
step2:注册类型处理器
在mybatis-config.xml中,使用<typeHandlers>元素来注册自定义的类型处理器。可以通过指定类名的方式逐个注册,也可以指定包名让Mybatis自动扫描包下的所有类型处理器。
逐个注册
<typeHandlers>
<typeHandler handler="com.harley.typeHandlers.LocalDateTypeHandler"/>
</typeHandlers>
批量注册
<typeHandlers>
<package name="com.harley.typeHandlers"/>
</typeHandlers>
step3:使用类型处理器
注册完成后,mybatis会自动使用这些类型处理器进行Java类型和JDBC类型的转换。在SQL映射文件(xxxMapper.xml)中,无需额外配置即可使用。
<select id="selectUserByDate" resultType="com.harley.pojo.User">
select * from mybatis.user where create_date = #{date}
</select>
这里的#{date}如果是LocalDate类型,Mybatis会自动使用LocalDateTypeHandler进行类型转换。
step4:显示指定类型处理器
在某些情况下,需要在SQL映射文件中显示指定使用的类型处理器。可以使用typeHandler属性来指定
<select id="selectUserByDate" resultType="com.harley.pojo.User">
select * from user where create_date = #{date,typeHandler=com.harley.typeHandlers.LocalDateTypeHandler}
</select>
005 || objectFactory(对象工厂)
主要负责创建Java对象实例,使用场景如下:
(1)自定义对象创建逻辑
当默认的对象创建方式无法满足需求时,例如需要在创建对象时进行额外的初始化操作、注入特定的依赖或者根据不同条件创建不同类型的对象,就可以通过自定义ObjectFactory来实现。
(2)集成第三方依赖注入框架
如果项目中使用了如Spring这样的依赖注入框架,需要将依赖注入的逻辑与Mybatis的对象创建过程集成,自定义ObjectFactory可以实现这一点,确保创建的对象能正确注入所需的依赖。
(3)处理特殊对象创建需求
对于一些特殊的Java对象,可能需要特殊的创建方式,例如创建具有复杂构造函数的对象,或者需要从特定的对象池中获取对象,此时自定义ObjectFactory能满足这些特殊需求。
step1:自定义ObjectFactory
package com.harley.utils;
import org.apache.ibatis.reflection.factory.DefaultObjectFactory;
import java.util.List;
import java.util.Properties;
/**
* @author harley
* @since 2025-02-15 21:50:00
*/
public class CustomObjectFactory extends DefaultObjectFactory {
@Override
public <T> T create(Class<T> type) {
// 可以在这里添加自定义的对象创建逻辑
System.out.println("Using custom object factory to create object of type:" + type.getName());
return super.create(type);
}
@Override
public <T> T create(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
// 可以在这里添加自定义的对象创建逻辑
System.out.println("Using custom object factory to create object of type: " + type.getName() + " with constructor args");
return super.create(type, constructorArgTypes, constructorArgs);
}
@Override
public void setProperties(Properties properties) {
// 可以处理传入的属性配置
super.setProperties(properties);
}
}
step2:在mybatis-config.xml中配置自定义ObjectFactory
<objectFactory type="com.harley.utils.CustomObjectFactory">
<!--可以在这里配置属性-->
<property name="propertyName" value="propertyValue"/>
</objectFactory>
step3:使用自定义ObjectFactory
配置完成后,MyBatis在创建对象时会自动使用自定义的ObjectFactory。
当执行查询操作并将结果映射到Java对象时,Mybatis会调用自定义ObjectFactory的create方法来创建对象实例。
<select id="selectUser" resultType="com.harley.pojo.User">
select * from mybatis.user where id = #{id}
</select>
当执行上述查询时,Mybatis会使用自定义的ObjectFactory来创建com.harley.pojo.User对象实例,并且会执行自定义ObjectFactory中重写的create方法里的逻辑。
比如,有一个pojo类为User,包含id、name、age属性。可以在自定义对象工厂(CustomObjectFactory)进行如下配置
@Override
public void setProperties(Properties properties) {
// 从配置属性中获取默认名称和年龄
this.defaultName = properties.getProperty("defaultName", "DefaultUser");
this.defaultAge = Integer.parseInt(properties.getProperty("defaultAge", "20"));
super.setProperties(properties);
}
@Override
public <T> T create(Class<T> type) {
if (type == User.class) {
// 创建 User 对象并使用默认值初始化
User user = new User();
user.setName(defaultName);
user.setAge(defaultAge);
return (T) user;
}
return super.create(type);
}
然后在mybatis-config.xml配置相关属性
<!-- 配置自定义 ObjectFactory -->
<objectFactory type="com.example.CustomObjectFactory">
<property name="defaultName" value="John"/>
<property name="defaultAge" value="25"/>
</objectFactory>
根据Resources.getResourceAsStream("mybatis-config.xml")作为inputStream,然后通过SqlSessionFactoryBuilder().build()方法返回sqlSessionFactory对象,该对象开启会话,进行查询时。会查到如下内容
User{id=1, name='John', age=25}
即为,可为pojo对象的属性进行初始化赋值,类似于Spring的依赖注入功能。
006 || plugins(插件)
常见的使用场景如下:
(1)分页功能:处理大量数据查询时,需要对结果进行分页展示。通过插件可以在SQL执行前动态修改SQL语句,添加分页逻辑,而无需在每个查询方法中手动编写分页代码。
(2)性能监控:对SQL语句的执行时间进行监控,帮助开发者找出性能瓶颈。插件可以在SQL执行前后记录时间,统计执行时长,并将这些信息输出到日志或监控系统中。
(3)数据加密与解密:在数据持久化到数据库之前对敏感数据进行加密,在从数据库查询数据时对加密数据进行解密。插件可以在参数处理和结果处理阶段插入加密和解密逻辑。
(4)SQL日志增强:除了MyBatis自带的日志功能,插件可以进一步增强SQL日志的输出,例如将SQL语句和实际参数进行格式化输出,方便调试和分析。
step1:自定义插件类
package com.harley.plugins;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import java.util.Properties;
/**
* @author harley
* @since 2025-02-15 22:15:06
*/
@Intercepts({
@Signature(type = StatementHandler.class,method="prepare",args = {java.sql.Connection.class,Integer.class})
})
public class CustomPlugin implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
// 在目标方法执行前插入自定义逻辑
System.out.println("Before statement prepare");
Object result = invocation.proceed();
System.out.println("After statement prepare");
return result;
}
@Override
public Object plugin(Object target) {
return Plugin.wrap(target,this);
}
@Override
public void setProperties(Properties properties) {
// 可以处理插件配置的属性
Interceptor.super.setProperties(properties);
}
}
@Intercepts和@Signature注解用于指定要拦截的目标类和方法。这里拦截的是StatementHandler类的prepare方法。intercept方法是插件的核心逻辑,在目标方法执行前后可以插入自定义代码plugin方法用于将插件应用到目标对象上setProperties方法用于处理插件配置的属性
step2:在mybatis-config.xml中配置插件
<plugins>
<plugin interceptor="com.harley.plugins.CustomPlugin">
<!--可以配置插件属性-->
<property name="propertyName" value="propertyValue"/>
</plugin>
</plugins>
007 || environments(环境配置)
可以配置多个环境,但是每个
SqlSessionFactory实例只能选择一种环境。mybatis默认的事务管理器(
transactionManager)就是JDBC,连接池(dataSource)是POOLED注意
<environments>的default需要配置一个<environment>的id
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
011 || mappers(映射器)
(1)使用<mapper>标签指定单个映射文件
<mappers>
<mapper resource="com/example/mapper/UserMapper.xml"/>
</mappers>
(2)使用<mapper>标签指定单个映射接口
<mappers>
<mapper class="com.example.mapper.UserMapper"/>
</mappers>
使用该方法,UserMapper映射接口和UserMapper.xml映射文件必须在同一个包下,且名称必须一致。
(3)使用<package>标签批量扫描包
<mappers>
<package name="com.example.mapper"/>
</mappers>
使用该方法,UserMapper映射接口和UserMapper.xml映射文件必须在同一个包下,且名称必须一致。
— 业精于勤荒于嬉,行成于思毁于随 —
mybatis - [08] mybatis-config.xml 详解的更多相关文章
- Mybatis(一):MyBatis配置文件config.xml详解
MyBatis 配置文件基本结构 在使用mybatis框架时,首先导入其对应的jar包,并进行相应的配置,所以得对配置文件的每个参数都得了解.一个完全的mybatis配置文件结构如下: <?xm ...
- Mybatis映射配置文件Mapper.xml详解
1.概述: MyBatis 的真正强大在于它的映射语句,也是它的魔力所在. 2.常用的属性 常用的几个属性: select元素:代表查询,类似的还有update.insert.delete id:这个 ...
- MyBatis Mapper XML 详解
MyBatis Mapper XML 详解 MyBatis 真正的力量是在映射语句中.这里是奇迹发生的地方.对于所有的力量,SQL 映射的 XML 文件是相当的简单.当然如果你将它们和对等功能的 JD ...
- Quartz学习——SSMM(Spring+SpringMVC+Mybatis+Mysql)和Quartz集成详解(转)
通过前面的学习,你可能大致了解了Quartz,本篇博文为你打开学习SSMM+Quartz的旅程!欢迎上车,开始美好的旅程! 本篇是在SSM框架基础上进行的. 参考文章: 1.Quartz学习——Qua ...
- 《深入理解mybatis原理6》 MyBatis的一级缓存实现详解 及使用注意事项
<深入理解mybatis原理> MyBatis的一级缓存实现详解 及使用注意事项 0.写在前面 MyBatis是一个简单,小巧但功能非常强大的ORM开源框架,它的功能强大也体现在它的缓 ...
- [转载]Mybatis Generator最完整配置详解
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfiguration ...
- applicationContext.xml及springMVC.xml详解
在前面的web.xml详解里,我们引入applicationContext.xml和springMVC.xml两个配置文件, 前者是spring 全局配置文件,用来控制spring 特性的, 后者则是 ...
- Web.xml详解(转)
这篇文章主要是综合网上关于web.xml的一些介绍,希望对大家有所帮助,也欢迎大家一起讨论. ---题记 一. Web.xml详解: (一) web.xml加载过程(步骤) 首 ...
- Asp.net中web.config配置文件详解(一)
本文摘自Asp.net中web.config配置文件详解 web.config是一个XML文件,用来储存Asp.NET Web应用程序的配置信息,包括数据库连接字符.身份安全验证等,可以出现在Asp. ...
- C#中web.config文件详解
C#中web.config文件详解 一.认识Web.config文件 Web.config 文件是一个XML文本文件,它用来储存 ASP.NET Web 应用程序的配置信息(如最常用的设置ASP.NE ...
随机推荐
- Typroa主题替换
Typroa主题替换 从这里下载主题 1.解压后: 2.拷贝到typroa的主题目录下(打开typroa -> 偏好设置 -> 外观 -> 打开主题文件夹) 3.拷贝后: 4.重新打 ...
- docker-compose安装mysql
0. 安装docker-compose,参见:[Amadeus原创]docker compose的安装 1. 目录结构:按以下目录结构mkdir文件夹和相关文件 mysql 目录下的 data 为数据 ...
- 【Amadeus原创】word图片隐藏在文字里了的终极解决办法
终极解决方案: 点击该图片,然后,选择正文,即可.
- 【前端】【探究】HTML - input类型为file时如何实现自定义文本以更好的美化
想到英语四级考了两次都没过,我觉得要多使用英文,所以本文使用英文书写. 本文讲述了遇到的问题,解决的思路,并讲述了解决方案,也许对你会有帮助. 目录 Problem description Solut ...
- Kubernetes 服务发现 监控Endpoints
监控 Pod之前的apiserver 实际上就是一种特殊的 Endpoints,现在我们同样来配置一个任务用来专门发现普通类型的 Endpoint,其实就是 Service 关联的 Pod 列表,由于 ...
- Qt/C++地图高级绘图/指定唯一标识添加删除修改/动态显示和隐藏/支持天地图高德地图百度地图
一.前言说明 已经有了最基础的接口用来添加覆盖物,而且还有通过进入覆盖物模式动态添加覆盖物的功能,为什么还要来个高级绘图?因为又有新的需求,给钱就搞,一点底线都没有.无论哪个地图厂家,提供的接口都是没 ...
- Gitea搭建
关闭注册 找到gitea的配置文件gitea/conf/app.ini,把下面的设置改为true即可: [service] DISABLE_REGISTRATION = true 关闭openid [ ...
- 大端地址 小端地址 网络字节序 intel主机字节序
小端字节序:低字节数据存放在内存低地址处,高字节数据存放在内存高地址处:大端字节序:高字节数据存放在内存低地址处,低字节数据存放在内存高地址处. 网络字节序: MSB 高字节前存法 Most Sign ...
- Web网页端IM产品RainbowChat-Web的v7.1版已发布
一.关于RainbowChat-Web RainbowChat-Web是一套Web网页端IM系统,是RainbowChat的姊妹系统(RainbowChat是一套基于开源IM聊天框架 MobileIM ...
- 微信团队分享:微信后端海量数据查询从1000ms降到100ms的技术实践
本文由微信技术团队仇弈彬分享,原题"微信海量数据查询如何从1000ms降到100ms?",本文进行了内容修订和排版优化. 1.引言 微信的多维指标监控平台,具备自定义维度.指标的监 ...
