当前位置: 首页 > news >正文

MyBatis 从入门到精通(第二篇)—— 核心架构、配置解析与 Mapper 代理开发

        在第一篇博客中,我们掌握了 MyBatis 的基础概念与环境搭建,成功通过简单查询实现了数据持久化。但要真正用好 MyBatis,还需深入理解其 “内部工作原理” 与 “企业级开发规范”。本篇将聚焦三大核心:MyBatis 架构与核心类全局配置文件详解Mapper 代理开发(企业主流方案),帮你从 “会用” 升级到 “懂原理、能规范开发”。

目录

一、深入 MyBatis 架构:三层架构 + 核心类解析

1.1 三层架构:从 “调用入口” 到 “基础支撑”

(1)API 接口层:上层应用的 “交互入口”

(2)数据处理层(核心层):MyBatis 的 “业务大脑”

(3)基础支撑层:MyBatis 的 “后勤保障”

1.2 5 个核心类:MyBatis 的 “关键零件”

核心类工作流程示例(以 “查询部门” 为例):

二、MyBatis 全局配置文件:SqlMapConfig.xml 详解

2.1 properties标签:灵活管理数据源参数

方式 1:内部直接定义属性(简单但不推荐)

方式 2:加载外部jdbc.properties文件(推荐)

方式 3:动态传入属性(了解,特殊场景用)

2.2 settings标签:MyBatis 的 “运行开关”

配置示例:

2.3 typeAliases标签:简化全限定类名的 “别名神器”

方式 1:为单个类定义别名(简单场景用)

方式 2:为包下所有类定义别名(推荐,企业常用)

2.4 environments标签:多环境配置(开发 / 测试 / 生产)

配置示例:

关键子标签说明:

切换环境:

2.5 mappers标签:告诉 MyBatis “SQL 在哪里”

方式 1:加载类路径下的 Mapper.xml(入门用)

方式 2:加载本地文件系统的 Mapper.xml(了解)

方式 3:加载单个 Mapper 接口(Mapper 代理用)

方式 4:扫描包下所有 Mapper 接口(推荐,企业常用)

三、Mapper 代理开发:企业级 Dao 层开发规范

3.1 为什么要放弃 “原始 Dao 开发”?

3.2 Mapper 代理开发的 4 个核心规范

3.3 Mapper 代理开发实战步骤

步骤 1:创建 Mapper 接口(DeptMapper.java)

步骤 2:创建对应的 Mapper.xml(DeptMapper.xml)

步骤 3:配置SqlMapConfig.xml的mappers标签

步骤 4:编写测试类,通过代理对象调用方法

代理开发的优势总结:

四、总结与下一步预告


一、深入 MyBatis 架构:三层架构 + 核心类解析

        就像开车需要了解方向盘、油门的作用,使用 MyBatis 前,搞懂其架构与核心类,能让你在遇到问题时快速定位原因。MyBatis 的功能架构自上而下分为三层,核心类则是每层的 “关键执行器”。

1.1 三层架构:从 “调用入口” 到 “基础支撑”

MyBatis 的架构设计清晰,每层职责明确,协同完成数据库操作,具体如下:

(1)API 接口层:上层应用的 “交互入口”

        这是我们最常接触的一层,核心对象是SqlSession—— 它是上层应用(如 Service 层)与 MyBatis 的 “桥梁”,提供了 CRUD 操作的所有方法(如selectList()查询列表、insert()插入数据、update()更新数据)。
我们无需关心底层如何执行 SQL,只需通过SqlSession调用对应的方法即可。例如:

// 通过SqlSession调用查询方法,定位SQL的“namespace+id”
List<Dept> depts = session.selectList("com.jr.mapper.DeptMapper.selectDept");

SqlSession接收到调用请求后,会将任务交给下一层(数据处理层)执行。

(2)数据处理层(核心层):MyBatis 的 “业务大脑”

这是 MyBatis 的核心,负责完成数据库操作的全流程,主要做四件事:

  1. 参数映射:将 Java 代码传入的参数(如Integer deptno)解析并转换为 JDBC 支持的类型(如SQL INTEGER);
  2. SQL 解析:读取 Mapper.xml 中的 SQL 语句,处理动态 SQL(如<if><where>标签),生成最终可执行的 SQL;
  3. SQL 执行:通过执行器(Executor)调用 JDBC API 执行 SQL,与数据库交互;
  4. 结果映射:将数据库返回的 ResultSet 结果集,自动映射为 Java 实体类(如Dept对象),无需手动遍历赋值。

这一层的核心组件是Executor(执行器),它是 SQL 执行的 “实际操作者”,MyBatis 提供了三种常用执行器:

  • SimpleExecutor:默认执行器,每次执行 SQL 都会创建新的PreparedStatement
  • ReuseExecutor:重用PreparedStatement,避免重复创建,提升性能;
  • BatchExecutor:支持批量更新,适用于大量插入 / 更新场景。
(3)基础支撑层:MyBatis 的 “后勤保障”

这一层提供通用功能支撑,为上层(数据处理层)服务,核心能力包括:

  • 连接管理:通过数据源(DataSource)管理数据库连接,支持连接池(如POOLED类型),避免频繁创建 / 关闭连接;
  • 事务管理:支持 JDBC 事务(手动提交 / 回滚)和 MANAGED 事务(交给容器管理,如 Spring);
  • 缓存处理:实现一级缓存(SqlSession级别)和二级缓存(Mapper级别),减少数据库访问次数;
  • 工具类:提供 XML 解析、反射、日志打印等基础工具,简化框架内部逻辑。

1.2 5 个核心类:MyBatis 的 “关键零件”

理解核心类的作用与生命周期,是排查问题、优化性能的关键,下表整理了必须掌握的 5 个核心类:

核心类核心作用生命周期关键特点
SqlSessionFactory创建SqlSession的 “工厂”应用启动时创建,全局唯一一旦创建,需一直存在,不可重复创建(浪费资源)
SqlSession与数据库的 “一次会话”,提供 CRUD 方法每次操作数据库时创建,用完关闭非线程安全,必须手动关闭(推荐try-finally
Executor执行器,负责 SQL 的实际执行(查询 / 更新)每个SqlSession对应一个Executor可通过配置切换执行器类型(如批量执行器)
MappedStatement存储 Mapper.xml 中的 SQL 信息(id、参数、结果映射)应用启动时加载,全局唯一每个 SQL 节点(如<select>)对应一个实例
Configuration存储 MyBatis 的所有配置信息(数据源、映射、settings)应用启动时解析配置文件生成是 MyBatis 的 “配置中心”,所有核心类都依赖它
核心类工作流程示例(以 “查询部门” 为例):
  1. 应用启动时,解析SqlMapConfig.xmlDeptMapper.xml,生成Configuration对象;
  2. 通过SqlSessionFactoryBuilder读取Configuration,创建SqlSessionFactory
  3. 调用SqlSessionFactory.openSession(),创建SqlSession,并为其分配Executor
  4. 调用SqlSession.selectList("com.jr.mapper.DeptMapper.selectDept")SqlSession通过 “namespace+id” 找到对应的MappedStatement
  5. Executor根据MappedStatement中的 SQL 信息,执行 SQL 并处理结果,最终返回Dept列表;
  6. 关闭SqlSession,释放Executor与数据库连接。

二、MyBatis 全局配置文件:SqlMapConfig.xml 详解

SqlMapConfig.xml是 MyBatis 的 “全局控制中心”,所有影响 MyBatis 行为的配置都集中在这里。上篇我们只写了基础配置,本篇将详细解析 5 个核心配置标签,覆盖企业开发中的常用场景。

2.1 properties标签:灵活管理数据源参数

properties标签用于加载数据库连接参数(如驱动、URL、用户名、密码),避免硬编码在配置文件中,支持三种使用方式,推荐第二种(加载外部属性文件)

方式 1:内部直接定义属性(简单但不推荐)

直接在properties标签内写死参数,修改时需改配置文件,灵活性差:

<configuration><!-- 内部定义数据源参数 --><properties><property name="driver" value="com.mysql.cj.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/mytestdb?serverTimezone=GMT&amp;useSSL=false"/><property name="username" value="root"/><property name="password" value="root"/></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>
</configuration>
方式 2:加载外部jdbc.properties文件(推荐)

将参数放在独立的属性文件中,实现 “参数与配置分离”,修改参数无需动SqlMapConfig.xml

src/main/resources下新建jdbc.properties文件:

# jdbc.properties:单独存储数据源参数
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mytestdb?serverTimezone=GMT&useSSL=false
username=root
password=root

SqlMapConfig.xml中加载该文件:

<configuration><!-- 加载外部属性文件,resource指定文件路径(类路径下) --><properties resource="jdbc.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>
</configuration>
方式 3:动态传入属性(了解,特殊场景用)

通过SqlSessionFactoryBuilder.build()方法动态传入参数,覆盖配置文件中的值,适用于 “临时切换数据源” 场景:

// 1. 加载配置文件
InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
// 2. 动态创建属性,覆盖url
Properties props = new Properties();
props.setProperty("url", "jdbc:mysql://localhost:3306/testdb2?serverTimezone=GMT&useSSL=false");
// 3. 传入属性,创建SqlSessionFactory
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is, props);

重要优先级规则:动态传入的属性 > 外部属性文件 > 内部定义的属性,即后加载的属性会覆盖先加载的同名属性。

2.2 settings标签:MyBatis 的 “运行开关”

settings标签用于配置 MyBatis 的全局运行参数,这些参数直接影响框架的性能与行为。企业开发中常用的配置如下:

设置项作用描述默认值推荐配置
cacheEnabled开启全局二级缓存(后续博客详解)true保持默认 true
lazyLoadingEnabled开启延迟加载(按需加载关联数据,如查员工时不默认查部门)false复杂项目设为 true
aggressiveLazyLoading开启 “积极懒加载”:访问实体类任一属性,加载所有关联数据false(3.4.1+)设为 false(按需加载,更灵活)
mapUnderscoreToCamelCase开启 “下划线转驼峰”:数据库字段dept_name自动映射为实体类属性deptNamefalse必须设为 true(避免手动映射字段)
logImpl指定日志实现(如 SLF4J、LOG4J)未设置开发环境设为 LOG4J(方便看 SQL 日志)
配置示例:
<configuration><properties resource="jdbc.properties"/><!-- settings标签必须在properties之后、typeAliases之前 --><settings><!-- 开启下划线转驼峰,避免手动映射字段 --><setting name="mapUnderscoreToCamelCase" value="true"/><!-- 开启延迟加载,优化关联查询性能 --><setting name="lazyLoadingEnabled" value="true"/><!-- 关闭积极懒加载,按需加载关联数据 --><setting name="aggressiveLazyLoading" value="false"/></settings><!-- 其他配置... -->
</configuration>

2.3 typeAliases标签:简化全限定类名的 “别名神器”

        在 Mapper.xml 中,resultType/parameterType需要写实体类的全限定类名(如com.jr.pojo.Dept),重复书写繁琐且易出错。typeAliases标签可给实体类定义 “别名”,简化书写。

方式 1:为单个类定义别名(简单场景用)
<configuration><properties resource="jdbc.properties"/><settings>...</settings><!-- 为单个实体类定义别名 --><typeAliases><!-- alias:别名,type:实体类全限定类名 --><typeAlias alias="dept" type="com.jr.pojo.Dept"/><typeAlias alias="emp" type="com.jr.pojo.Emp"/></typeAliases><!-- 其他配置... -->
</configuration>

使用时直接写别名,无需全限定类名:

<!-- Mapper.xml中使用别名 -->
<select id="selectDept" resultType="dept"> <!-- 直接用“dept”代替“com.jr.pojo.Dept” -->select * from dept
</select>
方式 2:为包下所有类定义别名(推荐,企业常用)

        若实体类较多,逐个定义别名太麻烦,可直接扫描整个包,MyBatis 会自动将 “类名首字母小写” 作为别名(如DeptdeptEmpemp):

<configuration><properties resource="jdbc.properties"/><settings>...</settings><!-- 扫描com.jr.pojo包下所有实体类,自动生成别名 --><typeAliases><package name="com.jr.pojo"/></typeAliases><!-- 其他配置... -->
</configuration>

特殊需求:若想自定义别名(不使用首字母小写),可在实体类上添加@Alias注解:

import org.apache.ibatis.type.Alias;@Alias("myDept") // 自定义别名“myDept”
public class Dept {// 实体类属性、getter/setter...
}

使用时直接写自定义别名:

<select id="selectDept" resultType="myDept">select * from dept
</select>

2.4 environments标签:多环境配置(开发 / 测试 / 生产)

        实际项目中,开发、测试、生产环境的数据库配置不同(如开发用本地库,生产用服务器库),environments标签支持配置多个环境,默认激活一个。

配置示例:
<configuration><properties resource="jdbc.properties"/><settings>...</settings><typeAliases>...</typeAliases><!-- default:默认激活的环境ID(此处为开发环境) --><environments default="development"><!-- 开发环境 --><environment id="development"><!-- 事务管理器:JDBC(手动控制事务) --><transactionManager type="JDBC"/><!-- 数据源:POOLED(连接池,开发/测试用) --><dataSource type="POOLED"><property name="driver" value="${dev.driver}"/><property name="url" value="${dev.url}"/><property name="username" value="${dev.username}"/><property name="password" value="${dev.password}"/></dataSource></environment><!-- 生产环境 --><environment id="production"><!-- 事务管理器:MANAGED(交给Spring容器管理) --><transactionManager type="MANAGED"/><!-- 数据源:POOLED(生产环境也用连接池,提升性能) --><dataSource type="POOLED"><property name="driver" value="${prod.driver}"/><property name="url" value="${prod.url}"/><property name="username" value="${prod.username}"/><property name="password" value="${prod.password}"/></dataSource></environment></environments><!-- 其他配置... -->
</configuration>

对应的jdbc.properties需包含多环境参数:

# 开发环境参数
dev.driver=com.mysql.cj.jdbc.Driver
dev.url=jdbc:mysql://localhost:3306/dev_db?serverTimezone=GMT&useSSL=false
dev.username=root
dev.password=root# 生产环境参数
prod.driver=com.mysql.cj.jdbc.Driver
prod.url=jdbc:mysql://192.168.1.100:3306/prod_db?serverTimezone=GMT&useSSL=false
prod.username=prod_user
prod.password=prod_pwd
关键子标签说明:
  • transactionManager(事务管理器)
    支持两种类型:JDBC(依赖数据源连接,手动调用session.commit()提交事务)和MANAGED(不管理事务,交给容器如 Spring 处理,MyBatis 只负责 SQL 执行)。
  • dataSource(数据源)
    支持三种类型:
    • POOLED:连接池,创建连接池管理连接,避免频繁创建 / 关闭,开发 / 测试 / 生产都推荐;
    • UNPOOLED:无连接池,每次执行 SQL 都新建连接,性能差,仅适用于小规模项目;
    • JNDI:从应用服务器(如 Tomcat)的 JNDI 数据源获取连接,适用于 JavaEE 企业级项目。
切换环境:

默认使用default指定的环境,若需切换(如测试时用生产环境配置),可在创建SqlSessionFactory时指定环境 ID:

InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");
// 指定激活“production”环境
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is, "production");

2.5 mappers标签:告诉 MyBatis “SQL 在哪里”

mappers标签用于配置 “Mapper 映射文件” 或 “Mapper 接口” 的位置 ——MyBatis 需要通过它找到我们写的 SQL 语句,常用四种配置方式,企业开发推荐后两种(Mapper 代理用)

方式 1:加载类路径下的 Mapper.xml(入门用)

通过resource指定 Mapper.xml 的类路径,适用于 “普通项目” 或 “非代理开发” 场景:

<mappers><mapper resource="com/jr/mapper/DeptMapper.xml"/><mapper resource="com/jr/mapper/EmpMapper.xml"/>
</mappers>
方式 2:加载本地文件系统的 Mapper.xml(了解)

通过url指定本地文件的绝对路径,适用于 Mapper.xml 不在类路径下的场景(很少用):

<mappers><mapper url="file:///D:/mybatis-project/mappers/DeptMapper.xml"/>
</mappers>
方式 3:加载单个 Mapper 接口(Mapper 代理用)

通过class指定 Mapper 接口的全限定类名,适用于 “Mapper 代理开发”(后续详解),要求:Mapper 接口与 Mapper.xml 在同一包下,且文件名相同

<mappers><mapper class="com.jr.mapper.DeptMapper"/><mapper class="com.jr.mapper.EmpMapper"/>
</mappers>
方式 4:扫描包下所有 Mapper 接口(推荐,企业常用)

通过package扫描整个包下的所有 Mapper 接口,自动关联对应的 Mapper.xml,要求与方式 3 一致(接口与 XML 同包同名),简化大量配置:

<mappers><!-- 扫描com.jr.mapper包下所有Mapper接口 --><package name="com.jr.mapper"/>
</mappers>

三、Mapper 代理开发:企业级 Dao 层开发规范

        在第一篇的环境搭建中,我们通过SqlSession.selectList("namespace+id")调用 SQL,这种方式属于 “原始 Dao 开发”。但在企业项目中,更推荐Mapper 代理开发—— 无需编写 Dao 接口的实现类,MyBatis 会自动生成代理对象,大幅减少重复代码。

3.1 为什么要放弃 “原始 Dao 开发”?

原始 Dao 开发需要手动编写 Dao 接口的实现类(如DeptDaoImpl),存在三个明显缺点:

  1. 模板代码冗余:实现类中大量重复代码(如创建SqlSession、调用方法、关闭SqlSession),开发者沦为 “代码搬运工”;
  2. SQL ID 硬编码:调用SqlSession方法时,需写死 SQL 的 “namespace+id”(如session.selectList("com.jr.mapper.DeptMapper.selectDept")),写错不会在编译期报错,只能在运行时发现;
  3. 类型不安全SqlSession的方法参数与返回值大量使用泛型(如selectList()返回List<Object>),若参数类型或返回值类型错误,编译期无法察觉。

而 Mapper 代理开发能完美解决这些问题 —— 只需写 “Mapper 接口” 和 “Mapper.xml”,MyBatis 自动生成实现类代理对象,既简洁又安全。

3.2 Mapper 代理开发的 4 个核心规范

要让 MyBatis 自动生成代理对象,必须遵守以下 4 个规范(缺一不可),否则框架无法关联接口与 SQL:

  1. 接口与 XML 同包同名:Mapper 接口(如DeptMapper.java)与 Mapper.xml(如DeptMapper.xml)必须在同一包下,且文件名完全相同;
  2. XML 的 namespace 与接口全路径一致:Mapper.xml 的namespace属性必须等于 Mapper 接口的全限定类名(如com.jr.mapper.DeptMapper);
  3. 接口方法名与 XML 的 SQL ID 一致:Mapper 接口中的方法名(如selectDept())必须等于 Mapper.xml 中 SQL 标签的id(如<select id="selectDept">);
  4. 接口方法参数 / 返回值与 XML 匹配
    • 接口方法的参数类型 ≡ XML 中 SQL 的parameterType
    • 接口方法的返回值类型 ≡ XML 中 SQL 的resultType/resultMap(若返回列表,返回值类型为List<实体类>,XML 中resultType为单个实体类)。

3.3 Mapper 代理开发实战步骤

以 “查询部门列表” 为例,完整演示 Mapper 代理开发的流程(基于 Maven 项目):

步骤 1:创建 Mapper 接口(DeptMapper.java)

src/main/java/com/jr/mapper下创建接口,定义查询方法,无需写实现类:

package com.jr.mapper;import com.jr.pojo.Dept;
import java.util.List;// 规范1:接口名与后续XML文件名相同(DeptMapper)
public interface DeptMapper {// 规范3:方法名与XML中SQL的id一致(selectDept)// 规范4:返回值类型为List<Dept>,对应XML中resultType="dept"(单个实体类)List<Dept> selectDept();// 新增:根据部门编号查询单个部门(演示参数匹配)// 规范4:参数类型为int,对应XML中parameterType="int";返回值为Dept,对应resultType="dept"Dept selectDeptByNo(int deptno);
}
步骤 2:创建对应的 Mapper.xml(DeptMapper.xml)

src/main/resources/com/jr/mapper下创建 XML 文件(与接口同包同名),配置 SQL 并遵守规范:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd"><!-- 规范2:namespace等于Mapper接口全路径(com.jr.mapper.DeptMapper) -->
<mapper namespace="com.jr.mapper.DeptMapper"><!-- 规范3:id等于接口方法名(selectDept) --><!-- 规范4:resultType="dept"(单个实体类),对应接口返回值List<Dept> --><select id="selectDept" resultType="dept">select * from dept</select><!-- 规范3:id等于接口方法名(selectDeptByNo) --><!-- 规范4:parameterType="int"(接口方法参数类型),resultType="dept"(返回值类型) --><select id="selectDeptByNo" parameterType="int" resultType="dept">select * from dept where deptno = #{deptno}</select>
</mapper>
步骤 3:配置SqlMapConfig.xmlmappers标签

使用 “扫描包” 方式加载 Mapper 接口(企业推荐):

<configuration><properties resource="jdbc.properties"/><settings><setting name="mapUnderscoreToCamelCase" value="true"/></settings><typeAliases><package name="com.jr.pojo"/> <!-- 扫描实体类,生成别名 --></typeAliases><environments default="development"><!-- 数据源配置... --></environments><!-- 规范:扫描Mapper接口所在包,自动关联XML --><mappers><package name="com.jr.mapper"/></mappers>
</configuration>
步骤 4:编写测试类,通过代理对象调用方法

通过SqlSession.getMapper(接口.class)获取 MyBatis 自动生成的代理对象,直接调用接口方法:

import com.jr.mapper.DeptMapper;
import com.jr.pojo.Dept;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;
import java.io.InputStream;
import java.util.List;public class DeptMapperTest {private SqlSessionFactory factory;// 测试前初始化SqlSessionFactory(只执行一次)@Beforepublic void setUp() throws Exception {InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");factory = new SqlSessionFactoryBuilder().build(is);}// 测试查询所有部门@Testpublic void testSelectDept() {SqlSession session = null;try {session = factory.openSession();// 获取Mapper代理对象(MyBatis自动生成,无需手动new实现类)DeptMapper deptMapper = session.getMapper(DeptMapper.class);// 直接调用接口方法,底层自动执行SQLList<Dept> depts = deptMapper.selectDept();for (Dept dept : depts) {System.out.println(dept);}} finally {// 确保关闭会话if (session != null) {session.close();}}}// 测试根据部门编号查询@Testpublic void testSelectDeptByNo() {SqlSession session = null;try {session = factory.openSession();DeptMapper deptMapper = session.getMapper(DeptMapper.class);// 传入参数,调用方法Dept dept = deptMapper.selectDeptByNo(10);System.out.println(dept); // 输出:Dept{deptno=10, dname='ACCOUNTING', loc='NEW YORK'}} finally {if (session != null) {session.close();}}}
}
代理开发的优势总结:
  1. 无模板代码:无需写 Dao 实现类,MyBatis 自动生成代理对象;
  2. SQL ID 无硬编码:通过接口方法名关联 SQL,编译期可检查错误;
  3. 类型安全:接口方法的参数与返回值类型明确,编译期可发现类型错误;
  4. 符合面向接口编程:符合企业级开发规范,便于团队协作与后期维护。

四、总结与下一步预告

本篇博客我们深入 MyBatis 的核心:

  1. 理解了 MyBatis 的三层架构与核心类,知道 SQL 是如何从 “调用” 到 “执行” 的;
  2. 掌握了全局配置文件SqlMapConfig.xml的 5 个核心标签,能应对企业级项目的配置需求;
  3. 学会了 Mapper 代理开发规范,摆脱了原始 Dao 开发的冗余与不安全,实现了 “接口 + XML” 的简洁开发。

第三篇预告:MyBatis 的 “高级特性”—— 动态 SQL(灵活处理多条件查询)、关联查询(一对一 / 一对多)、查询缓存(一级 / 二级缓存优化性能),这些是解决复杂业务场景的关键,也是面试高频考点。跟着系列博客一步步深入,你会发现 MyBatis 的强大与灵活,真正做到 “知其然,更知其所以然”。


文章转载自:

http://wJ9gWVG9.wfpmt.cn
http://MJavn3XR.wfpmt.cn
http://lT9Y5eRX.wfpmt.cn
http://fvEChIQ2.wfpmt.cn
http://KuA2mkCr.wfpmt.cn
http://nHIqhVDd.wfpmt.cn
http://dqa46xg4.wfpmt.cn
http://EfY7U1ry.wfpmt.cn
http://tFJRWskz.wfpmt.cn
http://MnI70WQm.wfpmt.cn
http://HivWemmW.wfpmt.cn
http://faTVqRwW.wfpmt.cn
http://QBCmxp4j.wfpmt.cn
http://7F3hrlO0.wfpmt.cn
http://sx13eBUz.wfpmt.cn
http://zzyZST1o.wfpmt.cn
http://3ViMRy75.wfpmt.cn
http://A2HfCcaY.wfpmt.cn
http://eKA27LXB.wfpmt.cn
http://jkYOyuGb.wfpmt.cn
http://VbdGUtTz.wfpmt.cn
http://yoskgeuu.wfpmt.cn
http://Ix30ZQH0.wfpmt.cn
http://DNQD6KU0.wfpmt.cn
http://xaBBSPmi.wfpmt.cn
http://7PurBQP7.wfpmt.cn
http://of5p4kZx.wfpmt.cn
http://G5xfvMMg.wfpmt.cn
http://xgSPH7MW.wfpmt.cn
http://6ejSijAc.wfpmt.cn
http://www.dtcms.com/a/383781.html

相关文章:

  • Ubuntu 虚拟机设置双向复制粘贴
  • Lombok添加了依赖缺没有生效
  • 嵌入式开发中的keil常见错误与警告解决方案(部分)
  • ES5 和 ES6 类的实现
  • 设计模式-装饰器模式详解
  • 对AQS的详解
  • 实验-基本ACL
  • 开始 ComfyUI 的 AI 绘图之旅-SDXL文生图和图生图(全网首发,官网都没有更新)(十四)
  • Java可用打印数组方法5中+常用变量转字符串方法
  • ssh远程连接服务器到vscode上“连接失败”
  • SpringBoot -原理篇
  • 设计模式——结构型模式
  • I.MX6ULL时钟(clock)与定时器(EPITGPT)
  • STM32_06_Systick定时器
  • 用 Java 学会 Protocol Buffers从 0 到 1 的完整实战
  • 237.删除链表中的节点
  • 【Vue2手录14】导航守卫
  • Qt如何读写xml文件,几种方式对比,读写xml的Demo工程
  • 子网划分专项训练-1,eNSP实验,vlan/dhcp,IP规划
  • 云原生改造实战:Spring Boot 应用的 Kubernetes 迁移全指南
  • 看门狗的驱动原理
  • [论文阅读] 人工智能 + 软件工程 | 大语言模型驱动的多来源漏洞影响库识别研究解析
  • 【前缀和+哈希表】P3131 [USACO16JAN] Subsequences Summing to Sevens S
  • 05.【Linux系统编程】进程(进程概念、进程状态(注意僵尸和孤儿)、进程优先级、进程切换和调度)
  • 【从零开始java学习|小结】记录学习和编程中的问题
  • 图像拼接案例,抠图案例
  • 分层解耦讲解
  • 安装Hadoop中遇到的一些问题和解决
  • 音视频-色域
  • 返利软件的分布式缓存架构:Redis集群在高并发场景下的优化策略