# MyBatis 常用异常类总结表
| 类别 | 类名 | 包名 | 是否受检 | 主要用途/场景 | 继承关系 | 触发时机 |
|------|------|------|----------|---------------|----------|----------|
| **核心异常** | `PersistenceException` | org.apache.ibatis.exceptions | 否 | MyBatis所有异常的基类 | `RuntimeException` | MyBatis框架通用异常基类 |
| | `IbatisException` | org.apache.ibatis.exceptions | 否 | 旧版本异常基类(已弃用) | `RuntimeException` | 旧版本MyBatis异常 |
| **配置异常** | `BuilderException` | org.apache.ibatis.builder | 否 | 构建器异常 | `PersistenceException` | SQL映射构建、配置解析错误 |
| | `ParsingException` | org.apache.ibatis.parsing | 否 | 解析异常 | `PersistenceException` | XML/注解配置解析失败 |
| | `TypeException` | org.apache.ibatis.type | 否 | 类型处理异常 | `PersistenceException` | 类型处理器注册、转换失败 |
| | `BindingException` | org.apache.ibatis.binding | 否 | 绑定异常 | `PersistenceException` | Mapper接口与XML绑定失败 |
| | `ReflectionException` | org.apache.ibatis.reflection | 否 | 反射异常 | `PersistenceException` | 反射操作失败、属性访问异常 |
| | `TooManyResultsException` | org.apache.ibatis.exceptions | 否 | 查询结果过多异常 | `PersistenceException` | 查询返回多个结果但期望单个 |
| **SQL执行异常** | `SqlSessionException` | org.apache.ibatis.exceptions | 否 | SQL会话异常 | `PersistenceException` | SqlSession操作失败、事务异常 |
| | `ExecutorException` | org.apache.ibatis.executor | 否 | 执行器异常 | `PersistenceException` | SQL执行器错误、批处理失败 |
| | `BatchExecutorException` | org.apache.ibatis.executor | 否 | 批处理异常 | `ExecutorException` | 批处理操作失败 |
| | `StatementHandlerException` | org.apache.ibatis.executor.statement | 否 | 语句处理器异常 | `PersistenceException` | Statement/PreparedStatement处理错误 |
| | `ResultSetHandlerException` | org.apache.ibatis.executor.resultset | 否 | 结果集处理器异常 | `PersistenceException` | 结果集映射、处理错误 |
| | `ParameterHandlerException` | org.apache.ibatis.executor.parameter | 否 | 参数处理器异常 | `PersistenceException` | SQL参数处理、绑定失败 |
| **事务异常** | `TransactionException` | org.apache.ibatis.transaction | 否 | 事务异常 | `PersistenceException` | 事务管理、提交/回滚失败 |
| | `NestedTransactionException` | org.apache.ibatis.transaction | 否 | 嵌套事务异常 | `TransactionException` | 嵌套事务不支持或错误 |
| **缓存异常** | `CacheException` | org.apache.ibatis.cache | 否 | 缓存异常 | `PersistenceException` | 缓存操作失败、序列化错误 |
| | `SerializationException` | org.apache.ibatis.cache | 否 | 序列化异常 | `CacheException` | 缓存对象序列化/反序列化失败 |
| **插件异常** | `PluginException` | org.apache.ibatis.plugin | 否 | 插件异常 | `PersistenceException` | 拦截器插件执行失败 |
| | `InterceptorException` | org.apache.ibatis.plugin | 否 | 拦截器异常 | `PluginException` | 拦截器配置或执行错误 |
| **脚本异常** | `ScriptingException` | org.apache.ibatis.scripting | 否 | 脚本异常 | `PersistenceException` | 动态SQL脚本解析失败 |
| | `ExpressionEvaluatorException` | org.apache.ibatis.scripting | 否 | 表达式求值异常 | `ScriptingException` | OGNL/MVEL表达式求值错误 |
| **数据源异常** | `DataSourceException` | org.apache.ibatis.datasource | 否 | 数据源异常 | `PersistenceException` | 数据源获取连接失败 |
| **日志异常** | `LogException` | org.apache.ibatis.logging | 否 | 日志异常 | `PersistenceException` | 日志框架初始化失败 |
| **IO异常** | `IOException` | java.io | 是 | IO异常(MyBatis包装) | `Exception` | 配置文件读取、资源加载失败 |
| **资源异常** | `ResourceLoadException` | org.apache.ibatis.io | 否 | 资源加载异常 | `PersistenceException` | 类路径资源加载失败 |
| **XML解析异常** | `XMLParseException` | org.apache.ibatis.parsing | 否 | XML解析异常 | `ParsingException` | XML配置文件解析错误 |
| **映射异常** | `ResultMapException` | org.apache.ibatis.mapping | 否 | 结果映射异常 | `PersistenceException` | 结果集到对象映射失败 |
| | `InvalidResultMapException` | org.apache.ibatis.mapping | 否 | 无效结果映射异常 | `ResultMapException` | 结果映射配置错误 |
| **注解异常** | `AnnotationException` | org.apache.ibatis.annotations | 否 | 注解异常 | `PersistenceException` | 注解配置错误、重复注解 |
| **会话异常** | `SessionException` | org.apache.ibatis.session | 否 | 会话异常 | `PersistenceException` | SqlSession状态异常 |
| | `SqlSessionClosedException` | org.apache.ibatis.session | 否 | 会话关闭异常 | `SessionException` | 使用已关闭的SqlSession |
| **工具类** | `ExceptionFactory` | org.apache.ibatis.exceptions | - | 异常工厂类 | - | 异常包装和创建工具 |
## MyBatis 异常分类说明
### 1. **核心异常类**
- **`PersistenceException`**: MyBatis所有异常的基类,所有自定义异常都应继承此类
- **`IbatisException`**: 旧版本异常基类,新版本已弃用,建议使用`PersistenceException`
### 2. **配置异常**
- **`BuilderException`**: 配置构建时异常,如XML配置错误、映射文件格式问题
- **`TypeException`**: 类型处理器注册失败、Java类型与JDBC类型不匹配
- **`BindingException`**: Mapper接口与XML映射文件绑定失败,方法找不到对应的SQL语句
### 3. **SQL执行异常**
- **`TooManyResultsException`**: 查询返回多个结果但期望单个结果时抛出
- **`ExecutorException`**: SQL执行器异常,包括简单执行器、重用执行器、批处理执行器
- **`BatchExecutorException`**: 批处理操作失败时抛出
### 4. **事务异常**
- **`TransactionException`**: 事务管理异常,包括JDBC事务、Managed事务等
- **`NestedTransactionException`**: 嵌套事务相关异常
### 5. **常用异常处理示例**
```java
// 1. 查询单个结果但返回多个的处理
try {
User user = sqlSession.selectOne("com.example.mapper.UserMapper.selectById", 1);
} catch (TooManyResultsException e) {
log.error("查询到多个结果但期望单个: {}", e.getMessage());
// 改用查询列表
List<User> users = sqlSession.selectList("com.example.mapper.UserMapper.selectById", 1);
return users.isEmpty() ? null : users.get(0);
}
// 2. 处理Mapper绑定异常
try {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
mapper.selectById(1);
} catch (BindingException e) {
log.error("Mapper绑定失败: {}", e.getMessage());
// 检查XML映射文件是否存在或SQL语句是否正确
if (e.getMessage().contains("does not contain value")) {
log.error("请检查XML文件中SQL语句的id是否正确");
}
}
// 3. 处理类型转换异常
try {
// 执行查询
sqlSession.selectList("com.example.mapper.UserMapper.selectAll");
} catch (TypeException e) {
log.error("类型处理失败: {}", e.getMessage());
// 检查实体类字段类型与数据库字段类型是否匹配
// 或注册自定义类型处理器
}
// 4. 处理SQL执行异常
try {
sqlSession.insert("com.example.mapper.UserMapper.insert", user);
sqlSession.commit();
} catch (ExecutorException e) {
log.error("SQL执行失败: {}", e.getMessage());
sqlSession.rollback();
// 根据具体错误类型处理
if (e.getCause() instanceof SQLIntegrityConstraintViolationException) {
throw new BusinessException("数据完整性约束错误");
}
}
```
### 6. **MyBatis全局异常处理**
```java
@RestControllerAdvice
public class MyBatisExceptionHandler {
@ExceptionHandler(TooManyResultsException.class)
public Result<Void> handleTooManyResultsException(TooManyResultsException e) {
log.warn("查询结果过多: {}", e.getMessage());
return Result.fail("查询到多个结果,请优化查询条件");
}
@ExceptionHandler(BindingException.class)
public Result<Void> handleBindingException(BindingException e) {
log.error("Mapper绑定异常: {}", e.getMessage());
return Result.fail("数据映射配置错误,请联系管理员");
}
@ExceptionHandler(PersistenceException.class)
public Result<Void> handlePersistenceException(PersistenceException e) {
log.error("MyBatis持久化异常: {}", e.getMessage(), e);
// 根据不同子类异常处理
if (e instanceof ExecutorException) {
return Result.fail("数据库操作失败,请稍后重试");
} else if (e instanceof TransactionException) {
return Result.fail("事务处理异常,请检查数据一致性");
}
return Result.fail("系统数据处理异常");
}
@ExceptionHandler(SQLException.class)
public Result<Void> handleSQLException(SQLException e) {
log.error("数据库SQL异常: {}", e.getMessage(), e);
// 处理常见的SQL状态码
int errorCode = e.getErrorCode();
String sqlState = e.getSQLState();
if ("23000".equals(sqlState) || errorCode == 1062) {
return Result.fail("数据已存在,请勿重复添加");
} else if ("22001".equals(sqlState)) {
return Result.fail("数据长度超出限制");
} else if ("28000".equals(sqlState)) {
return Result.fail("数据库连接权限不足");
}
return Result.fail("数据库操作失败");
}
}
```
### 7. **MyBatis异常处理最佳实践**
```java
public class UserService {
@Autowired
private SqlSessionFactory sqlSessionFactory;
public User getUserById(Long id) {
try (SqlSession sqlSession = sqlSessionFactory.openSession()) {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
return mapper.selectById(id);
} catch (TooManyResultsException e) {
// 记录日志并返回null或抛出业务异常
log.warn("用户ID:{} 查询到多个结果", id);
throw new BusinessException("用户数据异常");
} catch (BindingException e) {
// 检查Mapper配置
log.error("UserMapper配置错误", e);
throw new SystemException("系统配置错误");
} catch (PersistenceException e) {
// 其他MyBatis异常
log.error("查询用户失败", e);
throw new SystemException("数据库操作失败");
}
}
public void batchInsertUsers(List<User> users) {
try (SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH)) {
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
for (User user : users) {
mapper.insert(user);
}
sqlSession.commit();
} catch (BatchExecutorException e) {
log.error("批处理插入失败", e);
throw new BusinessException("批量操作失败");
} catch (TransactionException e) {
log.error("事务提交失败", e);
throw new SystemException("事务处理异常");
}
}
}
```
### 8. **MyBatis与Spring整合的异常处理**
```java
@Repository
public class UserDaoImpl implements UserDao {
@Autowired
private SqlSessionTemplate sqlSessionTemplate;
@Override
@Transactional(rollbackFor = Exception.class)
public int insertUser(User user) {
try {
UserMapper mapper = sqlSessionTemplate.getMapper(UserMapper.class);
return mapper.insert(user);
} catch (DataAccessException e) {
// Spring会将MyBatis异常包装为DataAccessException
log.error("插入用户失败", e);
// 获取根本原因
Throwable cause = e.getCause();
if (cause instanceof PersistenceException) {
// 处理MyBatis原生异常
handleMyBatisException((PersistenceException) cause);
}
throw new BusinessException("保存用户失败");
}
}
private void handleMyBatisException(PersistenceException e) {
if (e instanceof TooManyResultsException) {
// 处理查询结果过多
} else if (e instanceof ExecutorException) {
// 处理执行器异常
}
}
}
```
## MyBatis异常处理总结
1. **异常继承体系**:所有MyBatis异常都继承自`PersistenceException`,属于运行时异常
2. **异常分类清晰**:按功能模块分类,便于定位问题
3. **与Spring整合**:Spring会将MyBatis异常包装为`DataAccessException`
4. **实际开发建议**:
- 对`TooManyResultsException`、`BindingException`等常见异常进行专门处理
- 使用try-with-resources确保SqlSession正确关闭
- 在事务操作中注意异常回滚
- 结合具体业务场景定义业务异常
通过合理处理MyBatis异常,可以提高系统的健壮性和可维护性。
- 环境配置
- window怎么配置java环境变量?
- SQL学习
- 字段类型
- 1、 所有可声明的字段类型
- 2、常用的可声明的字段类型
- 创建表和表内字段
- 1、整个创建表语句
- 2、设置id主键
- 3、设置业务主键,唯一索引
- 4、设置业务字段
- 5、普通索引
- 6、唯一索引与普通索引的区别
- 7、表的引擎、字符集、排序规则和注释的设置
- Java基础语法
- 数据类型
- Java中的数据类型
- LocalDate
- 常用的数据类型
- Java 常用数据类型方法
- Java中数组、list、Map、HashMap
- 如何用Map来优化那些复杂的“双重 for 循环”查询?
- Java 8 中steam()操作流
- Java中HashMap和JSON
- Java中的JSONObject
- 工具类
- Java 常用工具类
- Arrays工具类
- Java 时间工具类
- 泛型
- Java中泛型概念
- Java中的泛型容器
- 泛型参数与函数参数的区别
- 推断出泛型实参
- Lambda表达式
- 数据分层
- 异常处理
- Java8 异常处理类总结表
- MyBatis-Plus 常用异常类总结表
- Java高级特性
- Maven
- jib-maven-plugin
- 什么是Spring Boot 的 parent pom?
- maven中各个生命周期的含义
- Spring Boot
- maven与spring boot 的关系
- Java中的连接池
- Spring JDBC
- Spring JDBC的概念
- JdbcTemplate常用的方法
- Spring中Bean的概念
- Spring中的抽象,通俗解释一下
- Spring中的事物
- Spring中的事物,通俗解释一下
- Spring中的事物抽象,常见的有哪些,列举一下
- Spring中常用的事物场景有哪些,列举一下
- Spring事务管理有哪些注解?
- Spring中使用事物处理订单的案例,列举说明一下
- Spring中声明式事务、分布式事务以及编程式事务的区别,列举一下
- 配置文件
- application-properties配置文件
- Spring Boot 的启动
- spring boot项目如何启动?
- 列举一下Spring Boot的启动过程
- SpringApplication.run方法
- Spring Boot 启动时有哪些接口?
- CommandLineRunner
- Spring Boot 的常用注解
- 系统注解
- 表格:系统注解
- @Override
- @Deprecated
- @SuppressWarnnings
- 使用在类名上的注解
- 表格:使用在类名上的注解
- @RestController
- @Controller
- @Service
- @Repository
- @Component
- @Configuration
- @Resource
- @Autowired
- @RequestMapping
- @GetMapping
- @PostMapping
- @Transactional
- @Qualifier
- 使用在方法上的注解
- 表格:使用在方法上的注解
- @RequestBody
- @PathVariable
- @Bean
- @ResponseBody
- @PreAuthorize
- 其他常用注解
- 表格:其他常用注解
- @EnableAutoConfiguration
- @SpringBootApplication
- @EnableScheduling
- @EnableAsync
- @ComponentScan
- @Aspec
- @ControllerAdvice
- @ExceptionHandler
- @Value
- @ConfigurationProperties
- @EnableConfigurationProperties
- @MapperScan
- @ApiOperation
- @Produces
- Validator验证的常用注解
- spring IoC容器
- Spring IoC容器依赖注入实现方式
- 常用依赖
- RESTEasy
- resteasy简介
- RESTEasy框架(依赖)的功能和常用注解
- MyBatis
- 简介
- paginationInterceptor
- @TableName
- @TableId
- @Param
- MyBatis-Plus
- MyBatis-Plus简介
- MyBatis-Plus的工具类
- Mybatis-Plus扩展的工具类和方法
- MyBatis-Plus中最常用的工具类方法
- MyBatis-Plus 中最常用的 4 大核心工具类
- Wrapper条件构造器
- Wrapper条件构造器详解
- Wrapper条件构造器eq等方法的参数说明
- LambdaQueryWrapper与QueryWrapper
- 日期格式是否必须转换
- Lombok
- Lombok作用详解
- @Data
- @Slf4j
- @Builder
- @EqualsAndHashCode
- @Accessors
- Jackson
- Jackson简介
- @JsonFormat
- Jackson高效地在 HashMap 和 JSON 字符串之间进行相互转换
- Hutool
- Hutool简介
- hutool依赖常用的方法
- fastjson2
- fastjson2简介
- UrlBasedCorsConfigurationSource
- 生态相关
- JBoss 社区
- 支付系统
- 1. 初始化mysql数据库流程
- 2. 初始化redis数据库的流程
- 3. 初始化rabbitmq服务
- 环球置业
- 1.模块目录结构分析
- 2. DTO(数据传输层)的核心作用
- 3. VO(视图对象层)
- 4. VO(视图对象层)和 DTO 数据传输层 的区别
