在实际的项目开发中,Spring与MyBatis都是整合在一起使用的。要实现MyBatis和Spring的整合,除了需要这两个框架的JAR包,还需要其它的JAR包来配合使用,整合时所需准备的JAR包具体如下:
Spring框架所需要准备的JAR包包括4个核心模块JAR,AOP开发使用的JAR,JDBC和事务的JAR,具体如下图所示:
MyBatis框架所需要准备的JAR包包括MyBatis核心包以及其解压文件夹中lib目录中的所有JAR,具体如下图所示:
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=UTF-8
jdbc.username=root
jdbc.password=root
jdbc.maxTotal=30
jdbc.maxIdle=10
jdbc.initialSize=5
除了配置连接数据库的基本4项外,还配置了数据库连接池的最大连接数(maxTotal),最大空闲连接数(maxIdle)以及初始化连接数(initialSize)
<?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}" />
<!--连接数据库的url -->
<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>
<!-- 事务管理器,依赖于数据源 -->
<!-- 事务的作用特点 -->
<!-- 避免了每次对数据操作都要先获得Session实例来启动事务/提交/回滚事务还有繁琐的Try /Catch操作 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<!--开启事务注解 -->
<tx:annotation-driven transaction-manager="transactionManager" />
<!-- 使用MyBatis工厂与Spring进行整合 -->
<!-- 用于构建SqlSessionFactory类 -->
<!-- 通过sqlSessionFactory里面的两个参数, Spring的ioc容器就会在初始化id为sqlSessionFactory
的Bean时解析MyBatis的配置文件,并将数据源一同保存在Spring中的Bean中 -->
<!--配置MyBatis工厂 -->
<bean id="sqlSessionFactory"
class="org.mybatis.spring.SqlSessionFactoryBean">
<!--注入数据源 -->
<property name="dataSource" ref="dataSource" />
<!--指定mybatis的核心配置文件位置 -->
<property name="configLocation" value="classpath:mybatis-config.xml" />
</bean>
<!-- Mapper代理开发(基于MapperScannerConfigurer) -->
<!-- 用于简化开发,自动扫描包下的接口文件 -->
<!-- Spring会自动通过包中的接口来生成映射器 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.lwz.mapper" />
</bean>
<!-- 开启扫描 -->
<context:component-scan base-package="com.lwz.service" />
</beans>
上述代码中,使用了class为org.mybatis.spring.mapper.MapperScannerConfigurer
的bean,MapperScannerConfigurer在使用的时候只需通过basePackage属性指定需要扫描的包即可,Spring会自动通过包中的接口来生成映射器
<?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.lwz.po" />
</typeAliases>
</configuration>
由于在Spring中已经配置了数据源信息,所以MyBatis的配置文件就不要再配置数据源信息了,而且使用了基于MapperScannerConfigurer的Mapper代理开发,所以无需再使用
元素指定Mapper文件位置,MapperScannerConfigurer实现了BeanDefinitionRegistryPostProcessor接口,如果MapperScannerConfigurer实现了该接口,那么说明在application初始化的时候该接口会被调用。
package com.lwz.po;
/**
* 客户持久化类
*/
public class Customer {
private Integer id; // 主键id
private String username; // 客户名称
private String jobs; // 职业
private String phone; // 电话
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getJobs() {
return jobs;
}
public void setJobs(String jobs) {
this.jobs = jobs;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
@Override
public String toString() {
return "Customer [id=" + id + ", username=" + username + ", jobs=" + jobs + ", phone=" + phone + "]";
}
}
<?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.lwz.po.CustomerMapper">
<!--根据id查询客户信息 -->
<select id="findCustomerById" parameterType="Integer" resultType="customer">
select * from t_customer where id = #{id}
</select>
</mapper>
package com.lwz.mapper;
import com.lwz.po.Customer;
public interface CustomerMapper {
// 通过id查询客户
public Customer findCustomerById(Integer id);
// 添加客户
public void addCustomer(Customer customer);
// 模糊查询
public Customer findCustomerByName(String str);
}
Mapper映射文件和其接口放在同一文件夹下,并且两者应满足一下条件:
1:Mapper接口的名称和对应的Mapper.xml映射文件的名称必须一样
2:Mapper.xml文件中的namespace与Mapper.xml接口的类路径相同(即接口文件和映射文件需要放在同一包中)
3:Mapper接口中的方法名和Mapper.xml中定义的每个执行语句的id相同
4:Mapper接口中的方法的输入参数类型要和Mapper.xml中定义的每个sql的parameterType的类型相同
5:Mapper接口方法中的输出参数类型要和Mapper.xml中定义的每个sql的resultType的类型相同
详细的Mapper接口编程请看MyBatis的Mapper接口编程方式
package com.lwz.test;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.lwz.dao.CustomerDao;
import com.lwz.mapper.CustomerMapper;
import com.lwz.po.Customer;
/**
* DAO测试类
*/
public class DaoTest {
// 用于测试Mapper接口方式的开发整合
@Test
public void findCustomerByIdMapperTest(){
ApplicationContext act = new ClassPathXmlApplicationContext("applicationContext.xml");
CustomerMapper customerMapper = act.getBean(CustomerMapper.class);
Customer customer = customerMapper.findCustomerById("王");
System.out.println(customer);
}
}
在测试类DaoTest中,编写测试方法findCustomerByIdMapperTest,通过调用映射文件中的SQL来测试整合是否成功
输出结果如下:
DEBUG [main] - ==> Preparing: select * from t_customer where id = ?
DEBUG [main] - ==> Parameters: 1(Integer)
DEBUG [main] - <== Total: 1
Customer [id=1, username=joy, jobs=doctor, phone=123456789]