2018/1/1
承接上文(Spring(14):使用MapperFactoryBean注入映射器),随着业务的增加,在DAO和业务Bean上花费的代码和管理会越来越多,有没有更好的办法简化DAO模块的编码呢?上一篇博文的例子,user和provider的映射文件都是在同一包里面,因此使用 MapperScannerConfigurer 去扫描指定包中的接口并将它们直接注册为 MapperFactoryBean。
【1】 在applicationContext-mybatis.xml 中添加MapperScannerConfigurer 的配置内容:
<!-- 配置MapperScannerConfigurer -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.smbms.dao"></property>
</bean>
【2】 这样一来,可以将原先对MapperBean的注册删除,删除内容如下:
<!-- 配置DAO-provider -->
<bean id="providerMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="com.smbms.dao.ProviderMapper"></property>
<property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
</bean>
<!-- 配置DAO-user -->
<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="com.smbms.dao.UserMapper"></property>
<property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
</bean>
<!-- 配置provider业务Bean ,构造器注入,一定要有带参构造函数-->
<bean id="providerService" class="com.smbms.service.ProviderServiceImpl">
<constructor-arg name="providerMapper" ref="providerMapper" ></constructor-arg>
</bean>
<!-- 配置provider业务Bean ,构造器注入,一定要有带参构造函数-->
<bean id="userService" class="com.smbms.service.UserServiceImpl">
<constructor-arg name="userMapper" ref="userMapper"></constructor-arg>
</bean>
完整配置文件内容:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">
<!-- 数据源配置 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url">
<value><![CDATA[jdbc:mysql://127.0.0.1:3306/test?
useUnicode=true&characterEncoding=utf-8]]></value>
</property>
<property name="username" value="root"></property>
<property name="password" value=""></property>
</bean>
<!-- SqlSessionFactoryBean 配置 -->
<bean id="sqlSessionFactory"
class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 引用数据源组件 -->
<property name="dataSource" ref="dataSource"></property>
<!-- 引用Mybatis配置文件的配置 -->
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
</bean>
<!-- 配置provider业务Bean ,构造器注入,一定要有带参构造函数-->
<bean id="providerService" class="com.smbms.service.ProviderServiceImpl">
<constructor-arg name="providerMapper" ref="providerMapper" ></constructor-arg>
</bean>
<!-- 配置provider业务Bean ,构造器注入,一定要有带参构造函数-->
<bean id="userService" class="com.smbms.service.UserServiceImpl">
<constructor-arg name="userMapper" ref="userMapper"></constructor-arg>
</bean>
<!-- 配置MapperScannerConfigurer -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.smbms.dao"></property>
</bean>
</beans>
解释:测试得到正确结果,但是常用的业务类配置方法不是这个!见步骤【4】
【4】 但是业务类的注入配置不能删除,这里先介绍方法2--注解配置业务类,先删除业务类的bean配置内容,加入context-component自动扫描,然后配置文件内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">
<!-- 数据源配置 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
<property name="url">
<value><![CDATA[jdbc:mysql://127.0.0.1:3306/test?
useUnicode=true&characterEncoding=utf-8]]></value>
</property>
<property name="username" value="root"></property>
<property name="password" value=""></property>
</bean>
<!-- SqlSessionFactoryBean 配置 -->
<bean id="sqlSessionFactory"
class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 引用数据源组件 -->
<property name="dataSource" ref="dataSource"></property>
<!-- 引用Mybatis配置文件的配置 -->
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
</bean>
<!-- 配置MapperScannerConfigurer -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.smbms.dao"></property>
</bean>
<context:component-scan base-package="com.smbms.service"></context:component-scan>
</beans>
解释:(1)别忘了引入context命名空间!!
在 UserServiceImpl.java 做以下修改:
package com.smbms.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.smbms.dao.UserMapper;
import com.smbms.entities.User;
@Service("userService")
public class UserServiceImpl implements UserService{
//或者@Resource
@Autowired
private UserMapper userMapper;
@Override
public List<User> findUsersWithConditions() {
return userMapper.Usershow();
}
@Override
public User findUsersWithConditionsById(Integer id) {
return userMapper.UsershowById(id);
}
public UserServiceImpl() {}
public UserServiceImpl(UserMapper userMapper) {
this.userMapper = userMapper;
}
}
解释:(1)使用@Autowired 或 @Resource 注解实现对业务组件的依赖注入,以简化业务组件的配置。
【5】输出结果:
DEBUG 01-01 23:09:53,928 Fetching JDBC Connection from DataSource (DataSourceUtils.java:110)
DEBUG 01-01 23:09:54,244 JDBC Connection [jdbc:mysql://127.0.0.1:3306/test?
useUnicode=true&characterEncoding=utf-8, UserName=root@localhost, MySQL Connector Java] will not be managed by Spring (JakartaCommonsLoggingImpl.java:54)
DEBUG 01-01 23:09:54,250 ==> Preparing: select * from smbms_user (JakartaCommonsLoggingImpl.java:54)
DEBUG 01-01 23:09:54,290 ==> Parameters: (JakartaCommonsLoggingImpl.java:54)
DEBUG 01-01 23:09:54,343 <== Columns: id, userCode, userName, userPassword, gender, birthday, phone, address, userRole, createBy, createDate, modifyBy, modifyDate (JakartaCommonsLoggingImpl.java:59)
DEBUG 01-01 23:09:54,345 <== Row: 1, test01, mmb02, 9876543210, 2, 1991-12-29, 0000, maoming, 110, 1, 2017-12-17 10:50:04.0, null, null (JakartaCommonsLoggingImpl.java:59)
DEBUG 01-01 23:09:54,357 <== Row: 2, test01, mmb02, scua, 2, 1991-12-29, 0000, maoming, 110, 1, 2017-12-17 10:56:48.0, null, null (JakartaCommonsLoggingImpl.java:59)
DEBUG 01-01 23:09:54,358 <== Row: 3, test01, mmb02, scua, 2, 1991-12-29, 0000, maoming, 110, 1, 2017-12-17 10:58:46.0, null, null (JakartaCommonsLoggingImpl.java:59)
DEBUG 01-01 23:09:54,359 <== Row: 4, test01, mmb02, scua, 2, 1991-12-29, 0000, maoming, 110, 1, 2017-12-17 11:01:42.0, null, null (JakartaCommonsLoggingImpl.java:59)
DEBUG 01-01 23:09:54,360 <== Row: 5, test01, mmb02, scua, 2, 1991-12-29, 0000, maoming, 110, 1, 2017-12-17 11:03:05.0, null, null (JakartaCommonsLoggingImpl.java:59)
DEBUG 01-01 23:09:54,361 <== Total: 5 (JakartaCommonsLoggingImpl.java:54)
DEBUG 01-01 23:09:54,364 Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@4a668b6e] (JakartaCommonsLoggingImpl.java:54)
DEBUG 01-01 23:09:54,365 Returning JDBC Connection to DataSource (DataSourceUtils.java:327)
---------------2----------------
------------显示用户ID为1的结果------------
DEBUG 01-01 23:09:54,366 Creating a new SqlSession (JakartaCommonsLoggingImpl.java:54)
DEBUG 01-01 23:09:54,366 SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3cebbb30] was not registered for synchronization because synchronization is not active (JakartaCommonsLoggingImpl.java:54)
DEBUG 01-01 23:09:54,366 Fetching JDBC Connection from DataSource (DataSourceUtils.java:110)
DEBUG 01-01 23:09:54,368 JDBC Connection [jdbc:mysql://127.0.0.1:3306/test?
useUnicode=true&characterEncoding=utf-8, UserName=root@localhost, MySQL Connector Java] will not be managed by Spring (JakartaCommonsLoggingImpl.java:54)
DEBUG 01-01 23:09:54,368 ==> Preparing: select * from smbms_user where id = ? (JakartaCommonsLoggingImpl.java:54)
DEBUG 01-01 23:09:54,368 ==> Parameters: 1(Integer) (JakartaCommonsLoggingImpl.java:54)
DEBUG 01-01 23:09:54,370 <== Columns: id, userCode, userName, userPassword, gender, birthday, phone, address, userRole, createBy, createDate, modifyBy, modifyDate (JakartaCommonsLoggingImpl.java:59)
DEBUG 01-01 23:09:54,370 <== Row: 1, test01, mmb02, 9876543210, 2, 1991-12-29, 0000, maoming, 110, 1, 2017-12-17 10:50:04.0, null, null (JakartaCommonsLoggingImpl.java:59)
DEBUG 01-01 23:09:54,372 <== Total: 1 (JakartaCommonsLoggingImpl.java:54)
DEBUG 01-01 23:09:54,373 Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3cebbb30] (JakartaCommonsLoggingImpl.java:54)
DEBUG 01-01 23:09:54,373 Returning JDBC Connection to DataSource (DataSourceUtils.java:327)
【6】工程说明.txt:
(1)这是Mybatis和Spring整合练习的工程;
(2)实际使用有3个包:dao、entities、service;
(3)Mybatis配置文件内容很简洁,Spring完成大部分配置管理;
(4)通过SQLSessionTemplate的实现类对数据库进行操作;
(5)配置DAO组件并进入SqlSessionTemplate实例;
(6)配置业务Bean并注入DAO实例 ;
(7)完成的功能是:查询provider的列表,模糊查询供应商信息;
(8)与smbms05MybatisSpring的区别:去掉了实现类ProviderMapperImpl;仅仅保留ProviderMapper
接口和相关SQL映射文件,通过MapperFactoryBean注入给业务组件。
(9)此外,也新增了一个User查询,照壶画瓢;
(10)smbms06是使用MapperFactoryBean注入映射器,
而smbms07是更加方便的使用MapperScannerConfigurer注入映射器。
以上,是 Spring(15):使用MapperScannerConfigurer注入映射器 的全部内容。