Spring(14):使用MapperFactoryBean注入映射器

2018/1/1

根据上一篇文档(Spring(13):新增功能:超市订单的供应商表查询 and 根据供应商名称查询供应商信息--功能实现(上)),还有更加简洁的手法吗?

答:有的,Mybatis-Spring 提供了MapperFactoryBean, 能够以配置的方式生成映射器实现并注入给业务组件。前提是:仅仅使用SqlsessionTemplate执行基本的数据访问操作,不包含其它非Mybatis的工作,可以不必手工编码SqlsessionTemplate或者SqlSessionDaoSupport 来实现此类DAO。

 

【0】文件结构


图1


【1】在上一个案例基础上,删除ProviderMapperImpl.java,保留接口和SQL映射文件,然后在applicationContext-mybatis.xml 配置DAO,完整内容如下:

<?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>
    
	<!-- 配置DAO -->
	<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>
	
	<!-- 配置业务Bean ,构造器注入,一定要有带参构造函数-->
   	<bean id="providerService" class="com.smbms.service.ProviderServiceImpl">
   		<constructor-arg name="providerMapper" ref="providerMapper" ></constructor-arg>
   	</bean>
	
</beans>
解释:(1)配置DAO组件,class属性不是某个实现类,而是 MapperFactoryBean

(2)通过mapperInterface 属性指定了映射器(SQL映射接口文件),只能是接口类型,不能是某个实现类;

(3)MapperFactoryBean 是 SqlSessionDaoSupport 的子类,需要通过setSqlSessionFactory() 方法注入 SqlSessionFactory 实例,以创建SqlSessionTemplate。


【2】新建业务类接口 ProviderService.java 和实例 ProviderServiceImpl.java,注意 ProviderServiceImpl.java 直接将providerMapper属性调用了:

 ProviderService.java :

package com.smbms.service;

import java.util.List;

import com.smbms.entities.Provider;

public interface ProviderService {
	public List<Provider> findUsersWithConditions();
	public List<Provider> findUsersWithConditionsByAddress(String address);
}

  ProviderServiceImpl.java:

package com.smbms.service;

import java.util.List;

import com.smbms.dao.ProviderMapper;
import com.smbms.entities.Provider;

public class ProviderServiceImpl implements ProviderService{
	private ProviderMapper providerMapper;
	
	public ProviderServiceImpl() {}

	public ProviderServiceImpl(ProviderMapper providerMapper) {
		this.providerMapper = providerMapper;
	}

	@Override
	public List<Provider> findUsersWithConditions() {
		return providerMapper.providershow();
	}

	@Override
	public List<Provider> findUsersWithConditionsByAddress(String address) {
		return providerMapper.providershowbyAddress(address);
	}
	

}

【3】编写单元测试 ProviderServiceImplTest.java:

package com.smbms.service;

import java.util.List;

import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.smbms.entities.Provider;

public class ProviderServiceImplTest {

	@Test
	public void test() {
		System.out.println("start..");
		System.out.println("----------------1----------------");
		ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext-mybatis.xml");
		ProviderService providerService = (ProviderService) ctx.getBean("providerService");
		List<Provider> providers = providerService.findUsersWithConditions();
		for(Provider p: providers){
			p.toString();
		}
		System.out.println("---------------2----------------");
		String address = "Maoming";
		System.out.println("------------显示供应商地点为茂名的结果------------");
		providers = providerService.findUsersWithConditionsByAddress(address);
		for(Provider p: providers){
			p.toString();
		}
	}

}

【4】输出结果:

DEBUG 01-01 21:43:30,475 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 21:43:30,483 ==>  Preparing: select * from smbms_provider   (JakartaCommonsLoggingImpl.java:54) 
DEBUG 01-01 21:43:30,532 ==> Parameters:   (JakartaCommonsLoggingImpl.java:54) 
DEBUG 01-01 21:43:31,998 <==    Columns: id, proAddress, proFax, createdBy, creatiomDate, modifyBy, modifyDate  (JakartaCommonsLoggingImpl.java:59) 
DEBUG 01-01 21:43:31,999 <==        Row: 1, Maoming, 0213-11, 110, 2017-12-31 00:00:00.0, null, null  (JakartaCommonsLoggingImpl.java:59) 
DEBUG 01-01 21:43:33,482 <==        Row: 2, Gaozhou, 0213-12, 110, 2017-12-31 18:32:43.0, null, null  (JakartaCommonsLoggingImpl.java:59) 
DEBUG 01-01 21:43:33,484 <==      Total: 2  (JakartaCommonsLoggingImpl.java:54) 
DEBUG 01-01 21:43:33,544 Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@36bc55de]  (JakartaCommonsLoggingImpl.java:54) 
DEBUG 01-01 21:43:33,545 Returning JDBC Connection to DataSource  (DataSourceUtils.java:327) 
---------------2----------------
------------显示供应商地点为茂名的结果------------
DEBUG 01-01 21:43:33,546 Creating a new SqlSession  (JakartaCommonsLoggingImpl.java:54) 
DEBUG 01-01 21:43:33,546 SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@757277dc] was not registered for synchronization because synchronization is not active  (JakartaCommonsLoggingImpl.java:54) 
DEBUG 01-01 21:43:33,546 Fetching JDBC Connection from DataSource  (DataSourceUtils.java:110) 
DEBUG 01-01 21:43:33,547 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 21:43:33,548 ==>  Preparing: select * from smbms_provider where proAddress like CONCAT('%',?,'%')   (JakartaCommonsLoggingImpl.java:54) 
DEBUG 01-01 21:43:33,548 ==> Parameters: Maoming(String)  (JakartaCommonsLoggingImpl.java:54) 
DEBUG 01-01 21:43:33,746 <==    Columns: id, proAddress, proFax, createdBy, creatiomDate, modifyBy, modifyDate  (JakartaCommonsLoggingImpl.java:59) 
DEBUG 01-01 21:43:33,747 <==        Row: 1, Maoming, 0213-11, 110, 2017-12-31 00:00:00.0, null, null  (JakartaCommonsLoggingImpl.java:59) 
DEBUG 01-01 21:43:33,748 <==      Total: 1  (JakartaCommonsLoggingImpl.java:54) 
DEBUG 01-01 21:43:33,748 Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@757277dc]  (JakartaCommonsLoggingImpl.java:54) 
DEBUG 01-01 21:43:33,748 Returning JDBC Connection to DataSource  (DataSourceUtils.java:327) 


同理,可以对User也采取相应的动作,目的去查询User的信息:

【5】在applicationContext-mybatis.xml 配置user-DAO,添加的内容如下:

	<!-- 配置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="userService" class="com.smbms.service.UserServiceImpl">
		<constructor-arg name="userMapper" ref="userMapper"></constructor-arg>
	</bean>


【6】新建业务类接口 UserService.java 和实例 UserServiceImpl.java,注意 UserServiceImpl.java 直接将UserMapper属性调用了:

UserService.java:

package com.smbms.service;

import java.util.List;

import com.smbms.entities.User;

public interface UserService {
	public List<User> findUsersWithConditions();
	public User findUsersWithConditionsById(Integer id);
}

User ServiceImpl.java:

package com.smbms.service;

import java.util.List;

import com.smbms.dao.UserMapper;
import com.smbms.entities.User;

public class UserServiceImpl implements UserService{
	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;
	}
	
	
}

【7】新建单元测试 UserServiceImplTest.java : 

package com.smbms.service;

import java.util.List;

import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.smbms.entities.User;

public class UserServiceImplTest {

	@Test
	public void test() {
		System.out.println("start..");
		System.out.println("----------------1----------------");
		ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext-mybatis.xml");
		UserService userService = (UserService) ctx.getBean("userService");
		List<User> users = userService.findUsersWithConditions();
		for(User u: users){
			u.toString();
		}
		System.out.println("---------------2----------------");
		String address = "Maoming";
		System.out.println("------------显示用户ID为1的结果------------");
		User user = userService.findUsersWithConditionsById(1);
		user.toString();
	}

}

【8】输出结果:

DEBUG 01-01 22:31:30,662 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 22:31:30,678 ==>  Preparing: select * from smbms_user   (JakartaCommonsLoggingImpl.java:54) 
DEBUG 01-01 22:31:30,736 ==> Parameters:   (JakartaCommonsLoggingImpl.java:54) 
DEBUG 01-01 22:31:30,790 <==    Columns: id, userCode, userName, userPassword, gender, birthday, phone, address, userRole, createBy, createDate, modifyBy, modifyDate  (JakartaCommonsLoggingImpl.java:59) 
DEBUG 01-01 22:31:30,792 <==        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 22:31:30,797 <==        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 22:31:30,799 <==        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 22:31:30,800 <==        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 22:31:30,802 <==        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 22:31:30,803 <==      Total: 5  (JakartaCommonsLoggingImpl.java:54) 
DEBUG 01-01 22:31:30,806 Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@2a65fe7c]  (JakartaCommonsLoggingImpl.java:54) 
DEBUG 01-01 22:31:30,807 Returning JDBC Connection to DataSource  (DataSourceUtils.java:327) 
---------------2----------------
------------显示用户ID为1的结果------------
DEBUG 01-01 22:31:30,808 Creating a new SqlSession  (JakartaCommonsLoggingImpl.java:54) 
DEBUG 01-01 22:31:30,808 SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6236eb5f] was not registered for synchronization because synchronization is not active  (JakartaCommonsLoggingImpl.java:54) 
DEBUG 01-01 22:31:30,808 Fetching JDBC Connection from DataSource  (DataSourceUtils.java:110) 
DEBUG 01-01 22:31:30,809 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 22:31:30,810 ==>  Preparing: select * from smbms_user where id = ?   (JakartaCommonsLoggingImpl.java:54) 
DEBUG 01-01 22:31:30,810 ==> Parameters: 1(Integer)  (JakartaCommonsLoggingImpl.java:54) 
DEBUG 01-01 22:31:30,811 <==    Columns: id, userCode, userName, userPassword, gender, birthday, phone, address, userRole, createBy, createDate, modifyBy, modifyDate  (JakartaCommonsLoggingImpl.java:59) 
DEBUG 01-01 22:31:30,812 <==        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 22:31:30,813 <==      Total: 1  (JakartaCommonsLoggingImpl.java:54) 
DEBUG 01-01 22:31:30,814 Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6236eb5f]  (JakartaCommonsLoggingImpl.java:54) 
DEBUG 01-01 22:31:30,814 Returning JDBC Connection to DataSource  (DataSourceUtils.java:327) 

看一下完整的Spring配置文件吧!

<?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>
    
	<!-- 配置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>
</beans>

解释:provider写了一个mapper,user写了一个mapper,随着业务的增加,在DAO和业务Bean上花费的代码和管理会越来越多,有没有更好的办法简化DAO模块的编码呢?

答案是肯定的,那就是使用MapperScannerConfigurer注入映射器。相关内容在我的下一篇博文:Spring(15):使用MapperScannerConfigurer注入映射器


【9】工程说明.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查询,照壶画瓢;

以上,是 Spring(14):使用MapperFactoryBean注入映射器 的全部内容。




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值