mybatis与spring的使用中,对于mybatis映射的创建,除了(一)里面提到的使用MapperScannerConfigurer方法,(二)里面直接使用sqlSession配置,还有第三种配置。MyBatis-Spring提供了一个动态代理的实现:MapperFactoryBean。这个类可以直接注入数据映射器接口到你的service层bean中。当使用映射器时,如调用自己编写的DAO一样调用它们就可以了,而不需要编写任何DAO实现的代码,MyBatis-Spring将会自动创建代理。
例如,我在实验中配置如下:
<bean id="userDao" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="com.cstor.network.service.UserDao" />
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
<bean id="userService" class="com.cstor.network.serviceImpl.UserServiceImpl">
<property name="userDao" ref="userDao"/>
</bean>
如果映射文件和映射类不在同一个目录之下,则需要使用mapperLocations进行配置,我的程序中,spring与映射相关的主要配置如下:
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mapperLocations" value="classpath*:com/cstor/network/dao/*.xml" />
</bean>
<bean id="userDao" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="com.cstor.network.service.UserDao" />
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
<bean id="userService" class="com.cstor.network.serviceImpl.UserServiceImpl">
<property name="userDao" ref="userDao"/>
</bean>
<bean id="userAction" class="com.cstor.network.action.UserAction" scope="prototype">
<property name="userService" ref="userService"/>
</bean>
启动tomcat之后,系统正常,进行页面操作时,页面抛出异常:
java.lang.IllegalArgumentException: Mapped Statements collection does not contain value for com.cstor.network.service.UserDao.queryUsersorg.apache.ibatis.session.Configuration$StrictMap.get(Configuration.java:672)org.apache.ibatis.session.Configuration.getMappedStatement(Configuration.java:507)org.apache.ibatis.session.Configuration.getMappedStatement(Configuration.java:500)org.apache.ibatis.binding.MapperMethod.setupCommandType(MapperMethod.java:240)org.apache.ibatis.binding.MapperMethod.<init>(MapperMethod.java:71)org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:39)$Proxy6.queryUsers(Unknown Source)com.cstor.network.serviceImpl.UserServiceImpl.queryAllUsers(UserServiceImpl.java:24)com.cstor.network.action.UserAction.login(UserAction.java:27)sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
这个异常的主要原因之一是mybatis的映射XML文件namespace不正确,经查看,我的配置如下:
<mapper namespace="/">
<resultMap id="userResultMap" type="com.cstor.network.bean.User">
<result property="id" column="ID"/>
<result property="username" column="USERNAME"/>
<result property="password" column="PASSWORD"/>
<result property="email" column="EMAIL"/>
</resultMap>
<!-- Select with no parameters using the result map for Account class. -->
<select id="queryUsers" resultMap="userResultMap">
select * from user
</select>
</mapper>
这样的配置,如果不适用mybatis的代理,而是直接使用sqlSession,自己编写Dao方法,是没有问题,但使用MapperFactoryBean代理,该映射文件的命名空间就必须与映射文件对应的映射类com.cstor.network.service.UserDao对应,将命名空间更改为:
<mapper namespace="com.cstor.network.service.UserDao">
<resultMap id="userResultMap" type="com.cstor.network.bean.User">
<result property="id" column="ID"/>
<result property="username" column="USERNAME"/>
<result property="password" column="PASSWORD"/>
<result property="email" column="EMAIL"/>
</resultMap>
<!-- Select with no parameters using the result map for Account class. -->
<select id="queryUsers" resultMap="userResultMap">
select * from user
</select>
</mapper>
此时,重启tomcat,再次在页面查询,结果能正常查出,系统正常运行。