百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

MyBatis配置详解:从入门到精通(mybatis-config配置)

mhr18 2025-06-10 16:28 2 浏览 0 评论

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>
  <!-- 配置内容 -->
</configuration>

二、核心配置属性详解

2.1 properties(属性)

<properties resource="db.properties">
  <property name="username" value="dev_user"/>
</properties>

属性:

  • resource:指定外部properties文件的位置
  • url:通过URL指定外部properties文件的位置

子元素:

  • property:定义单个属性

分析:

  • 属性可以外部化配置,便于不同环境切换
  • 加载顺序:先读取properties元素体内的属性,然后读取resource/url指定的属性,后者的属性会覆盖前者
  • 专业建议:生产环境推荐使用外部properties文件,避免将敏感信息硬编码在配置文件中

2.2 settings(设置)

<settings>
  <setting name="cacheEnabled" value="true"/>
  <setting name="lazyLoadingEnabled" value="true"/>
  <!-- 更多设置 -->
</settings>

重要设置详解:

设置名

描述

默认值

建议值

cacheEnabled

全局开启或关闭缓存

true

生产环境建议true

lazyLoadingEnabled

延迟加载的全局开关

false

根据业务需求

aggressiveLazyLoading

当开启时,任何方法的调用都会加载该对象的所有属性

false

建议false

mapUnderscoreToCamelCase

自动将数据库下划线命名转为Java驼峰命名

false

建议true

jdbcTypeForNull

当没有为参数指定jdbcType时,空值的默认JDBC类型

OTHER

建议NULL

logImpl

指定MyBatis所用日志的具体实现

SLF4J或Log4j2

专业分析:

  • 延迟加载设置需要权衡性能与N+1查询问题
  • 缓存设置对性能影响重大,需结合二级缓存策略
  • 日志实现建议使用现代日志框架如SLF4J

2.3 typeAliases(类型别名)

<typeAliases>
  <typeAlias alias="User" type="com.example.model.User"/>
  <package name="com.example.model"/>
</typeAliases>

属性:

  • alias:别名
  • type:Java类全限定名
  • package:指定包名,自动扫描该包下的类,别名默认为类名(首字母小写)

分析:

  • 减少全限定类名的冗余输入
  • 自动扫描功能在大型项目中特别有用
  • 注意:别名冲突时,后定义的会覆盖先定义的

2.4 typeHandlers(类型处理器)

<typeHandlers>
  <typeHandler handler="com.example.MyTypeHandler"/>
  <package name="com.example.handlers"/>
</typeHandlers>

作用:

  • 用于Java类型与JDBC类型之间的转换
  • 可以自定义处理器处理特殊类型

专业建议:

  • 优先使用MyBatis内置的类型处理器
  • 自定义处理器应确保线程安全
  • 复杂类型转换推荐使用自定义处理器

2.5 objectFactory(对象工厂)

<objectFactory type="com.example.MyObjectFactory">
  <property name="someProperty" value="100"/>
</objectFactory>

作用:

  • 创建结果集对象的实例
  • 可以自定义以实现依赖注入等高级功能

分析:

  • 大多数情况下不需要自定义
  • 与Spring等DI框架集成时可能有用

2.6 plugins(插件)

<plugins>
  <plugin interceptor="com.example.MyPlugin">
    <property name="someProperty" value="100"/>
  </plugin>
</plugins>

作用:

  • 通过拦截器实现MyBatis核心行为的拦截和增强
  • 可用于分页、性能监控、SQL改写等

专业分析:

  • 插件是MyBatis最强大的扩展点之一
  • 实现原理基于JDK动态代理
  • 注意拦截方法的性能影响
  • 多个插件执行顺序与配置顺序相同

2.7 environments(环境配置)

<environments default="development">
  <environment id="development">
    <transactionManager type="JDBC"/>
    <dataSource type="POOLED">
      <!-- 数据源配置 -->
    </dataSource>
  </environment>
</environments>

关键配置:

  1. transactionManager(事务管理器)
  2. type:JDBC或MANAGED
  3. JDBC:使用JDBC的事务管理
  4. MANAGED:容器管理事务
  5. 建议:Spring集成时通常不需要配置,由Spring管理事务
  6. dataSource(数据源)
  7. type:UNPOOLED|POOLED|JNDI
  8. UNPOOLED:不使用连接池
  9. POOLED:使用MyBatis内置连接池
  10. JNDI:容器提供数据源
  11. 专业建议:生产环境推荐使用DBCP2、HikariCP等专业连接池

2.8 databaseIdProvider(数据库厂商标识)

<databaseIdProvider type="DB_VENDOR">
  <property name="MySQL" value="mysql"/>
  <property name="Oracle" value="oracle"/>
</databaseIdProvider>

作用:

  • 支持多数据库厂商
  • 可根据不同数据库执行不同SQL

分析:

  • 适用于需要支持多数据库的产品
  • 结合XML中的databaseId属性使用

2.9 mappers(映射器)

<mappers>
  <mapper resource="com/example/mapper/UserMapper.xml"/>
  <mapper class="com.example.mapper.UserMapper"/>
  <package name="com.example.mapper"/>
</mappers>

配置方式:

  • resource:类路径下的XML文件
  • url:文件系统或网络路径的XML文件
  • class:Mapper接口
  • package:包扫描

专业建议:

  • 推荐使用包扫描方式,结合注解或XML
  • 接口与XML文件应保持相同目录结构
  • 注意避免XML与注解同时使用导致的冲突

三、Mapper.xml配置详解

3.1 Mapper 文件基本结构

<?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.UserMapper">
  <!-- SQL 映射定义 -->
</mapper>

3.2 核心元素详解

3.2.1 select 查询语句

<select 
  id="selectUser" 
  parameterType="int" 
  resultType="User"
  resultMap="userResultMap"
  flushCache="false"
  useCache="true"
  timeout="10"
  fetchSize="256"
  statementType="PREPARED"
  resultSetType="FORWARD_ONLY"
  databaseId="mysql"
  lang="xml"
  resultOrdered="false">
  SELECT * FROM user WHERE id = #{id}
</select>

属性详解:

属性

描述

默认值

最佳实践

id

方法名,必须与接口方法名一致

保持命名一致性

parameterType

参数类型

可省略,MyBatis会自动推断

resultType

返回结果类型

简单类型时使用

resultMap

复杂结果映射引用

复杂映射时优先使用

flushCache

执行后清空本地/二级缓存

false

查询通常设为false

useCache

是否使用二级缓存

true

频繁查询且不常改的数据可启用

timeout

查询超时时间(秒)

根据DB性能设置

fetchSize

获取记录数提示

大数据量查询优化

statementType

语句类型(
STATEMENT/PREPARED/CALLABLE)

PREPARED

通常保持默认

resultSetType

结果集类型(
FORWARD_ONLY/SCROLL_INSENSITIVE/SCROLL_SENSITIVE)

驱动默认

大数据量考虑SCROLL

databaseId

数据库厂商标识

多数据库支持时使用

lang

动态SQL语言

xml

自定义语言时使用

resultOrdered

嵌套结果排序

false

解决嵌套结果问题时使用

专业分析:

  • resultMap vs resultType:复杂对象关联映射必须使用resultMap
  • 缓存控制:对于实时性要求高的数据,可设置useCache="false"
  • 性能优化:大数据量查询适当设置fetchSize可减少内存消耗

3.2.2 insert/update/delete DML语句

<insert 
  id="insertUser" 
  parameterType="User"
  flushCache="true"
  timeout="20"
  statementType="PREPARED"
  useGeneratedKeys="true"
  keyProperty="id"
  keyColumn="id"
  databaseId="mysql">
  INSERT INTO user(name,email) VALUES(#{name},#{email})
</insert>

特有属性:

属性

描述

默认值

最佳实践

useGeneratedKeys

使用JDBC获取自增主键

false

自增主键表必须设为true

keyProperty

主键属性名

与实体类属性名一致

keyColumn

主键列名

与数据库列名一致

flushCache

执行后清空缓存

true(insert/update/delete)

通常保持默认

批量插入示例:

<insert id="batchInsert" useGeneratedKeys="true" keyProperty="id">
  INSERT INTO user (name,email) VALUES
  <foreach collection="list" item="item" separator=",">
    (#{item.name},#{item.email})
  </foreach>
</insert>

专业建议:

  • 批量操作使用foreach标签
  • Oracle等序列数据库需使用<selectKey>获取主键
  • 重要业务数据考虑添加@Transactional注解

3.2.3 resultMap 结果映射

<resultMap id="userResultMap" type="User">
  <constructor>
    <idArg column="id" name="id" javaType="int"/>
    <arg column="username" name="name" javaType="String"/>
  </constructor>
  <id property="id" column="id"/>
  <result property="username" column="name"/>
  <association property="role" javaType="Role" resultMap="roleResultMap"/>
  <collection property="posts" ofType="Post" select="selectPostsByUser"/>
  <discriminator javaType="int" column="type">
    <case value="1" resultMap="adminResultMap"/>
    <case value="2" resultMap="userResultMap"/>
  </discriminator>
</resultMap>

元素详解:

  1. constructor - 用于实例化类时注入结果到构造方法
  2. idArg:ID参数,标记结果作为ID
  3. arg:普通注入到构造方法的参数
  4. id & result - 基本映射
  5. property:Java属性名
  6. column:数据库列名
  7. javaType:Java类型
  8. jdbcType:JDBC类型
  9. typeHandler:类型处理器
  10. association - 复杂类型关联(一对一)
  11. 可以使用resultMapselect实现延迟加载
  12. collection - 集合关联(一对多)
  13. ofType:集合中元素的类型
  14. 同样支持延迟加载
  15. discriminator - 鉴别器(根据值映射不同结果)
  16. 实现类似switch-case的逻辑

专业建议:

  • 复杂对象图优先使用resultMap而非嵌套select
  • N+1查询问题可通过联合查询+结果映射解决
  • 延迟加载对性能影响较大,需实际测试

3.2.4 sql 可重用SQL片段

<sql id="userColumns">id,username,email</sql>

<select id="selectUsers" resultType="User">
  SELECT <include refid="userColumns"/> FROM user
</select>

最佳实践:

  • 提取公共列名、条件语句
  • 支持<property>传递参数
  • 大型项目中可集中管理SQL片段

3.2.5 parameterMap (已废弃)

<!-- 不推荐使用 -->
<parameterMap id="userParamMap" type="User">
  <parameter property="id" jdbcType="INTEGER"/>
</parameterMap>

注意:

  • MyBatis 3已废弃parameterMap
  • 推荐使用内联参数映射

3.3 动态SQL标签

3.2.1 if 条件判断

<select id="findActiveUser" resultType="User">
  SELECT * FROM user WHERE state = 'ACTIVE'
  <if test="name != null">
    AND name LIKE #{name}
  </if>
</select>

3.3.2 choose/when/otherwise 多重选择

<select id="findUser" resultType="User">
  SELECT * FROM user WHERE state = 'ACTIVE'
  <choose>
    <when test="id != null">
      AND id = #{id}
    </when>
    <when test="name != null">
      AND name LIKE #{name}
    </when>
    <otherwise>
      AND email IS NOT NULL
    </otherwise>
  </choose>
</select>

3.3.3 trim/where/set 智能处理

<select id="findUser" resultType="User">
  SELECT * FROM user
  <where>
    <if test="id != null">id = #{id}</if>
    <if test="name != null">AND name LIKE #{name}</if>
  </where>
</select>

<update id="updateUser">
  UPDATE user
  <set>
    <if test="name != null">name = #{name},</if>
    <if test="email != null">email = #{email},</if>
  </set>
  WHERE id = #{id}
</update>

3.3.4 foreach 循环遍历

<select id="selectUsersInIds" resultType="User">
  SELECT * FROM user WHERE id IN
  <foreach item="id" collection="list" open="(" separator="," close=")">
    #{id}
  </foreach>
</select>

参数说明:

  • collection:集合属性名(可传List、Set、Map、数组)
  • item:当前元素变量名
  • index:索引变量名
  • open/close:包装符号
  • separator:分隔符

3.3.5 bind 变量绑定

<select id="selectUsers" resultType="User">
  <bind name="pattern" value="'%' + name + '%'"/>
  SELECT * FROM user WHERE name LIKE #{pattern}
</select>

3.4 高级映射技巧

3.4.1 嵌套结果 vs 嵌套查询

嵌套结果(联合查询):

<resultMap id="blogResultMap" type="Blog">
  <id property="id" column="blog_id"/>
  <result property="title" column="blog_title"/>
  <association property="author" javaType="Author" resultMap="authorResultMap"/>
</resultMap>

<select id="selectBlog" resultMap="blogResultMap">
  SELECT 
    b.id as blog_id,
    b.title as blog_title,
    a.id as author_id,
    a.name as author_name
  FROM blog b LEFT JOIN author a ON b.author_id = a.id
  WHERE b.id = #{id}
</select>

嵌套查询(分次查询):

<resultMap id="blogResultMap" type="Blog">
  <association property="author" column="author_id" javaType="Author" select="selectAuthor"/>
</resultMap>

<select id="selectBlog" resultMap="blogResultMap">
  SELECT * FROM blog WHERE id = #{id}
</select>

<select id="selectAuthor" resultType="Author">
  SELECT * FROM author WHERE id = #{id}
</select>

对比分析:

  • 嵌套结果:单次查询,性能更好,适合简单关联
  • 嵌套查询:支持延迟加载,适合复杂对象图
  • N+1问题:嵌套查询需注意关联查询次数

3.4.2 鉴别器高级用法

<resultMap id="vehicleResultMap" type="Vehicle">
  <discriminator javaType="String" column="vehicle_type">
    <case value="CAR" resultMap="carResultMap"/>
    <case value="TRUCK" resultMap="truckResultMap"/>
  </discriminator>
</resultMap>

应用场景:

  • 继承结构的数据库表示
  • 单表存储多种类型数据
  • 类似面向对象的多态行为

3.5 缓存配置

3.5.1 二级缓存配置

<cache
  eviction="FIFO"
  flushInterval="60000"
  size="512"
  readOnly="true"
  type="com.example.MyCustomCache"/>

属性说明:

  • eviction:回收策略(LRU/FIFO/SOFT/WEAK)
  • flushInterval:刷新间隔(ms)
  • size:缓存对象数量
  • readOnly:是否只读(性能更好)
  • type:自定义缓存实现

专业建议:

  • 频繁读取很少修改的数据适合缓存
  • 注意缓存一致性,更新操作要清空缓存
  • 分布式系统需要实现自定义缓存

四、高级配置与最佳实践

4.1 多环境配置策略

<environments default="${environment}">
  <environment id="development">
    <!-- 开发环境配置 -->
  </environment>
  <environment id="production">
    <!-- 生产环境配置 -->
  </environment>
</environments>

最佳实践:

  • 使用properties文件管理环境变量
  • 结合Maven profiles实现构建时环境切换

4.2 自定义类型处理器

@MappedTypes(String.class)
@MappedJdbcTypes(JdbcType.VARCHAR)
public class ExampleTypeHandler extends BaseTypeHandler<String> {
  // 实现方法
}

应用场景:

  • 加密/解密字段
  • 特殊格式处理(如JSON、XML字段)
  • 枚举类型的自定义存储

4.3 插件开发要点

@Intercepts({
  @Signature(type= Executor.class, method="query", 
    args={MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})
})
public class ExamplePlugin implements Interceptor {
  // 实现方法
}

关键点:

  • 明确拦截的目标和方法
  • 注意拦截器链的执行顺序
  • 避免在插件中执行耗时操作

五、性能调优相关配置

5.1 缓存配置优化

<settings>
  <setting name="localCacheScope" value="SESSION"/>
</settings>

选项:

  • SESSION:缓存一个会话中执行的所有查询(默认)
  • STATEMENT:仅缓存单条语句

分析:

  • SESSION级别在事务型应用中表现更好
  • STATEMENT级别可减少内存使用

5.2 批量操作优化

<settings>
  <setting name="defaultExecutorType" value="BATCH"/>
</settings>

执行器类型:

  • SIMPLE:普通执行器(默认)
  • REUSE:重用预处理语句
  • BATCH:批量更新优化

建议:

  • 批量操作时使用BATCH执行器
  • 可通过SqlSessionFactory.openSession(ExecutorType.BATCH)临时切换

六、安全相关配置

6.1 SQL注入防护

  • 始终使用#{}参数语法而非${}拼接
  • 对必须使用${}的场景进行严格过滤

6.2 敏感信息保护

  • 数据库密码等敏感信息应使用加密properties文件
  • 或通过JNDI由容器管理数据源

关注我?别别别,我怕你笑出腹肌找我赔钱。


头条对markdown的文章显示不太友好,想了解更多的可以关注微信公众号:“Eric的技术杂货库”,后期会有更多的干货以及资料下载。

相关推荐

重大故障!业务核心表被truncate删除,准备跑路……

完蛋!最近项目组同事说,核心业务表被truncate删除,也惊呆了,现在的业务都这么粗暴了,安全机制、作业规范形同虚设?接下来就给大家一起聊下,表被truncate,解决问题的关键就是找到关键的问题!...

数据孤岛(Data Silos)(数据孤岛解决方案)

数据孤岛(DataSilos)是指组织内部数据因技术、管理或文化壁垒被隔离在不同部门、系统或平台中,无法有效共享、整合和交互的状态。这些数据如同分散的“岛屿”,虽各自有价值,但因孤立性难以发挥整体效...

弱口令漏洞总结及研究(弱口令是高危漏洞吗)

1.1弱口令漏洞定义弱口令漏洞是指因使用简单、易猜测、易破解的密码导致的系统安全风险。常见的弱口令包括:默认密码:如admin/admin、root/123456。规律字符:如连续数字(123456)...

SQL 逻辑处理核心知识点全解析,从入门到精通看这篇就够了!

刚入行程序员/数据分析?写SQL总卡壳?别愁!今天一次性把SQL逻辑处理核心技能讲透,涵盖数值、字符、日期函数+条件表达式,附超全数据库差异对比,工作中直接套用!一、SQL函数大揭秘!...

智能文档检索:AI语义搜索实践(智能语音检索)

以下是基于AI语义搜索的智能文档检索实践要点解析,结合行业前沿案例与技术框架:一、核心技术架构与实现路径语义理解与嵌入模型采用BERT、GPT等预训练模型进行文本向量化,捕捉上下文语义15通过多模态分...

国产IAutodraw办公工具更新到3.7.5!这些隐藏功能你知道吗?

大家好,IAuto流程软件(简称IAutodraw)终于迎来2025年的第一个版本更新,本次更新同时包含Window、Mac等操作系统,更新的内容包括:1、流程画布支持Mermaid语法的粘贴(mer...

企业复杂数据处理必备:五款主流好用的报表工具

1.山海鲸报表山海鲸报表(免费的零代码BI报表工具,为您提供BI报表+GIS+数字孪生+可视化大屏一体化服务)作为国产报表工具中的后起之秀,专注于为企业提供高效、便捷的数据可视化与分析方案。它最大的...

Oracle数据库批量更新翻车!老司机3招省80%时间

开篇热梗:凌晨3点,程序员老张盯着屏幕上转不停的进度条,第N次猛灌咖啡——10万条数据更新跑了半小时还没完!突然“啪”的一声,屏幕黑了...(你的系统是不是也这样崩溃过?评论区扣1)终极总结:3句话讲...

硬盘smart健康深度检测工具——wgcloud

S.M.A.R.T的全称为“Self-MonitoringAnalysisandReportingTechnology”,上个世纪九十年代,由于经常发生硬盘莫名其妙的故障问题,导致很多用户的数...

Oracle 数据库培训:让你从菜鸟到大师的华丽转身

深入学习理论知识基础教程:介绍数据库管理系统的基本原理,让学员理解数据库的工作机制。讲解Oracle数据库的安装过程,包括各种环境配置和参数设置。教授如何使用SQL语言进行基本操作,如数据的查...

从 0 到 1:30 天变身 Oracle 数据库大师的独家学习秘籍

基础理论学习数据库基础概念:学习数据库的基本概念,如数据库管理系统表、行、列、索引、事务等。可以阅读《数据库系统概念》这样的经典教材,系统地掌握数据库的基础知识。SQL语言:SQL是与数据库交互的...

数据库故障排查指南(数据库故障处理流程)

数据库故障排查指南大纲常见故障类型与症状连接问题:无法连接、连接超时、连接数过多性能问题:查询缓慢、CPU/内存占用过高、锁等待数据一致性问题:数据丢失、数据损坏、主从不一致日志与错误消息:关键错误日...

Java性能监控工具大揭秘:全面掌握你的应用表现

Java性能监控工具大揭秘:全面掌握你的应用表现在Java开发的世界里,性能优化如同一场永无止境的马拉松。一个程序再优雅的设计,如果执行效率低下,也会让人头疼不已。而性能监控工具就像是我们身边的“跑表...

jmap(jmap -heap详解)

jmap是JDK自带的一个命令行工具,用于生成Java进程的堆内存快照(heapdump),也可以查看Java堆内存的详细统计信息。它是排查内存泄漏、分析对象占用内存情况的重要工具之...

Java性能监控工具:让程序跑得更快的秘密武器

Java性能监控工具:让程序跑得更快的秘密武器大家好呀!今天咱们来聊聊Java程序背后的“幕后英雄”——性能监控工具。这些工具就像是医生手中的听诊器,能够帮我们及时发现程序运行中的各种“健康问题”。无...

取消回复欢迎 发表评论: