mybatis在debug模式下延迟加载无效问题

本文详细解析了在使用MyBatis框架时遇到的懒加载功能失效问题,通过具体的代码示例展示了如何配置和使用懒加载,以及在调试过程中可能导致懒加载失效的常见原因。

首先是resultMap的定义 

<!-- 延迟加载的resultMap -->
	<resultMap type="sc.ustc.po.Orders" id="userOrderResult">
		<id column="id" property="id"/>
		<result column="user_id" property="userId"/>
		<result column="number" property="number"/>
		<result column="createtime" property="createtime"/>
		<result column="note" property="note"/>
		
		<association property="user" javaType="sc.ustc.po.User" 
			select="sc.ustc.mapper.Mapper.findUserById" column="user_id" fetchType="lazy">
		</association>
	</resultMap>

select标签

<select id="findUserOrderLazyLoadingResultMap" resultMap="userOrderResult">
		SELECT * from orders
</select>

mapper代理接口中方法定义:

public interface OrderMapperCustomer {
	
	public List<Orders> findUserOrderLazyLoadingResultMap()throws Exception;
	
}

测试代码:

@Test
public void testFindUserOrderLazyLoadingResultMap() throws Exception {
	SqlSession sqlSession=sf.openSession();

	OrderMapperCustomer omc=sqlSession.getMapper(OrderMapperCustomer.class);
	List<Orders> list=omc.findUserOrderLazyLoadingResultMap();

	for(Orders orders:list) {
		User user=orders.getUser();//这里会触发对user的加载
		System.out.println(user);
	}
}

​

测试代码断点设置在了for循环上,但是执行之后并没有起到延迟加载作用,如下图:

可以看到,代码运行到断点处时还没有执行getUser()方法,但是却执行了查询user的sql语句,也就是说懒加载失效了。。。

看了一下核心文件配置,懒加载也确实配置了,但是就是没有效果。

后来上网查阅资料才找到原因:原来在开启debug后,不能点开list信息,甚至不能把鼠标移到上面。否则在debug下会默认执行关联查询。

后来重试了一下,确实如此。

<think>嗯,用户遇到了MyBatis在Spring中的异常,具体是MyBatisSystemException和BuilderException。我需要先弄清楚这些异常通常是什么原因引起的。根据经验,MyBatisSystemException通常是MyBatis抛出的异常被Spring封装后的结果,而BuilderException可能和MyBatis的SQL映射文件中的表达式有关,比如OGNL表达式解析失败。 首先,用户提到的错误信息里有“Error evaluating expression”,这提示在动态SQL中使用了错误的表达式,比如条件判断中的变量名错误或者表达式语法不对。比如在<if test="username != null">中,如果“username”在参数中不存在,就会导致这个错误。 接下来,我需要考虑可能的原因。常见的包括:XML中的变量名与Java对象属性不匹配,参数未正确传递,动态SQL语法错误,或者MyBatis配置问题,比如未启用驼峰命名转换导致字段映射失败。 然后,用户可能需要检查他们的Mapper XML文件,特别是动态SQL部分,比如<if>、<choose>、<foreach>等标签中的test表达式是否正确。例如,使用#{}和${}的区别,或者参数是否为null。 另外,参数传递是否正确也是一个关键点。如果使用@Param注解或者在Spring中参数绑定不正确,可能会导致MyBatis不到对应的变量名,从而引发BuilderException。 还有MyBatis的配置,比如是否配置了<setting name="lazyLoadingEnabled" value="false"/>,或者是否启用了驼峰命名,这些都可能影响映射的正确性。 用户可能需要检查日志,查看具体的错误堆栈,定位到是哪一行XML或哪个方法调用导致的异常。例如,日志中可能会指出是哪个Mapper的哪个方法,以及具体的SQL片段,这样用户可以直接检查对应的代码。 此外,还需要考虑是否存在类型处理器的问题,比如Java对象中的属性类型和数据库字段类型不匹配,导致MyBatis无法正确转换,但这可能更多导致其他类型的异常,不过也不能完全排除。 还有可能的是,MyBatis的版本与Spring的版本不兼容,或者依赖冲突,导致某些功能异常。这时候需要检查pom.xml或build.gradle中的依赖版本是否符合官方推荐的组合。 总结下来,解决步骤可能包括:检查动态SQL表达式,确认变量名正确;检查参数传递是否正确;验证MyBatis配置;查看详细日志定位问题;确认依赖版本兼容性。如果用户提供了具体的代码片段或错误日志,可以更精准地诊断问题。</think>### MyBatisSystemException和BuilderException的解决方案分析 #### 一、异常原因定位 1. **BuilderException核心触发场景** - 动态SQL表达式解析失败(例如OGNL表达式错误) - XML映射文件中存在无效属性引用:$\\color{red}{如<if test="invalidField">}$ - 类型处理器不匹配或缺失 2. **MyBatisSystemException封装机制** 该异常是Spring对原生MyBatis异常的封装,常见触发场景: ```java // Spring通过SqlSessionTemplate捕获MyBatis异常 try { return sqlSession.selectOne(statement, parameter); } catch (Exception ex) { throw new MyBatisSystemException(ex); } ``` #### 二、具体解决步骤 ##### 步骤1:检查动态SQL表达式 *示例错误映射片段*: ```xml <select id="findUser"> SELECT * FROM users <where> <!-- 错误示例:status应为参数对象的属性 --> <if test="status != null"> AND account_status = #{status} </if> </where> </select> ``` 解决方法: 1. 确保表达式中的变量名与Java参数对象属性完全一致 2. 使用$\\color{green}{@Param}$注解明确参数名称: ```java List<User> findUser(@Param("status") String status); ``` ##### 步骤2:验证参数传递 常见错误场景: ```java // 错误示例:未使用@Param注解传递多个参数 List<User> findUsers(String name, Integer age); // 正确写法 List<User> findUsers(@Param("userName") String name, @Param("userAge") Integer age); ``` 对应的XML应使用: ```xml <if test="userName != null"> AND name = #{userName} </if> <if test="userAge != null"> AND age = #{userAge} </if> ``` ##### 步骤3:配置检查 在`mybatis-config.xml`中确保: ```xml <settings> <!-- 启用自动驼峰命名规则 --> <setting name="mapUnderscoreToCamelCase" value="true"/> <!-- 防止延迟加载导致的问题 --> <setting name="lazyLoadingEnabled" value="false"/> </settings> ``` ##### 步骤4:日志分析 在`log4j.properties`中开启调试日志: ```properties log4j.logger.org.mybatis=DEBUG log4j.logger.java.sql=DEBUG ``` 典型错误日志示例: ``` Error evaluating expression 'statu'. Cause: org.apache.ibatis.ognl.NoSuchPropertyException ``` #### 三、进阶验证方法 ```java // 单元测试时直接调用SQLSession验证 try (SqlSession session = sqlSessionFactory.openSession()) { UserMapper mapper = session.getMapper(UserMapper.class); mapper.findUser("active"); // 触发异常点 } ```
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值