目录

一、引言:

1.1、Spring的两大核心思想:

1.2 、Spring可以对mybatis提供哪些支持?

二、Spring整合mybatis准备工作:

2.1 创建maven工程

2.2 部署mybatis、Spring、整合依赖等框架

三、配置数据源(Druid连接池)

3.1 添加Druid依赖

3.2 创建Druid.properties属性文件

3.3 在ApplicationContext.xml配置数据源

四:配置sqlsessionFactory

五、配置MapperScannerConfigurer

六、整合Aop配置

6.1 将spring事务配置给spring容器

6.2 声明事务策略

6.2.1 事务的隔离级别

6.2.2 事务的传播机制

6.3 Aop事务配置

七、事务管理配置(注解配置)

八、案例测试


一、引言:

1.1 Spring的两大核心思想

        1、IOC:控制反转,Spring容器可以完成对象的创建,属性的注入,对象管理等工作

        2、Aop:面向切面,在不修改代码业务逻辑的情况下,实现原有的业务的增强

1.2 Spring可以对mybatis提供哪些支持?

        1、Spring-Ioc可以为mybatis完成DataSource、SqlSessionFactory、SqlSession以及Dao对象的创建

        2、Spring-Aop可以提供事物管理切面类完成对mybatis数据库中的事务管理

二、Spring整合mybatis准备工作:

2.1 创建maven工程

        创建maven工程可以选择模板创建,也可以手动创建(建议手动创建),使用模板时间较慢,本实例中项目取名为“SpringMybatis02”(可以自定义),创建好项目后,补全项目框架结构,创建好的项目框架如下:

mybatis整合spring maven案例 spring整合mybatis要点_jar

 2.2 部署mybatis、Spring、整合依赖等框架

          搭建好项目结构后,接下来进行jar包依赖的添加,分别是mysql驱动、mybatis依赖、spring-context、spring-Aspect、mybatis-spring(Spring整合mybatis的依赖)spring-jdbc也要添加进去,要不然进行数据源配置时会报错,依赖可以在maven仓库(https://mvnrepository.com)中进行查找,也可以赋值下面代码到pom.xml中进行添加

<!---添加mysql依赖-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.44</version>
        </dependency>
        <!---添加mybatis依赖-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.2</version>
        </dependency>
        
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>5.3.15</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.3.19</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>2.0.6</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.16</version>
            <scope>provided</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/log4j/log4j -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/junit/junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-jdbc -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.3.19</version>
        </dependency>

三、配置数据源(Druid连接池)

3.1 添加Druid依赖

        这里的数据源我们使用的阿里巴巴旗下的Druid,如果想要其他的数据源,例如c3p0等,可以添加对应的jar包依赖即可,配置方法相同

<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.9</version>
        </dependency>

3.2 创建Druid.properties属性文件

        外部属性文件中有数据源的相关配置,例如Driver、url、username、password等其他数据源的配置,具体如下:

druid.driver =com.mysql.jdbc.Driver
druid.url =  jdbc:mysql://localhost:3306/spring_mybatis
druid.userName = root
druid.password = 990501
#初始化连接数
druid.pool.init=3
#高峰期过后,保留连接吃的个数
druid.pool.minIdle = 5
#高峰期,最大能创建连接的个数
druid.pool.MaxActive = 20
#等待的时间
durid.pool.timeout = 30

3.3 在ApplicationContext.xml配置数据源

        在配置数据源之前,我们首先进行注解配置的声明以及使用<Context:property-placeholder>进行外部文件的引用,之后在使用<bean>标签进行数据源的配置,然后再使用${}符号记性属性值的注入即可;

<?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:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd
       http://www.springframework.org/schema/aop
      http://www.springframework.org/schema/aop/spring-aop.xsd
      http://www.springframework.org/schema/tx
      http://www.springframework.org/schema/tx/spring-tx.xsd">
    <!--声明使用注解配置-->
    <Context:annotation-config/>
    <!--声明Spring工厂注解的扫描范围-->
    <Context:component-scan base-package="com.xgsm"/>

    <!--引用外部文件-->
    <Context:property-placeholder location="druid.properties"/>
    <!--配置DruidDataSources-->
    <bean id="DruidDataSources" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="${druid.driver}"/>
        <property name="url" value="${druid.url}"/>
        <property name="username" value="${druid.userName}"/>
        <property name="password" value="${druid.password}"/>
        <property name="initialSize" value="${druid.pool.init}"/>
        <property name="minIdle" value="${druid.pool.minIdle}"/>
        <property name="maxActive" value="${druid.pool.MaxActive}"/>
        <property name="maxWait" value="${durid.pool.timeout}"/>
    </bean>

</beans>

加载驱动的时候这里要使用driverClassName,不能使用driver,要不然会报错!

四、配置sqlsessionFactory

        首先需要依赖spring容器进行mybatis的sqlsessionfactory的创建,然后再进行数据源的配置,在配置sqlsessionFactory过程中可以对mapper映射文件进行配置,也可以进行配置需要定义的实体类别名、以及引入mybatis-config.xml(mybatis主配置文件)等操作~

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!--配置数据源-->
        <property name="dataSource" ref="DruidDataSources"/>
        <!--配置mapper的路径-->
        <property name="mapperLocations" value="classpath*:mappers/*Mapper.xml">
        </property>
        <!--配置需要定义别名的实体类的包-->
        <property name="typeAliasesPackage" value="com.xgsm.pojo"/>
        <!--配置需要mybatis的主配置文件-->
        <property name="configLocation" value="Mybatis-config.xml"/>
    </bean>

五、配置MapperScannerConfigurer:

        在配置MapperScannerConfigurer中主要是加载dao包中的所有dao接口,通过sqlsessionFactory获取sqlsession,然后创建所有dao接口对象,存储在spring容器

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer" >
        <property name="sqlSessionFactoryBeanName" value="SqlsessionFactory"/>
        <property name="basePackage" value="com.xgsm.Dao"/>
    </bean>

六、整合Aop配置:

        使用spring整合Aop配置,使用spring提供的事务管理切面类,完成dao中的CRUD操作的事务管理。步骤如下:

  1. 将spring提供的事务管理配置给spring
  2. 通过spring jdbc提供的<tx>标签,声明事物的管理策略(设置事务的隔离级别以及传播机制)
  3. 将事务管理策略以Aop配置,应用于Dao层的操作方法

6.1 将spring事务管理配置给spring

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="DruidDataSources"/>
    </bean>

6.2 声明事务策略

        通过Spring jdbc提供的<tx>标签声明事物的管理策略,并给事务设置隔离级别以及传播机制

<tx:advice id="TxAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="Insert*" isolation="REPEATABLE_READ" propagation="REQUIRED"/>
            <tx:method name="Update*" isolation="REPEATABLE_READ" propagation="REQUIRED"/>
            <tx:method name="Delete*" isolation="REPEATABLE_READ" propagation="REQUIRED"/>
            <tx:method name="Query*" isolation="REPEATABLE_READ" propagation="SUPPORTS"/>
        </tx:attributes>
    </tx:advice>

6.2.1 事务的隔离级别

        事务的隔离级别就是约束两个事物是否可以并行,目的是保证数据的安全性,数据的隔离级别越高,数据的效率越低,具体的使用,要根据场景进行不同的选择,隔离级别有以下四种:

事务的隔离级别

隔离级别的分类:

可能会造成的影响:

Serializable(可序化):T1线程在执行过程中,T2线程既不能读也不能写(只能一个一个执行)

最安全,但是效率是最低的

Repeatable read(可重复读):T1线程在执行过程中,T2线程能读但是不能写,T2可以添加数据

可能造成“幻读”

Read Commit(读提交):T1线程在执行过程中,T2可以读也可以写,但是T1只能读取T2提交的数据

可能造成“幻读”、“不可重复读”

Read UnCommit(读未提交):T1线程在执行过程中,T2可以读,也可以学,T1可以读取到T2未提交的数据

可能造成“幻读”、“不可重复读”、“脏读”

6.2.2 事务的传播机制 

        事务的传播机制有七种,表示的是线程在执行过程中如何处理事务的,具体如下;

事务的传播机制

Required:如果上层方法没有事务,则创建一个新的事务;如果有,咋加入该事务。即必须在事务中执行

Supports:如果上层方法没有事务,则以非事务方式进行;如果有,咋加入该事务。即非必要在事务中执行

Required-new:如果上层方法没有事务,则创建一个新的事务;如果有,则将当前事物挂起。即必须在新事务中执行

Not-Supports:以非事务方式运行,如果已经存在事务,则挂起

Never:如果上层没有事务,则以非事务方式运行,如果已经存在事务,则抛出异常

ManadaTory:如果上层方法已经存在事务,则加入该事务,不存在则抛异常

Nested:如果上层没有事务,则创建新事务,如果有则嵌套在当前事务中执行

6.3 Aop事务配置

        将事务管理策略以Aop配置,应用于Dao层的操作方法(主要是应用于ServiceI方法(ServiceImp)),使用<aop:config>标签;在标签内,定义切点。

<!--将事务管理以Aop配置,应用于ServiceI方法(ServiceImp)-->
    <aop:config>
        <aop:pointcut id="crud" expression="execution(* com.xgsm.Service.*.*(..))"/>
        <aop:advisor advice-ref="TxAdvice" pointcut-ref="crud"/>
    </aop:config>

七、事务管理配置(注解配置):

        在配置文件中,配置事务管理类,使用<tx:annotation>声明使用注解方式进行事务配置,在需要进行事务管理的方法上添加注解,以下面例子为参考;

package com.xgsm.Service.ServiceImp;

import com.xgsm.Dao.UserDao;
import com.xgsm.Service.UserDaoService;
import com.xgsm.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * Description: SpringMybatis
 * Created by WuHuaSen .
 * Created Date:  2022/4/17 17:06
 * Version:  V1.0
 */
@Service
public class UserDaoServiceImp implements UserDaoService {
    @Autowired
    private UserDao userDao;
@Transactional(isolation = Isolation.REPEATABLE_READ,propagation = Propagation.SUPPORTS)
    public List<User> SelectAllUser() {
        return userDao.SelectAllUser();
    }


}

九、案例测试:

        Spring整合mybatis已经整合完毕,下面将通过一个实例进行整合测试,有这样一个数据库库,数据库中有两张表(User、ClassRoom),本实例中我们执行的操作是查询User表中的全部信息,进行打印输出,下面是具体的代码:

User实体类

UserDao层

package com.xgsm.pojo;import lombok.*;@Data@ToString@NoArgsConstructor@AllArgsConstructor@Getter@Setterpublic class User { private int UserId; private String UserName; private String UserPwd; private String UserRealName; private String UserImg; private int ClazzId;}

package com.xgsm.Dao;import com.xgsm.pojo.User; import java.util.List; /** * Description: SpringMybatis02 * Created by WuHuaSen . * Created Date: 2022/4/19 15:34 * Version: V1.0 */ public interface UserDao { //查询所有学生 public List<User> SelectAllUser(); }

本实例我们实现的service接口,具体代码如下:

UserDaoService 层

UserDaoServiceImp 层

package com.xgsm.Service;import com.xgsm.pojo.User;import java.util.List;public interface UserDaoService { //查询所有学生 public List<User> SelectAllUser();}

package com.xgsm.Service.ServiceImp;import com.xgsm.Dao.UserDao;import com.xgsm.Service.UserDaoService;import com.xgsm.pojo.User;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import org.springframework.transaction.annotation.Isolation;import org.springframework.transaction.annotation.Propagation;import org.springframework.transaction.annotation.Transactional;import java.util.List;@Servicepublic class UserDaoServiceImp implements UserDaoService { @Autowired private UserDao userDao; public List<User> SelectAllUser() { return userDao.SelectAllUser(); }}

mapper映射文件代码如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org/DTD Mapper 3.0" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.xgsm.Dao.UserDao">
    <resultMap id="userMap" type="user">
        <id column="user_id" property="UserId"></id>
        <result column="user_name" property="UserName"></result>
        <result column="user_pwd" property="UserPwd"></result>
        <result column="user_realname" property="UserRealName"></result>
        <result column="user_img" property="UserImg"></result>
        <result column="clazz_id" property="ClazzId"></result>
        <association property="classRoom" select="com.xgsm.dao.ClassRoomDao.SelectClassRoom" column=""></association>
    </resultMap>
    <sql id="user_cloumn_list">
        user_id,user_name,user_pwd,user_realname,user_img,clazz_id
    </sql>
    <select id="SelectAllUser" resultMap="userMap">
        SELECT <include refid="user_cloumn_list"/> FROM user;
    </select>
</mapper>

测试类通过spring来接口获取对象,代码如下:

import com.xgsm.Service.UserDaoService;
import com.xgsm.pojo.User;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.util.List;

public class UserDaoTest {
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("ApplicationContext.xml");
    @Test
    public void SelectAllUser() {

        UserDaoService userDao = (UserDaoService) context.getBean("userDaoServiceImp");
        List<User> users = userDao.SelectAllUser();
        for (User i : users
                ) {
            System.out.println(i);
        }

    }
}

测试结果:

mybatis整合spring maven案例 spring整合mybatis要点_java_02

 在最后附上数据库文件以便读者进行测试:

CREATE DATABASE /*!32312 IF NOT EXISTS*/`spring_mybatis` /*!40100 DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci */ /*!80016 DEFAULT ENCRYPTION='N' */;

USE `spring_mybatis`;

/*Table structure for table `classroom` */

DROP TABLE IF EXISTS `classroom`;

CREATE TABLE `classroom` (
  `clazz_id` int NOT NULL AUTO_INCREMENT,
  `clazz_name` varchar(20) NOT NULL,
  PRIMARY KEY (`clazz_id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;



insert  into `classroom`(`clazz_id`,`clazz_name`) values (1,'java1833'),(2,'web1244');



DROP TABLE IF EXISTS `user`;

CREATE TABLE `user` (
  `user_id` int NOT NULL AUTO_INCREMENT,
  `user_name` varchar(40) NOT NULL,
  `user_pwd` varchar(40) NOT NULL,
  `user_realname` varchar(40) NOT NULL,
  `user_img` varchar(40) NOT NULL,
  `clazz_id` int NOT NULL,
  PRIMARY KEY (`user_id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;

/*Data for the table `user` */

insert  into `user`(`user_id`,`user_name`,`user_pwd`,`user_realname`,`user_img`,`clazz_id`) values (1,'wangwu','111','王五','01.pdf',1),(2,'李四','222','李四','02.pdf',2),(3,'maliu','2355','马六','03.jpg',2),(4,'wangerniu','erere','王二妞','04.jpg',2);