Spring 集成 MyBatis 使用
前面复习 MyBatis 时, 发现在测试时, 需要手动创建 sqlSessionFactory,Spring 将帮忙自动创建 sqlSessionFactory, 并且将自动扫描 Mapper 映射器
(1)集成步骤
step1 导包: spring-webmvc, mybatis, mybatis-spring, dbcp, ojdbc, spring-jdbc, junit, MySQL 相关等
- <dependencies>
- <!-- 导入 junit 测试包 -->
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>4.12</version>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>4.12</version>
- <classifier>sources</classifier>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>4.12</version>
- <classifier>javadoc</classifier>
- </dependency>
- <!-- 导入数据库包 -->
- <dependency>
- <groupId>commons-dbcp</groupId>
- <artifactId>commons-dbcp</artifactId>
- <version>1.4</version>
- </dependency>
- <dependency>
- <groupId>com.oracle</groupId>
- <artifactId>ojdbc6</artifactId>
- <version>11.2.0.1.0</version>
- </dependency>
- <!-- 导入 mybatis 的包 -->
- <dependency>
- <groupId>org.mybatis</groupId>
- <artifactId>mybatis</artifactId>
- <version>3.4.0</version>
- </dependency>
- <dependency>
- <groupId>org.mybatis</groupId>
- <artifactId>mybatis</artifactId>
- <version>3.2.8</version>
- <classifier>sources</classifier>
- </dependency>
- <dependency>
- <groupId>org.mybatis</groupId>
- <artifactId>mybatis</artifactId>
- <version>3.2.8</version>
- <classifier>javadoc</classifier>
- </dependency>
- <!-- 针对 mysql 的导包 -->
- <dependency>
- <groupId>org.wisdom-framework</groupId>
- <artifactId>MySQL-connector-java</artifactId>
- <version>5.1.34_1</version>
- </dependency>
- <!-- 导入 spring-webmvc 的 jar 包 -->
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-webmvc</artifactId>
- <version>4.2.3.RELEASE</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-webmvc</artifactId>
- <version>4.2.3.RELEASE</version>
- <classifier>sources</classifier>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-webmvc</artifactId>
- <version>4.2.3.RELEASE</version>
- <classifier>javadoc</classifier>
- </dependency>
- <!-- 针对 spring JDBC 导包 -->
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-jdbc</artifactId>
- <version>4.2.3.RELEASE</version>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-jdbc</artifactId>
- <version>4.2.3.RELEASE</version>
- <classifier>sources</classifier>
- </dependency>
- <dependency>
- <groupId>org.springframework</groupId>
- <artifactId>spring-jdbc</artifactId>
- <version>4.2.3.RELEASE</version>
- <classifier>javadoc</classifier>
- </dependency>
- <!-- 关键: 导入 mybatis-spring -->
- <dependency>
- <groupId>org.mybatis</groupId>
- <artifactId>mybatis-spring</artifactId>
- <version>1.3.2</version>
- </dependency>
- <dependency>
- <groupId>org.mybatis</groupId>
- <artifactId>mybatis-spring</artifactId>
- <version>1.3.2</version>
- <classifier>sources</classifier>
- </dependency>
- <dependency>
- <groupId>org.mybatis</groupId>
- <artifactId>mybatis-spring</artifactId>
- <version>1.3.2</version>
- <classifier>javadoc</classifier>
- </dependency>
- </dependencies>
注意: 导包可能出现版本不兼容的问题, 可以参考博客建议, 暂时没找着链接
step2 添加 spring 配置文件, 不再需要 MyBatis 的配置文件
- <?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" xmlns:util="http://www.springframework.org/schema/util"
- xmlns:jee="http://www.springframework.org /schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
- xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:mvc="http://www.springframework.org/schema/mvc"
- xsi:schemaLocation="
- http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
- http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd
- http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd
- http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd
- http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd
- http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.3.xsd
- http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
- <!-- 配置连接池 -->
- <!-- 读取属性文件 -->
- <util:properties id="db" location="classpath:config.properties">
- </util:properties>
- <!-- 配置连接池, 可以参考 DBUtil 的方法, 这里采用 spring 创建连接池 -->
- <!-- destroy-method 方法作用是: 当 spring 容器关闭后, 会将连接释放回到连接池, 避免资源浪费 -->
- <bean id="ds" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
- <property name="driverClassName" value="#{db.driver}"/>
- <property name="url" value="#{db.url}" />
- <property name="username" value="#{db.user}" />
- <property name="password" value="#{db.pwd}" />
- </bean>
- <!-- 配置 SqlSessionFactoryBean -->
- <bean id="ssfb" class="org.mybatis.spring.SqlSessionFactoryBean">
- <!-- 指定连接资源 -->
- <property name="dataSource" ref="ds"/>
- <!-- 指定映射文件: entity 包下的所有后缀 xml 的映射文件 -->
- <property name="mapperLocations" value="classpath:entity/*.xml"/>
- </bean>
- <!-- 配置 MapperScannerConfigurer -->
- <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
- <!-- 注入映射器所在的包名 -->
- <property name="basePackage" value="dao"/>
- <!-- 只扫描有特定注解的接口 -->
- <property name="annotationClass" value="annotations.MyBatisRepository" />
- </bean>
- </beans>
可以在 spring 配置文件中, 添加 SqlSessionFactoryBean 来代替单独使用 MyBatis 时, 需要加载 sqlMapConfig.xml.MyBatis 创建 sqlSessionFactory 时, 会加载这个配置文件, 完成初始化连接池, 以及读取映射文件后将 sql 预编译后存入一个 Map 集合两项工作, 配置 sqlSessionFactoryBean 也完成了上述两项工作, 其主要交给 Spring 来自动完成.
step3 写实体类, 属性名和表格的字段名一样
- public class Employee {
- private int id;
- private String name;
- private int age;
- public int getId() {
- return id;
- }
- public void setId(int id) {
- this.id = id;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- @Override
- public String toString() {
- return "Employee [id=" + id + ", name=" + name + ", age=" + age + "]";
- }
- }
step4 写了具体 sql 的 xml 映射文件, 跟 MyBatis 写法一样, 要注意的是 namespace 是 mapper 映射器的包名 + 类名
<?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="dao.EmployeeDAO">
- <!-- id 要求唯一
- parameterType: 填写实体类的完整名字
- -->
- <!-- 插入语句 -->
- <insert id="save" parameterType="entity.Employee">
- INSERT INTO T_TABLE VALUES(6,#{name},#{age})
- </insert>
- <!-- 根据 id 查询语句 -->
- <select id="findByID" parameterType="int" resultType="entity.Employee">
- SELECT * FROM T_TABLE WHERE ID=#{id}
- </select>
- <!-- 查询所有结果, 不需要参数类型 -->
- <select id="findAll" resultType="entity.Employee">
- SELECT * FROM T_TABLE
- </select>
- <!-- 修改操作 -->
- <update id="modify" parameterType="entity.Employee">
- UPDATE T_TABLE SET NAME=#{name},AGE=#{age} WHERE ID=#{id}
- </update>
- <!-- 删除操作 -->
- <delete id="delete" parameterType="int">
- DELETE FROM T_TABLE WHERE ID=#{ididid}
- </delete>
- <!-- 返回 map 类型的结果 -->
- <!-- 也可以将返回结果简写成 map,map 即为 java.util.Map -->
- <select id="findOne" parameterType="int" resultType="java.util.Map">
- SELECT * FROM T_TABLE WHERE ID=#{id}
- </select>
- <!-- 使用 resultMap 解决表的字段名和实体类的属性名不一致的情况 -->
- <resultMap id="resultMapID" type="entity.NewEmployee">
- <result property="empID" column="id" />
- <result property="empName" column="name" />
- <result property="empAge" column="age" />
- </resultMap>
- <select id="findOneByNewEmp" parameterType="int" resultMap="resultMapID">
- SELECT * FROM T_TABLE WHERE ID=#{id}
- </select>
- </mapper>
step5Mapper 映射器: 一个接口, 里面写好了方法, 跟 MyBatis 配置时一样, 主要目的为调用方法时能依据命名空间和其他约束条件找到对应的 sql
- import java.util.List;
- import java.util.Map;
- import org.springframework.stereotype.Repository;
- import annotations.MyBatisRepository;
- import entity.Employee;
- import entity.NewEmployee;
- /**
- * Mapper 映射器
- * @author clyang
- */
- @Repository("empDAO")
- @MyBatisRepository
- public interface EmployeeDAO {
- // 将一条数据插入数据库
- public void save(Employee e);
- // 查询所有结果
- public List<Employee> findAll();
- // 根据 id 来查找结果
- public Employee findByID(int id);
- // 修改操作
- public void modify(Employee e);
- // 删除操作
- public void delete(int id);
- // 返回类型为 map 的查询, 根据 id 来查询
- public Map findOne(int id);
- // 当表的字段名和实体类的属性名不一致时, 根据 id 来查询
- public NewEmployee findOneByNewEmp(int id);
- }
step6 配置 MapperScannerConfigurer
配置参考上上图
该 bean 会扫描指定包及其子包下面的所有 mapper 映射器 (即接口), 并调用 session.getMapper() 方法获得映射器的具体实现, 比如 MyBatis 例子中的 EmployeeDAO dao=session.getMapper(EmployeeDAO.class), 并且将这些实现后的对象添加到 spring 容器中, 对应的 bean id 为接口首字母小写, 可以使用 repository("别名")来, 重命名 bean id, 方便业务层调用.
测试代码:
- import java.util.List;
- import org.junit.Test;
- import org.springframework.context.ApplicationContext;
- import org.springframework.context.support.ClassPathXmlApplicationContext;
- import dao.EmployeeDAO;
- import entity.Employee;
- public class testCase {
- @Test
- public void test1() {
- // 启动 spring 容器
- String config="spring-mybatis.xml";
- ApplicationContext ac=new ClassPathXmlApplicationContext(config);
- // 调用 mapper 映射器实现类对象
- EmployeeDAO dao=ac.getBean("empDAO",EmployeeDAO.class);
- // 调用查询方法
- List<Employee> list=dao.findAll();
- System.out.println(list);
- // 不需要手动关闭连接
- }
- // 下面略去
- }
测试时只要启动 Spring 容器, Spring 会根据配置自动完成 MyBatis 中需要手动完成的工作, 如得到一个 sqlSession, 创建一个 Mapper 映射器具体实现对象.
Spring 容器实现 Mapper 映射器具体实现, 采用了接口指向对象, 这为 Java 多态的使用, 根据接口具体实现方法的不同, 实现方法动态调度
测试结果:
(2)只扫描特定的接口
为什么只扫描特定的接口, 因为 dao 下的 Mapper 映射器接口, 有些可能不是采用 MyBatis 来实现连接, 可能采用其它的连接方式, 如果是 JDBC 实现的 dao 类, 也会被 MapperScannerConfigure 扫描到, 但是扫描到后无法使用, 会导致程序报错, 为了解决这个问题, 需要做到只扫描特定的接口
方法:
step1 开发一个注解, 注解只是一个标识, 代表只扫描它, 其他的的不扫描
- /**
- * 一个标识
- * @author clyang
- */
- public @interface MyBatisRepository {
- }
step2 将该注解添加到需要扫描的接口之上
step3 修改 MapperScannerConfigurer, 告诉它只扫描有注解的接口
总结: Spring 集成 MyBatis 后, 充分发挥了 Spring 的管理对象之间关系的能力, 配置好后, 自动完成以前 MyBatis 需要手动完成的步骤
来源: http://www.bubuko.com/infodetail-2946175.html