开发环境,jar包的引入
要实现 MyBatis Spring 的整合,很明显需要这两个框架的 JAR 包,但是只使用这两个框架中所提供的 JAR 包是不够的,还需要其他的 JAR 包来配合使用,整合时所需准备的 JAR 包真体如下:
- Spring框架所需的jar包:
Spring 框架所需要准备的JAR包共10个,其中包括:4个核心模块 JAR AOP 开发使用JAR JDBC 和事务的 JAR (其中核心容器依赖的 commons-Iogging JAR MyBatis框架的lib包中已经包含,所以这里不必再加入), - MyBatis所需的jar包:
MyBatis 框架所需要准备的JAR包共13个,其中包括核心包 mybatis-3.5.4jar 以及其解压文件夹中 lib目录中的所有 JAR , - MyBatis和Spring的中间jar包:
mybatis-spring-1.3.1.jar - 数据库驱动jar包:
- 数据源所需的jar包:
整合时所使用的是 DBCP 数据源,所以需要准备 DBCP 和连接池的 JAR 包,
整体如下图:
传统的DAO方式的开发整合
采用传统DAO开发方式进行 MyBatis+Spring 框架的整合时,我们需要编写 DAO接口以及接口的实现类,并且需要向DAO实现类中注入SqlSessionFactory,然后在方法体内通过 SqlSessionFactory 创建SqlSession,为此,我们可以使用 mybatis-spring 包中所提供的 SqlSessionTemplate 类或 SqlSessionDaoSupport 类来实现此功能,这两个类的描述如下:
SqlSessionTemplate
: mybatis-spring 的核心类,它负责管理 MyBatis SqlSession调用 MyBatis SQL方法 当调用SQL方法时,SqlSessionTemplate 将会保证使用的SqlSession和当前Spring 的事务是相关的,它还管理SqlSession的生命周期包含必要的关闭/提交和回滚操作。SqlSessionDaoSupport
: 是一个抽象支持类,它继承了DaoSupport 类,主要是作为DAO的基类来使用可以通过SqlSessionDaoSupport类的getSqlSession方法来获取所需的SqlSession。
实现持久层
在src 目录下,创建一个 com lzq.po 包,并在包中创建持久化类 Customer ,在类当中对变量进行封装以及重写toString方法。(这个实体类是数据库当中的一个表:)以下代码省略getset方法。
package com.lzq.po;
public class Customer {
private Integer id;
private String username;
private String jobs;
private String phone;
@Override
public String toString() {
return "Customer [id=" + id + ", username=" + username + ", jobs=" + jobs + ", phone=" + phone + "]";
}
}
在同一个包下创建映射文件 CustomerMapper.xml,在该文件中编写根据id 查询客户信息的映射语句,
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lzq.po.CustomerMapper">
<select id="findCustomerById" parameterType="Integer" resultType="Customer">
select * from t_customer where id = #{id}
</select>
</mapper>
实现DAO层
在 src 目录下,创建一个 com.lzq.dao 包,并在包中创建接口 CustomerDao ,在接口中编写一个通过 id 查询客户的方法 findCustomerByld,
package com.lzq.dao;
import com.lzq.po.Customer;
public interface CustomerDao {
public Customer findCustomerById(Integer id);
}
在 src 目录下,创建一个 com lzq.dao impl 包,并在包中创建 CustomerDao 接口的实现类 CustomerDaolmpl ,
package com.lzq.dao.impl;
import com.lzq.dao.CustomerDao;
import com.lzq.po.Customer;
import org.mybatis.spring.support.SqlSessionDaoSupport;
public class CustomerDaoImpl extends SqlSessionDaoSupport implements CustomerDao {
public Customer findCustomerById(Integer id) {
return this.getSqlSession().selectOne("com.lzq.po"+".CustomerMapper.findCustomerById",id);
}
}
在上述代码当中,CustomerDaolmpl类继承了SqlSessionDaoSupport 类,并实现了CustomerDao接口。其中,SqlSessionDaoSupport类在使用时需要一个SqlSessionFactory 或一个SqlSessionTemplate 对象,所以需 要通过Spring给SqlSessionDaoSupport 类的子类对象注入一个SqlSessionFactory 或SqlSessionTemplate。 这样,在子类中就能通过调用SqlSessionDaoSupport类的getSqlSession()方法来获取SqlSession对象,并使用SqlSession对象中的方法了。
在Spring 的配置文件 applicationContext. xml 中,编写实例化 CustomerDaolmpl 的配置,代码如下所示:applicationContext.xml文件
<?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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.3.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.3.xsd">
<!--读取db.properties -->
<context:property-placeholder
location="classpath:db.properties" />
<!-- 配置数据源 -->
<bean id="dataSource"
class="org.apache.commons.dbcp2.BasicDataSource">
<!--数据库驱动 -->
<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="maxTotal" value="${jdbc.maxTotal}" />
<property name="maxIdle" value="${jdbc.maxIdle}" />
<property name="initialSize" value="${jdbc.initialSize}" />
</bean>
<!-- 事务管理器,依赖于数据源 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!--开启事务注解 -->
<tx:annotation-driven
transaction-manager="transactionManager" />
<!--配置MyBatis工厂 -->
<bean id="sqlSessionFactory"
class="org.mybatis.spring.SqlSessionFactoryBean">
<!--注入数据源 -->
<property name="dataSource" ref="dataSource" />
<!--指定核心配置文件位置 -->
<property name="configLocation"
value="classpath:mybatis-config.xml" />
</bean>
<!--实例化Dao -->
<bean id="customerDao" class="com.lzq.dao.impl.CustomerDaoImpl">
<!-- 注入SqlSessionFactory对象实例 -->
<property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>
</beans>
其余代码实现
加入db.properties文件
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC
jdbc.username=root
jdbc.password=root
jdbc.maxTotal=30
jdbc.maxIdle=10
jdbc.initialSize=5
加入log4j.properties文件
# Global logging configuration
log4j.rootLogger=ERROR, stdout
# MyBatis logging configuration...
log4j.logger.com.lzq=DEBUG
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
以及在MyBatis.xml文件当中对其进行引入
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<typeAliases>
<package name="com.lzq.po" />
</typeAliases>
<mappers>
<mapper resource="com/lzq/po/CustomerMapper.xml" />
</mappers>
</configuration>
最后定义测试方法:
在src 目录下,创建一个 com.lzq.test 包,在包中创建测试类DaoTest ,并在类中编写测试方法 findCustomerByIdDaoTest();
//@Test
public void findCustomerByIdTest() {
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
CustomerDao cd = (CustomerDao) ac.getBean("customerDao");
Customer c = cd.findCustomerById(2);
System.out.println(c);
}
效果图如下:
在上述方法 ,我们采用的是根据容器中Bean id 来获取指定 Bean 的方式。还有另一种获取 Bean 的方式,即根据类的类型来获取 Bean 的实例,此种方式就是Spring 另一种获取Bean的方式,如果要采用这种方式,只需将部分代码替换:这样在获取 Bean 的实例时,就不再需要进行强制类型转换了
CustornerDao custornerDao = ac.getBean(CustornerDao.class);
Mapper接口方式的开发整合
在MyBatis+Spring的项目中,虽然使用传统的DAO开发方式可以实现所需功能,但是采用这种方式在实现类中会出现大量的重复代码,在方法中也需要指定映射文件中执行语句的id,并且不能保证编写时id的正确性(运行时才能知道)。为此,我们可以使用MyBatis提供的另外一种编程方式,即使用Mapper接口编程。
基于MapperFactoryBean的整合
MapperFactoryBean是MyBatis+Spring 团队提供的一个用于根据Mapper接口生成Mapper对象的类,该类在Spring配置文件中使用时可以配置以下参数。
- mapperlnterface:用于指定接口。
- SqlSessionFactory: 用于指定SqlSessionFactory。
- SqlSessionTemplate:用于指定SqlSessionTemplate。如果与SqlSessionFactory同时设定,则只会启用SqlSessionTemplate。
代码实现
在srC目录下,创建-个com.lzq.mapper包,然后在该包中创建CustomerMapper接口以及对应的映射文件.
CustomerMapper.java
package com.lzq.mapper;
import com.lzq.po.Customer;
public interface CustomerMapper {
public Customer findCustomerById(Integer id);
}
CustomerMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lzq.mapper.CustomerMapper">
<select id="findCustomerById" parameterType="Integer" resultType="Customer">
select * from t_customer where id = #{id}
</select>
</mapper>
在MyBatis 的配置文件中,引入新的映射文件,
<mapper resource="com/lzq/mapper/CustomerMapper.xml" />
在 Spring 的配置文件applicationContext.xml 中,创建一个 id customerMapper Bean ,
<!-- Mapper代理开发(基于MapperFactoryBean) -->
<bean id="customerMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="com.lzq.mapper.CustomerMapper" />
<property name="sqlSessionFactory" ref="sqlSessionFactory" /> </bean>
<!-- Mapper代理开发(基于MapperScannerConfigurer) -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.lzq.mapper" />
</bean>
测试代码和上面基于传统DAO开发大致相同:如下图所示:
基于MapperScannerConfigurer的整合
在实际的项目中,DAO层会包含很多接口,如果每一一个接口都像基于传统DAO中那样在Spring配置文件中配置,那么不但会增加工作量,还会使得Spring 配置文件非常臃肿。为此,MyBatis-Spring团队提供了一种自动扫描的形式来配置MyBatis中的映射器一-采用MapperScannerConfigurer类。
MapperScannerConfigurer类在Spring配置文件中使用时可以配置以下几个属性。
- basePackage:指定映射接口文件所在的包路径,当需要扫描多个包时可以使用分号或逗号作为分隔符。指定包路径后,会扫描该包及其子包中的所有文件。
- annotationClass: 指定了要扫描的注解名称,只有被注解标识的类才会被配置为映射器。
- sqlSessionFactoryBeanName:指定在Spring中定义的SqlSessionFactory的Bean名称。
- sqlSessionTemplateBeanName:指定在Spring中定义的SqlSessionTemplate的Bean名称。如果定义此属性,则sqlSessionFactoryBeanName将不起作用。
- markerInterface: 指定创建映射器的接口。
而MapperScannerConfigurer的使用非常简单,只需要在Spring的配置文件中编写如下代码:
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.lzq.mapper" />
</bean>
将原先的配置进行注释,加上基于MapperScannerConfigurer的配置,再一次运行测试代码即可。