MyBatis快速入门第七讲——MyBatis整合Spring

本文将手把手教你MyBatis如何整合Spring,这儿,笔者使用的MyBatis是MyBatis3.2.7这个版本,Spring是Spring4.2.4这个版本,读者只要学会这两个版本的框架整合之后,其他版本之间的整合就一通百通了。

整合思路

MyBatis整合Spring的思路如下:

  1. SqlSessionFactory对象应该放到Spring容器中作为单例存在;
  2. 传统dao的开发方式中,应该从Spring容器中获得SqlSession对象;
  3. Mapper代理形式中,应该从Spring容器中直接获得Mapper的代理对象;
  4. 数据库的连接以及数据库连接池事务管理都要交给Spring容器来完成。

整合需要的jar包

MyBatis整合Spring所需的jar包如下:

  1. Spring的jar包;
  2. MyBatis的jar包;
  3. Spring与MyBatis的整合包,即mybatis-spring-1.2.2.jar
  4. MySQL数据库驱动jar包;
  5. 数据库连接池的jar包。

我整理出来的MyBatis与Spring整合的全部jar包(包括SpringMVC)有下面这些,一共31个jar包。
MyBatis快速入门第七讲——MyBatis整合Spring_第1张图片

整合的步骤

接下来,我将按照下面整合的步骤来整合MyBatis与Spring:

  1. 第一步:创建一个普通的Java工程;
  2. 第二步:导入jar包(上面所提到的jar包);
  3. 第三步:编写MyBatis的配置文件(即SqlMapConfig.xml);
  4. 第四步:编写Spring的配置文件,在该配置文件中,可能需要进行如下配置:
    • 数据库连接及连接池
    • 事务管理(暂时可以不配置)
    • SqlSessionFactory对象需要配置到Spring容器中
    • Mapeer代理对象或者是dao层实现类需要配置到Spring容器中
  5. 第五步:编写dao层或者mapper.xml映射文件;
  6. 第六步:测试。

按照上面的步骤来整合MyBatis与Spring的话,一般来讲,MyBatis的核心配置文件(即SqlMapConfig.xml)的内容就应该是下面这个样子了。



<configuration>
	
	<mappers>
		<mapper resource="mybatis/user.xml" />
	mappers>
configuration>

该核心配置文件处于工程中的如下图所示的位置。
MyBatis快速入门第七讲——MyBatis整合Spring_第2张图片
Spring核心配置文件(即application-context.xml)的内容就应该是下面这个样子。


<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
	http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">

   
   <context:property-placeholder location="classpath:jdbc.properties" />

	
	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
		destroy-method="close">
		<property name="driverClassName" value="${jdbc.driver}" />
		<property name="url" value="${jdbc.url}" />
		<property name="username" value="${jdbc.username}" />
		<property name="password" value="${jdbc.password}" />
		
		<property name="maxActive" value="10" />
		
		<property name="maxIdle" value="5" />
	bean>
	
	
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		
		<property name="dataSource" ref="dataSource">property>
		
		<property name="configLocation" value="classpath:SqlMapConfig.xml">property>
		
		<property name="typeAliasesPackage" value="com.meimeixia.mybatis.pojo">property>
	bean>
    
beans>

该核心配置文件处于工程中的如下图所示的位置。
MyBatis快速入门第七讲——MyBatis整合Spring_第3张图片
其中jdbc.properties配置文件中的内容如下所示:

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8
jdbc.username=root
jdbc.password=liayun

dao层的开发

MyBatis整合Spring之后,就要开发dao层了,dao层的开发共有两种实现方式:

  1. 传统dao层的开发方式;
  2. 使用Mapper代理形式开发方式,这种开发方式也可以分为两种,一种是为单个接口配置Mapper代理,一种是以扫描包形式配置Mapper代理。

接下来,我会依次讲解这两种实现方式。

传统dao层的开发方式

传统dao层的开发是使用接口+实现类的方式来完成的,dao层实现类需要继承SqlSessionDaoSupport类,就像下面这样:
MyBatis快速入门第七讲——MyBatis整合Spring_第4张图片
以上dao层实现类,即UserDaoImpl类的内容如下所示:

package com.meimeixia.mybatis.dao.impl;

import java.util.List;

import org.apache.ibatis.session.SqlSession;
import org.mybatis.spring.support.SqlSessionDaoSupport;

import com.meimeixia.mybatis.dao.UserDao;
import com.meimeixia.mybatis.pojo.User;

public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao {

	@Override
	public User getUserById(Integer id) {
		SqlSession sqlSession = super.getSqlSession();
		User user = sqlSession.selectOne("user.getUserById", id);
		/*
		 * 这里不能关闭SqlSession,记住千万不要释放资源,因为现在SqlSession由Spring来管理。
		 * 后续Spring就可以帮我们托管事务了,而托管事务就要使用到SqlSession。如果你手动关闭了
		 * SqlSession,那么就会抛出一个异常!
		 */
		//sqlSession.close();
		return user;
	}

	@Override
	public List<User> getUserByUserName(String userName) {
		SqlSession sqlSession = super.getSqlSession();
		List<User> list = sqlSession.selectList("user.getUserByUserName", userName);
		return list;
	}

	@Override
	public void insertUser(User user) {
		SqlSession sqlSession = super.getSqlSession();
		sqlSession.insert("user.insertUser", user);
	}

}

温馨提示:以上每个方法中不要手动关闭SqlSession,如果你手动关闭了,那么就会抛出一个如下的异常
在这里插入图片描述
然后,我们还需要把dao层实现类(即UserDaoImpl.java)配置到Spring容器中。


<bean class="com.meimeixia.mybatis.dao.impl.UserDaoImpl">
	
	<property name="sqlSessionFactory" ref="sqlSessionFactory" />
bean>

接着,我们就要进行测试了,针对UserDao接口编写一个UserDaoTest单元测试类,该单元测试类处于工程中的如下图所示的位置。
MyBatis快速入门第七讲——MyBatis整合Spring_第5张图片
以上单元测试类的内容如下所示:

package com.meimeixia.mybatis.test;

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.meimeixia.mybatis.dao.UserDao;
import com.meimeixia.mybatis.pojo.User;

public class UserDaoTest {
	
	private ApplicationContext applicationContext;
	
	@Before
	public void init() {
		applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
	}

	@Test
	public void testGetUserById() {
		UserDao userDao = applicationContext.getBean(UserDao.class);
		User user = userDao.getUserById(30);
		System.out.println(user);
	}

	@Test
	public void testGetUserByUserName() {
		fail("Not yet implemented");
	}

	@Test
	public void testInsertUser() {
		fail("Not yet implemented");
	}

}

运行以上testGetUserById方法,也有可能抛出如下异常:
MyBatis快速入门第七讲——MyBatis整合Spring_第6张图片
异常信息已用红框框出,怎么解决呢?聪明的小伙伴们肯定知道了,有可能你之前UserDaoImpl实现类中的getUserById方法是写成下面这样的。
MyBatis快速入门第七讲——MyBatis整合Spring_第7张图片
要解决该异常,只须将以上方法修改成下面这样。
MyBatis快速入门第七讲——MyBatis整合Spring_第8张图片
为什么要这样修改呢?我截图一张,你就应该明白了。
MyBatis快速入门第七讲——MyBatis整合Spring_第9张图片
讲完传统dao层的开发方式后,下面我来讲第二种实现方式,即使用Mapper代理形式开发dao层。

Mapper代理形式开发dao层

这种开发方式可以分为两种,第一种是为单个接口配置Mapper代理,第二种是以扫描包形式配置Mapper代理。下面我会对这两种开发方式加以详细阐述。

第一种方式:为单个接口配置Mapper代理

首先开发Mapper接口及相对应的mapper.xml映射文件,如下图所示。
MyBatis快速入门第七讲——MyBatis整合Spring_第10张图片
然后配置Mapper代理,即需要在applicationContext.xml配置文件中添加如下配置。



<bean id="baseMapper" class="org.mybatis.spring.mapper.MapperFactoryBean" abstract="true" lazy-init="true">
	
	<property name="sqlSessionFactory" ref="sqlSessionFactory" />
bean>

<bean parent="baseMapper">
	<property name="mapperInterface" value="com.meimeixia.mybatis.mapper.UserMapper" />
bean>

整体效果看起来就像下面这样:
MyBatis快速入门第七讲——MyBatis整合Spring_第11张图片
接着,我们就要进行测试了,针对UserMapper接口编写一个UserMapperTest单元测试类,该单元测试类位于工程的com.meimeixia.mybatis.test包中。

package com.meimeixia.mybatis.test;

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.meimeixia.mybatis.mapper.UserMapper;
import com.meimeixia.mybatis.pojo.User;

public class UserMapperTest {
	
	private ApplicationContext applicationContext;
	
	@Before
	public void init() {
		applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
	}

	@Test
	public void testGetUserById() {
		UserMapper userMapper = applicationContext.getBean(UserMapper.class);
		User user = userMapper.getUserById(30);
		System.out.println(user);
	}

	@Test
	public void testGetUserByUserName() {
		fail("Not yet implemented");
	}

	@Test
	public void testInsertUser() {
		fail("Not yet implemented");
	}

}

运行以上testGetUserById单元测试方法,你便可以看到Eclipse控制台打印出了如下内容。
MyBatis快速入门第七讲——MyBatis整合Spring_第12张图片

小结

使用Mapper代理形式的第一种方式开发dao层,在实际开发中显然不经常用,因为万一有很多很多Mapper接口需要配置其代理对象呢?所以接下来我就要讲使用Mapper代理形式的第二种方式开发dao层了,它在实际开发中就经常用到。

第二种方式:以扫描包形式配置Mapper代理

使用扫描包的形式配置Mapper代理来开发dao层,需要在applicationContext.xml配置文件中配置一个包扫描器,即在该文件中添加如下配置。


<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
	
	<property name="basePackage" value="com.meimeixia.mybatis.mapper" />
bean>

对于以上配置,我觉得有以下几点需要再次说明一下。

  1. 该包扫描器会自动去Spring容器中找你已经初始化好后的SqlSessionFactory,所以在此并不需要配置;
  2. 如果要扫描多个包,那么可以使用半角逗号进行分隔
  3. 使用扫描包的形式配置Mapper代理之后,每个Mapper代理对象的id就是其类名,且首字母小写

这样,整体效果看起来就像下面这样:
MyBatis快速入门第七讲——MyBatis整合Spring_第13张图片
并且如果在applicationContext.xml配置文件中配置了包扫描之后,那么在SqlMapConfig.xml配置文件中就不再需要以下配置了。


<mappers>
	<mapper resource="mybatis/user.xml" />
mappers>

也就是说SqlMapConfig.xml配置文件的内容为空即可,但是你不要想着它里面既然没有啥内容了,就把该文件删掉,就算是该文件的内容为空,它也必须存在,知道不!
MyBatis快速入门第七讲——MyBatis整合Spring_第14张图片
至此,MyBatis整合Spring我就已总结完了,觉得还算是蛮走心的。

你可能感兴趣的:(MyBatis快速入门第七讲——MyBatis整合Spring)