mybatis-spring整合总结04_Using an SqlSession

Using an SqlSession

在Mybatis中SqlSessionFactory负责创建SqlSession,一旦创建成功,就可以用SqlSession实例来执行映射语句,commit,rollback,close等方法。但当使用Mybatis-Spring时beans将会注入一个线程安全的SqlSession并通过Spring的事务管理自动commit,rollback,close。

由于没有必要直接使用SqlSession,大多数情况下由MapperFactoryBean把mappers注入到beans中。

SqlSessionTemplate
SqlSessionTemplate是MyBatis-Spring的核心类,它负责管理Mybatis的SqlSessions,调用Mybatis的SQL方法和翻译异常。SqlSessionTemplate基于线程安全而且可以被多个DAO共享。
当调用SQL方法(包括getMapper()返回的接口实现类),SqlSessionTemplate将会保证这个SqlSession和Spring事务相联系。并且SqlSessionTemplate管理着session的生命周期,包括commit,rollback,close
SqlSessionTemplate实现了SqlSession接口,目的是替代代码中任何地方出现的SqlSession。
SqlSessionTemplate可以通过一个类型为SqlSessionFactory的构造参数来初始化:
<
Java代码 复制代码  收藏代码
  1. bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">   
  2. <constructor-arg index="0" ref="sqlSessionFactory" />   
  3. </bean>  
   将该sqlSession注入到的类:
Java代码 复制代码  收藏代码
  1. public class UserDaoImpl implements UserDao {   
  2. private SqlSession sqlSession;   
  3. public void setSqlSession(SqlSession sqlSession) {   
  4. this.sqlSession = sqlSession;   
  5.     }   
  6. public User getUser(String userId) {   
  7. return (User) sqlSession.selectOne("org.mybatis.spring.sample.mapper.UserMapper.getUser", userId);   
  8.     }   
  9. }  
public class UserDaoImpl implements UserDao {
private SqlSession sqlSession;
public void setSqlSession(SqlSession sqlSession) {
this.sqlSession = sqlSession;
	}
public User getUser(String userId) {
return (User) sqlSession.selectOne("org.mybatis.spring.sample.mapper.UserMapper.getUser", userId);
	}
}

配置文件:
Java代码 复制代码  收藏代码
  1. <bean id="userDao" class="org.mybatis.spring.sample.dao.UserDaoImpl">   
  2. <property name="sqlSession" ref="sqlSession" />   
  3. </bean>  

另外,也可以通过实现SqlSessionDaoSupport来获取SqlSessionTemplate(推荐):
Java代码 复制代码  收藏代码
  1. public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao {   
  2. public User getUser(String userId) {   
  3. return (User) getSqlSession()   
  4. .selectOne("org.mybatis.spring.sample.mapper.UserMapper.getUser", userId);   
  5.     }   
  6. }  
对应的配置文件:
Java代码 复制代码  收藏代码
  1. <bean id="userMapper" class="org.mybatis.spring.sample.mapper.UserDaoImpl">   
  2. <property name="sqlSessionFactory" ref="sqlSessionFactory" />   
  3. </bean>  
2025-04-01 13:49:35.484 TRACE [org.springframework.web.servlet.DispatcherServlet] - GET "/big-screen/get-time-period-traffic?deviceType=3", parameters={masked}, headers={masked} in DispatcherServlet 'dispatcherServlet' 2025-04-01 13:49:35.485 TRACE [o.s.w.s.m.m.a.RequestMappingHandlerMapping] - Mapped to com.syzn.dv.biz.bigscreen.northbound.controller.BigScreenController#getTimePeriodTraffic(BigScreenCommonReq) 2025-04-01 13:49:35.512 TRACE [org.springframework.web.method.HandlerMethod] - Arguments: [BigScreenCommonReq(direction=null, deviceType=3, startDate=null, endDate=null)] 2025-04-01 13:49:35.530 DEBUG [org.mybatis.spring.SqlSessionUtils] - Creating a new SqlSession 2025-04-01 13:49:35.537 DEBUG [org.mybatis.spring.SqlSessionUtils] - SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3c31fc7a] was not registered for synchronization because synchronization is not active 2025-04-01 13:49:35.558 DEBUG [org.mybatis.spring.SqlSessionUtils] - Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3c31fc7a] 2025-04-01 13:49:35.560 DEBUG [o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver] - Using @ExceptionHandler com.syzn.dv.config.GlobalExceptionHandler#customErrorHandler(RuntimeException) 2025-04-01 13:49:35.560 TRACE [org.springframework.web.method.HandlerMethod] - Arguments: [org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.binding.BindingException: Parameter 'device_no' not found. Available parameters are [startTime, endTime, deviceNo, param3, param1, param2]] org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.binding.BindingException: Parameter 'device_no' not found. Available parameters are [startTime, endTime, deviceNo, param3, param1, param2] at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:96) at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:4
04-02
<think>嗯,用户遇到了MyBatis的BindingException,提示Parameter 'device_no' not found,但可用的参数是[startTime, endTime, deviceNo]。我需要帮他解决这个问题。 首先,我应该回想一下常见的MyBatis参数绑定问题。根据之前的引用,比如引用[4]提到,缺少@Param注解可能导致参数名不匹配。用户可能没有在Mapper接口的方法参数前添加@Param注解,导致MyBatis无法正确识别参数名称。 接下来,检查参数命名是否一致。用户提到的错误中的参数是'device_no',但可用参数里有deviceNo。这可能是因为在Mapper接口中参数名为deviceNo,而在XML中使用了device_no。MyBatis默认会使用参数的实际名称,但如果没有使用@Param,参数可能会被命名为param1、param2等,或者如果编译时启用了-parameters选项,才会保留实际名称。如果用户没有使用@Param,并且参数名在接口中是deviceNo,但在XML中使用#{device_no},就会导致名称不匹配。 另外,用户可能在使用foreach标签时,collection属性指定不正确。比如引用[5]中提到,当传入一个列表时,需要正确指定collection的名称,可能需要使用@Param来明确指定集合的名称。 可能的解决步骤包括: 1. 在Mapper接口的方法参数前添加@Param("deviceNo"),确保XML中的占位符名称与之一致。 2. 检查XML文件中所有使用到该参数的地方,是否都使用#{deviceNo}而不是#{device_no},因为下划线和驼峰命名可能不匹配。 3. 如果是集合参数,确保foreach标签的collection属性正确指向参数名称,如使用@Param("deviceNos")并在XML中写collection="deviceNos"。 此外,用户可能需要检查是否在MyBatis配置中启用了useActualParamName,这可能会影响参数名的解析。如果启用了,参数名会被保留,但如果有多个参数,还是建议使用@Param来明确指定。 还要提醒用户检查是否有拼写错误,比如deviceNo和device_no的大小写或下划线是否一致。MyBatis对参数名称是严格区分的,特别是在使用不同的命名风格时容易出错。 最后,如果用户使用的是旧版本的MyBatis,可能需要特别注意参数绑定的方式,或者是否有其他配置问题。建议用户提供相关代码片段,以便更准确地诊断问题。</think>### MyBatis参数绑定异常解决方案 **错误分析**:`Parameter 'device_no' not found`表明MyBatis在映射参数时找不到指定名称的参数。根据引用内容,该异常通常由以下原因导致: 1. 参数未添加`@Param`注解导致名称不匹配[^4] 2. XML中参数名与接口参数名不一致(如`device_no` vs `deviceNo`)[^5] 3. 集合参数未正确使用`collection`属性[^5] 4. 参数命名风格不一致(驼峰命名与下划线)[^3] **解决方案**: 1. **添加@Param注解** ```java // Mapper接口方法修改前 List<Device> selectDevices(Date startTime, Date endTime, String deviceNo); // 修改后(添加@Param) List<Device> selectDevices(@Param("startTime") Date startTime, @Param("endTime") Date endTime, @Param("device_no") String deviceNo); ``` 2. **保持命名一致性** ```xml <!-- XML映射文件修改前 --> <where> device_no = #{device_no} </where> <!-- 修改后(保持接口参数名与XML一致) --> <where> device_no = #{deviceNo} <!-- 或保持接口参数名为device_no --> </where> ``` 3. **集合参数处理** ```xml <foreach item="item" collection="deviceNos" open="(" separator="," close=")"> #{item} </foreach> ``` **注意事项**: - 单个参数也需要添加`@Param`注解 - 参数名严格区分大小写和下划线[^3] - 建议开启`-parameters`编译参数保留参数名
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值