9. Spring和Mybatis整合
9.1 创建工程
新建工程,导入所需jar包:
<dependencies>
<!-- mybatis核心包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.1</version>
</dependency>
<!-- mysql驱动包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.29</version>
</dependency>
<!-- junit测试包 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<!--日志包-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.1</version>
</dependency>
<!--spring数据库-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.11.RELEASE</version>
</dependency>
<!--aop-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>4.3.11.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.11.RELEASE</version>
</dependency>
<!--spring-mybatis整合包-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
</dependency>
<!--spring相关包-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.11.RELEASE</version>
</dependency>
</dependencies>
<!--配置资源文件扫描,否则Mapper-->
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
</resource>
</resources>
</build>
工程完整目录如下:
jdbc.properties文件存放数据库连接信息:
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/数据库?characterEncoding=utf-8
jdbc.username=用户名
jdbc.password=密码
log4j日志文件见1.6节
实体类Dept和Employee见1.3
映射文件DeptMapper.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.dao.DeptDAO">
<insert id="addDept" parameterType="Dept" keyProperty="id" useGeneratedKeys="true" >
insert into DEPT(NAME) values(#{name})
</insert>
</mapper>
接口DeptDAO
package com.dao;
import com.pojo.Dept;
public interface DeptDAO {
void addDept(Dept dept);
}
9.2 spring-mybatis整合
在spring与mybatis整合示例中,spring负责管理数据源、加载mybatis配置文件、mybatis的session和事务。
<?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"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd">
<!--spring管理数据源-->
<context:property-placeholder location="classpath:jdbc.properties" ignore-unresolvable="true"/>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
</beans>
mybatis的配置文件中不再写Mapper映射文件的配置:
<?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>
<typeAlias type="com.pojo.Dept" alias="Dept"/>
<typeAlias type="com.pojo.Employee" alias="Employee"/>
</typeAliases>
</configuration>
spring中加载mybatis的配置文件
<!--spring管理session工厂-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mapperLocations" value="classpath:com/dao/mapper/*.xml"/>
<property name="configLocation" value="classpath:mybatis-config.xml"/>
</bean>
省略mybatis配置文件的写法:
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="mapperLocations" value="classpath:dao/*.xml"/>
<property name="typeAliasesPackage" value="pojo"/>
<!--<property name="configLocation" value="classpath:mybatis-config.xml"/>-->
<property name="plugins">
<array>
<bean class="com.github.pagehelper.PageHelper">
<property name="properties">
<value>
dialect=mysql
reasonable=true
</value>
</property>
</bean>
</array>
</property>
</bean>
9.2.1 dao的基本整合
编写DeptDAO的实现类:
package com.dao.impl;
import com.dao.DeptDAO;
import com.pojo.Dept;
import org.mybatis.spring.support.SqlSessionDaoSupport;
public class DeptDAOImpl extends SqlSessionDaoSupport implements DeptDAO{
@Override
public void addDept(Dept dept) {
super.getSqlSession().insert("com.dao.DeptDAO.addDept", dept);
}
}
DAO继承了spring的SqlSessionDaoSupport,SqlSessionDaoSupport中注入sessionFactory,负责管理session。
声明DeptDAO的bean
<bean id="deptDAO" class="com.dao.impl.DeptDAOImpl">
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
测试代码:
public class SpringTest {
ApplicationContext ac = new ClassPathXmlApplicationContext("spring-mybatis.xml");
@Test
public void testDeptDAO() {
DeptDAO deptDAO = (DeptDAO) ac.getBean("deptDAO");
Dept dept = new Dept();
dept.setName("abcdefg");
deptDAO.addDept(dept);
}
}
9.2.2 面向接口的整合
mybatis的dao可以没有实现类,只写接口,要求对应的Mapper映射文件的namespace是接口的全路径。接口中方法名与sql语句的id一致。
接口EmployeeDAO
package com.dao;
import com.pojo.Employee;
import java.util.List;
/**
* 本接口没有实现类
*/
public interface EmployeeDAO {
List<Employee> getAllDept();
}
映射文件:
映射文件EmployeeMapper.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">
<!--注意namespace和接口全路径一致-->
<mapper namespace="com.dao.EmployeeDAO">
<resultMap id="employeeMap" type="Employee">
<id property="id" column="ID"/>
<result property="name" column="NAME"/>
<result property="job" column="JOB"/>
<result property="salary" column="SALARY"/>
<result property="hireDate" column="HIRE_DATE"/>
<result property="dept.id" column="DEPT_ID"/>
<result property="dept.name" column="DEPT_NAME"/>
</resultMap>
<!--注意语句的id与接口中的方法名一致-->
<select id="getAllDept" resultMap="employeeMap">
select ID,NAME FROM EMPLOYEE
</select>
</mapper>
spring中配置bean:
<!--面向接口的整合,EmployeeDAO接口没有实现类-->
<bean id="employeeDAO" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="com.dao.EmployeeDAO"/>
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
测试代码:
@Test
public void testEmpDAO() {
EmployeeDAO dao = (EmployeeDAO) ac.getBean("employeeDAO");
List<Employee> list = dao.getAllDept();
for (Employee employee : list) {
System.out.println(employee.getName());
}
}
9.2.3 简化配置
Mybatis的接口可以没有实现类,当接口很多的时候,可以统一扫描,不需要每个接口都声明bean:
<!—dao接口包扫描器 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.dao"/>
</bean>
注释掉7.2.2中employeeDAO的bean,运行测试代码一样可以成功。
简化:
当DAO的接口和Mapper映射文件在一个文件夹下,且命名一致的时候:
映射文件和接口的命名一样,只是 文件拓展名不同,配置了上面的MapperScannerConfigurer后,可以省略sqlSessionFactory中配置文件的路径:
<!--spring管理session工厂-->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<!--如果映射文件和接口在一个包下,并且命名一致,可以不写这句-->
<!--<property name="mapperLocations" value="classpath:com/dao/mapper/*.xml"/>-->
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<property name="plugins">
<array>
<bean class="com.github.pagehelper.PageHelper">
<property name="properties">
<value>
dialect=mysql
reasonable=true
</value>
</property>
</bean>
</array>
</property>
</bean>