Spring集成MyBatis的使用-使用Mapper映射器

Posted 斐波那切

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring集成MyBatis的使用-使用Mapper映射器相关的知识,希望对你有一定的参考价值。

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>

step5 Mapper映射器:一个接口,里面写好了方法,跟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需要手动完成的步骤

以上是关于Spring集成MyBatis的使用-使用Mapper映射器的主要内容,如果未能解决你的问题,请参考以下文章

Spring集成Mybatis3

spring boot集成MyBatis 通用Mapper 使用总结

Spring集成MyBatis的使用-使用SqlSessionTemplate

SpringSpring集成MyBatis

Spring Boot2:使用Spring Boot2集成Mybatis缓存机制

MyBatis 快速入门:MyBatis 和 Spring 集成