mapper代理开发,一样的套路:
mapper.java
public interface UserMapper {
// 根据id查询一个user
public User findUserById(int id);
}
mapper.xml
<mapper namespace="com.ddd.ssm.mapper.UserMapper">
<!-- 在映射文件中配置很多sql语句 -->
<!-- 通过select执行查询
id:用来表示文件中的sql,将sql语句封装到mappedstatement对象中,所以id其实是statement的id
parameterType:指定输入参数类型,id是int型
#{}表示一个占位符
#{id}表示id是接受的输入参数,名字是id,如果输入参数是简单类型,#{}中的参数名可以任意,可以是value或者其他名称
resultType:结果返回类型所映射的类,是单条记录所映射的对象类型 -->
<!-- 通过id查询用户 -->
<select id="findUserById" parameterType="int"
resultType="User">
SELECT * FROM USER WHERE id=#{id}
</select>
</mapper>
重点来了,之前我们是手动需要sqlSession来getMapper加载,生成的mapper代理实现,现在我们让spring帮我们实现这个mapper代理,在spring中配置代理:
MapperFactoryBean会根据mapper接口生成代理对象
<!-- mapper配置
MapperFactoryBean:根据mapper接口生成代理对象
-->
<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<!--mapperInterface指定mapper接口-->
<property name="mapperInterface" value="com.ddd.ssm.mapper.UserMapper"/>
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
测试代码:
package com.ddd.ssm.mapper;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.ddd.ssm.pojo.User;
import com.ddd.ssm.pojo.UserCustom;
public class UserMapperTest {
// 在setUp()方法中得到spring容器
private ApplicationContext applicationContext;
@Before
public void setUp() throws Exception {
applicationContext = new ClassPathXmlApplicationContext("classpath:spring/applicationContext.xml");
}
@Test
public void testFindUserById() {
UserMapper userMapper=(UserMapper) applicationContext.getBean("userMapper");
User u=userMapper.findUserById(6);
System.out.println(u);
}
}
结果:
Preparing: SELECT * FROM USER WHERE id=?
2017-07-19 16:04:43,876 [main] [com.ddd.ssm.mapper.UserMapper.findUserById]-[DEBUG] ==> Parameters: 6(Integer)
2017-07-19 16:04:43,900 [main] [com.ddd.ssm.mapper.UserMapper.findUserById]-[DEBUG] <== Total: 1
2017-07-19 16:04:43,901 [main] [org.mybatis.spring.SqlSessionUtils]-[DEBUG] Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@245f0324]
2017-07-19 16:04:43,901 [main] [org.springframework.jdbc.datasource.DataSourceUtils]-[DEBUG] Returning JDBC Connection to DataSource
User [id=6, username=大张伟, sex=男, birthday=Mon Jul 17 00:00:00 CST 2017, address=广州佛山, ordersList=null]
问题:
这样如果有很多mapper的话我们将需要配置很多mapper的bean,太麻烦了。
解决:
从mapper包中扫描mapper接口,自动生成代理对象,并且在spring容器中注入。
实现:
使用MapperScannerConfigurer来批量扫描mapper接口,而此时我们原先sqlMapConfig.xml中的扫描就不需要了可以去掉了
<!-- mapper批量扫描,从mapper包中扫描出mapper接口,自动创建代理对象并且在spring容器中注册
遵循规范:将mapper.java和mapper.xml映射文件名称保持一致,且在一个目录 中
自动扫描出来的mapper的bean的id为mapper类名(首字母小写)
-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 指定扫描的包名
如果扫描多个包,每个包中间使用半角逗号分隔
-->
<property name="basePackage" value="com.ddd.ssm.mapper"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>
测试结果和上面一样,只是这样我们如果有了更多的mapper接口,无需一一在spring里面配置,使用扫描的方式会更加方便。