Spring与MyBatis的整合(初级实现)

前言

在之前我们学习了Spring的控制反转以及AOP思想,那么我们如何将这些应用到我们的项目中呢?我们知道,通过MyBatis框架可以实现对数据库的操作,而通过Spring框架的IoC、AOP等机制,能够对项目中的组件进行解耦管理,建立一个低耦合的应用架构。将Spring框架与MyBatis框架整合在一起,在对组件实现解耦的同时,还能使MyBatis的使用变得更加方便、简单。此外,通过Spring的声明式事务等,还可以进一步简化编码,减少开发工作量,提高效率,当然这是后话,今天我们只实现两个框架的简单整合。

整合思路

作为Bean容器,Spring框架提供了IoC机制,可以接管所有组件的创建工作并进行依赖管理,因此整合的主要工作就是把MyBatis框架使用过程中所涉及的核心组件配置到Spring容器中,交给Spring来管理。

具体来说,业务逻辑对象依赖基于MyBatis技术实现的DAO层对象,核心即是获取SqlSession实例。再往上翻,获取SqlSession则需要依赖SqlSessionFactory实例。再往上翻一层,SqlSessionFactory是依赖SqlSessionFactoryBuilder读取MyBatis的配置文件中的数据源、SQL映射文件等信息来构建。

针对上述关系,我们只需要将以上这些流程全部交给Spring,由Spring来接管这一工作,实现解耦。

整合前的准备工作

准备所需要的jar包(这里只列出整合需要依赖的新jar包,以往的jar包请自行准备。x代表任意版本号)

mybatis-spring-x.x.x.jar

spring-jdbc-x.x.x.RELEASE.jar

spring-tx-x.x.x.RELEASE.jar

commons-dbcp-x.x.jar

commons-pool-x.x.jar

分享一下Spring所有的依赖包、整合所需要的所有依赖包以及Spring源码下载地址

https://pan.baidu.com/s/1HYqfU85-jPkHmDJeUFoWHA

1、新建Web项目(本文使用的开发工具是IDEA),目录结构如下,实体类、接口、映射文件等请自行创建。

 2、新建数据库Blog,新建数据库表Student

DROP TABLE IF EXISTS `Student`;
CREATE TABLE `Student` (
  `ID` int(4) NOT NULL AUTO_INCREMENT,
  `StuName` varchar(10) NOT NULL,
  PRIMARY KEY (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

3、将所需依赖包导入至项目中

开始实现整合

1、在实体类中声明属性id、stuName,并生成getter、setter方法。

2、在数据层接口StudentDao、服务层接口StudentService中定义如下方法

public Student getStudent(@Param("id") int id);  //根据ID查找学生对象

3、在服务层StudentServiceImpl中实现StudentService接口,并定义SqlSessionTemplate属性,生成其setter方法(至于这个类到底是干嘛的,在下文介绍配置文件时进行讲解)。

private SqlSessionTemplate sqlSession;  //为其生成setter方法
public void setSqlSession(SqlSessionTemplate sqlSession) {
    this.sqlSession = sqlSession;
}

@Override
public Student getStudent(@Param("id") int id) {
    return sqlSession.getMapper(StudentDao.class).getStudent(id);
}

4、在resource文件夹下新建mybatis-config.xml文件(MyBatis的配置文件),注意一定要把resource文件夹设置为编译文件夹,或者你可以直接将这些配置文件放在src目录下,个人习惯。

<?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>

    <!--设置运行时的行为-->
    <settings>
        <setting name="logImpl" value="LOG4J"/>
        <!--设置为FULL,自动匹配所有,则在resultMap中不进行匹配的字段也可以映射-->
        <setting name="autoMappingBehavior" value="FULL"/>
    </settings>

    <!--指向包含实体类的包-->
    <typeAliases>
        <package name="com.Blog.Entity"/>
    </typeAliases>

</configuration>

相比于之前,MyBatis的配置文件就显得简单很多,我们在这里只指定一个包含实体类的包,设置日志为LOG4J,自动映射级别为FULL,至于数据库环境、SQL映射文件,全部移交到Spring的配置文件中。

5、在resource文件夹下创建spring-mybatis.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:p="http://www.springframework.org/schema/p"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
">
    <!--第一步,配置数据源-->
    <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url">
            <value><![CDATA[jdbc:mysql://localhost:3306/Blog?useSSL=true&serverTimezone=UTC]]></value>
        </property>
        <property name="username" value="root" />
        <property name="password" value="****" />
    </bean>

    <!--第二步,配置SqlSessionFactoryBean-->
    <bean id="factory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />  <!--引用数据源组件-->
        <property name="configLocation" value="classpath:mybatis-config.xml" />  <!--引入mybatis配置文件-->
        <property name="mapperLocations">  <!--配置SQL映射文件-->
            <list>
                <value>classpath:com/Blog/Mapper/*.xml</value>  <!--代表扫描com.Blog.Mapper包下所有的xml格式的文件-->
            </list>
        </property>
    </bean>

    <!--第三步,配置SqlSessionTemplate-->
    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
        <constructor-arg name="sqlSessionFactory" ref="factory" />  <!--引用上一步定义的SqlSessionFactoryBean-->
    </bean>

    <!--第四步,装配业务组件-->
    <bean id="studentService" class="com.Blog.ServiceImpl.StudentServiceImpl">
        <property name="sqlSession" ref="sqlSession" />
    </bean>
</beans>

在以上配置文件中,除去最后装配我们的业务组件(为StudentServiceImpl类中的SqlSessionTemplate对象注入依赖),Spring与MyBatis的整合大概可分为三步:配置数据源、配置SqlSessionFactoryBean、配置SqlSessionTemplate。

配置数据源

对于任何持久化解决方案,连接数据库都是首要的问题。在Spring中,数据源作为一个重要的组件可以单独进行配置和维护。首先我们要选择一种具体的数据源实现技术,目前流行的数据源实现有dbcp、c3p0、Proxool等,它们都实现了连接池功能,这里以dbcp为例。其他数据源技术的配置都与此类似,只需要下载不同的jar包即可,可自行查阅资料进行学习。

因为我们的url属性中有特殊符号“&”,所以使用<![CDATA[]]>进行标记。

配置SqlSessionFactoryBean

从这个类的名称就可以看出来,它肯定与SqlSessionFactory有关。在MyBatis中,我们使用SqlSessionFactoryBuilder来创建SqlSessionFactory工厂。而在mybatis-spring集成环境中,可以使用SqlSessionFactoryBean来完成这个工作,它的内部封装了使用SqlSessionFactoryBuilder创建SqlSessionFactory的过程。同样,SqlSessionFactory需要依赖三部分东西:数据源、MyBatis的配置、SQL映射文件,所以就形成了上面的配置文件中的第二步,我们先引用之前定义的数据源组件,再指向MyBatis的配置文件,最后为这个类中的mapperLocations属性注入值,即要引入的SQL映射文件。因为逐个列出映射文件比较繁琐,所以我们使用mapperLocations属性扫描式地加载SQL映射文件,指定一个匹配表达式即可。

配置SqlSessionTemplate

跟之前相似,获得SqlSessionFactory的实例以后就可以获得SqlSession了。只不过在集成环境中为了更好地使用SqlSession,充分利用Spring框架提供的服务,mybatis-spring整合包中提供了SqlSessionTemplate类。这个类实现了SqlSession接口和DisposableBean接口,具有MyBatis中原有的SqlSession的所有操作方法。使用SqlSessionTemplate类可以更好地与Spring服务融合并简化一些工作,可以保证和当前Spring事务相关联、自动管理会话的生命周期、必要的回滚、提交、关闭等,当然这是后话,本文先不介绍。

在Spring容器中定义SqlSessionTemplate组件时,需要通过其构造方法为其注入一个SqlSessionFactory实例,所以我们引用了在第二步配置好的Bean组件。

6、在测试类中进行测试(在MyTest类中添加如下代码)

@Test
public void studentTest(){
    ApplicationContext context=new ClassPathXmlApplicationContext("spring-mybatis.xml");
    StudentService studentService=(StudentService)context.getBean("studentService");
    Student student=studentService.getStudent(1);
    System.out.println(student);
}

注:先往数据库插入一条记录,名叫张三,ID为1。

 总结

MyBatis与Spring的简单整合到这里就结束了,实现起来还是很简单的,只不过是把之前配置在MyBatis配置文件中的东西拿到Spring配置文件里,再把SqlSessionFactory、SqlSession的实例定义到Spring容器中,通过注入的方式注给需要获取它们的Bean组件,替代之前通过编码的方式获取连接。在下一篇博文中将对整合做一些优化。

====================================最后附上本文中所有的代码========================================

 实体类Student

package com.Blog.Entity;

public class Student {
    private int id;
    private String stuName;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getStuName() {
        return stuName;
    }

    public void setStuName(String stuName) {
        this.stuName = stuName;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", stuName='" + stuName + '\'' +
                '}';
    }
}

数据层接口StudentDao

package com.Blog.Dao;

import com.Blog.Entity.Student;
import org.apache.ibatis.annotations.Param;

public interface StudentDao {
    public Student getStudent(@Param("id") int id);  //根据ID查找学生对象
}

服务层接口StudentService

package com.Blog.Service;

import com.Blog.Entity.Student;
import org.apache.ibatis.annotations.Param;

public interface StudentService {
    public Student getStudent(@Param("id") int id);  //根据ID查找学生对象
}

服务层接口实现类StudentServiceImpl

package com.Blog.ServiceImpl;

import com.Blog.Dao.StudentDao;
import com.Blog.Entity.Student;
import com.Blog.Service.StudentService;
import org.apache.ibatis.annotations.Param;
import org.mybatis.spring.SqlSessionTemplate;

public class StudentServiceImpl implements StudentService {

    private SqlSessionTemplate sqlSession;  //为其生成setter方法
    public void setSqlSession(SqlSessionTemplate sqlSession) {
        this.sqlSession = sqlSession;
    }

    @Override
    public Student getStudent(@Param("id") int id) {
        return sqlSession.getMapper(StudentDao.class).getStudent(id);
    }
}

SQL映射文件StudentMapper.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.Blog.Dao.StudentDao">
    <select id="getStudent" resultType="Student">
        SELECT * FROM Student WHERE ID=#{id}
    </select>
</mapper>

MyBatis配置文件mybatis-config.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>

    <!--设置运行时的行为-->
    <settings>
        <setting name="logImpl" value="LOG4J"/>
        <!--设置为FULL,自动匹配所有,则在resultMap中不进行匹配的字段也可以映射-->
        <setting name="autoMappingBehavior" value="FULL"/>
    </settings>

    <!--指向包含实体类的包-->
    <typeAliases>
        <package name="com.Blog.Entity"/>
    </typeAliases>

</configuration>

Spring配置文件spring-mybatis.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:p="http://www.springframework.org/schema/p"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
">
    <!--第一步,配置数据源-->
    <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url">
            <value><![CDATA[jdbc:mysql://localhost:3306/Blog?useSSL=true&serverTimezone=UTC]]></value>
        </property>
        <property name="username" value="root" />
        <property name="password" value="accp" />
    </bean>

    <!--第二步,配置SqlSessionFactoryBean-->
    <bean id="factory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />  <!--引用数据源组件-->
        <property name="configLocation" value="classpath:mybatis-config.xml" />  <!--引入mybatis配置文件-->
        <property name="mapperLocations">  <!--配置SQL映射文件-->
            <list>
                <value>classpath:com/Blog/Mapper/*.xml</value>  <!--代表扫描com.Blog.Mapper包下所有的xml格式的文件-->
            </list>
        </property>
    </bean>

    <!--第三步,配置SqlSessionTemplate-->
    <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
        <constructor-arg name="sqlSessionFactory" ref="factory" />  <!--引用上一步定义的SqlSessionFactoryBean-->
    </bean>

    <!--第四步,装配业务组件-->
    <bean id="studentService" class="com.Blog.ServiceImpl.StudentServiceImpl">
        <property name="sqlSession" ref="sqlSession" />
    </bean>
</beans>

猜你喜欢

转载自blog.csdn.net/wzy18210825916/article/details/82626140