Spring整合MyBatis

MyBatis开发流程

在我们之前没有和Spring整合的时候,Mybatis的开发流程是:

  1. 编写实体类
  2. 编写核心配置文件
  3. 编写接口
  4. 编写Mapper.xml
  5. 测试

整合方法(一)

Spring与Mybatis的整合分两种方式,这里先介绍第一种。

1. Srping-dao.xml

这个文件主要配置了DataSourcesqlSessionFactorysqlSessionTemplate。这个文件类似于数据库永久配置,写好了基本不用改。注意:Spring里的sqlSessionTemplate就相当于之前在MyBatis里的sqlSession。因为在Spring里都使用bean,而不用new对象,所以这三样东西都需要在XML配置文件中注册成bean。其中DriverManagerDataSource是Spring配置内置的连接池,我们在实际项目中可以换成其他的数据库连接池

<?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:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       https://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/aop
       https://www.springframework.org/schema/aop/spring-aop.xsd">

<!-- dataSource: 使用Spring的数据源替换MyBatis的配置,这里使用Spring提供的JDBC:org.springframework.jdbc.datasource -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=false&amp;useUnicode=true&amp;characterEncoding=UTF-8" />
        <property name="username" value="root" />
        <property name="password" value="123456" />
    </bean>

<!-- sqlSessionFactory -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <!-- 绑定mybatis配置文件,这里注意不要重复配置,即配置了mapperLocations就不要在mybatis-config里再配置 -->
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <property name="mapperLocations" value="classpath:com/zzw/mapper/*.xml" />
    </bean>

<!-- SqlSessionTemplate:就是我们使用的sqlSession -->
    <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
        <!-- 这里只能使用构造器来注入sqlSessionFactory,因为SqlSessionTemplate这个类里没有set方法来注入 -->
        <constructor-arg index="0" ref="sqlSessionFactory" />
    </bean>

</beans>

其他的dataSource: e.g., c3p0的XML配置例子:

    <!--2. 数据库连接池-->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driver}"/>
        <property name="jdbcUrl" value="${jdbc.url}"/>
        <property name="user" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>

        <!-- c3p0连接池的私有属性 -->
        <property name="maxPoolSize" value="30"/>
        <property name="minPoolSize" value="10"/>
        <!-- 关闭连接后不自动commit -->
        <property name="autoCommitOnClose" value="false"/>
        <!-- 获取连接超时时间 -->
        <property name="checkoutTimeout" value="10000"/>
        <!-- 当获取连接失败重试次数 -->
        <property name="acquireRetryAttempts" value="2"/>
    </bean>

2. mybatis-config.xml

这个XML配置文件主要是放一些mybatis的别名、设置,比如日志开启等。这个文件在Spring-dao.xml中的sqlSessionFactory被注入依赖(configLocation设置文件的classpath)。Spring非常强大,本身就整合了mybatis的一些设置,本文件可以写也可以不写(相应的配置写到Spring-dap.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>

    <typeAliases>
        <package name="com.zzw.pojo"/>
    </typeAliases>
    
	<!-- settings, typeAliases还是可以放在mybatis的配置文件中 -->

</configuration>

3. User.java

import lombok.Data;

@Data
public class User {
    private int id;
    private String name;
    private String pwd;
}

4. UserMapper.java

import com.zzw.pojo.User;
import java.util.List;

public interface UserMapper {
    public List<User> selectUser();
}

需要注意的是:所有的映射器类必须是接口,而不是具体的实现类。SQL语句可以通过注解实现,也可以通过MyBatis映射器的XML配置文件。注解方式只能实现非常简单的SQL语句,倘若遇上复杂的需求,最好还是使用XML配置文件的方式来写SQL语句。

放在Mybatis里,传统做法就是先写一个对应的MyBatis映射器的XML配置文件(或者直接使用SQL语句的注解),然后在MyBatis的XML配置文件中注册这个映射器,而注册映射器这一步,其实我们已经在Srping-dao.xml文件中注册了(sqlSessionFactory里的<property name="mapperLocations" value="classpath:com/zzw/mapper/*.xml" />)。

在Spring中,我们同样需要做这一步(写对应的MyBatis映射器的XML配置文件,这里对应的就是写一个UserMapper.xml),此外还需要额外写一个UserMapperImpl类来实现UserMapper接口,并把其注册到Spring容器中,体现的还是面向对象编程的思想。

5. UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<!-- namespace: bind interface -->
<mapper namespace="com.zzw.mapper.UserMapper">

    <!--  这里虽然真实返回值是List,但实际只需要写List里的范型的类型即可,注意User在这里要写成小写的user  -->
    <select id="selectUser" resultType="user">
        select * from mybatis.user;
    </select>

</mapper>

6. UserMapperImpl.java

这个实现类本质还是套娃:注入SqlSessionTemplate的依赖,其本质还是SqlSession。这个SqlSessionTemplate就是Mybatis-Spring的核心,增删改查都是用这个类来做的。SqlSessionTemplate是线程安全的,可以被多个DAO或者映射器所共享使用,具体可见SqlSessionTemplate在官方文档中的介绍

import com.zzw.pojo.User;
import org.mybatis.spring.SqlSessionTemplate;
import java.util.List;

// 这里相当于多套了一层,以后做事情不用new sqlSession,直接调用Spring管理的bean下面的方法
public class UserMapperImpl implements UserMapper{

    // 所有的操作,都由sqlSessionTemplate来做
    private SqlSessionTemplate sqlSessionTemplate;

    // 因为我们需要使用spring来进行依赖注入,必须要有set方法
    public void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate) {
        this.sqlSessionTemplate = sqlSessionTemplate;
    }

    // 这里虽然实现了UserMapper接口,但其实还是让sqlSession来获取映射器(反射)
    // 这个映射器下的方法实现(SQL语句)写在了XML里
    @Override
    public List<User> selectUser() {
        UserMapper mapper = sqlSessionTemplate.getMapper(UserMapper.class);
        return mapper.selectUser();
    }
}

注意:在整合SSM框架的案例中,用到了另一种方法:直接将DAO接口扫描到Spring容器中,而不用为DAO接口写实现类:

Spring-dao.xml

    <!--配置dao接口扫描包,动态的实现了把Dao接口注入到Spring容器中(本来还要写一个接口的实现类然后注册该实现类)-->
    <!--注册以下这个bean后,以后写的Dao接口都不需要去实现然后注册(只需要接口+XML/SQL),Spring都通过反射去做了-->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!--注入sqlSessionFactory-->
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
        <!--要扫描的dao包-->
        <property name="basePackage" value="com.zzw.dao"/>
    </bean>

并且,使用这种方法后,我们无需显式地去mybatis-config.xml去手动注册Mapper。

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="STDOUT_LOGGING"/>
    </settings>

<!--  Mybatis原本需要配置数据源,但是于Spring整合后,这个事情交给Spring去做  -->
    <typeAliases>
        <package name="com.zzw.pojo"/>
    </typeAliases>

<!--&lt;!&ndash;  绑定Mapper  &ndash;&gt;-->
<!--    <mappers>-->
<!--        &lt;!&ndash;如果用class:'.';如果用resource:'/'&ndash;&gt;-->
<!--        <mapper class="com.zzw.dao.BookMapper" />-->
<!--    </mappers>-->

</configuration>

所以关于Mapper的写法有3种:

  1. 写接口,写XML的SQL,在Mybatis配置文件中注册这个mapper
  2. 写接口,写XML的SQL,让Spring来扫描(有两种方式):1. 直接在sqlSessionFactory里用mapperLocations写出XML所在位置;2. 单独写一个bean来扫描dao的包(如上),即MapperScannerConfigurer
  3. 写接口,写XML,再写接口的实现类封装起来,注册到Spring里

7. applicationContext.xml

接下来需要把这个UserMapperImpl也注册到Spring容器里,可以创建一个applicationContext.xml专门用来管理这一类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:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       https://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/aop
       https://www.springframework.org/schema/aop/spring-aop.xsd">

	<!-- 把dataSource, SqlSessionFactory和SqlSession都导入 -->
    <import resource="spring-dao.xml" />

    <!-- 注册mapper的Impl -->
    <bean id="userMapper" class="com.zzw.mapper.UserMapperImpl">
        <property name="sqlSessionTemplate" ref="sqlSessionTemplate" />
    </bean>
</beans>

需要注意区分UserMapperUserMapper.xmlUserMapperImpl
UserMapper:Dao的接口 UserMapper.xml:接口的实现(SQL语句)
UserMapper.xml:真正实现Dao接口里方法的地方,写SQL语句的地方
UserMapperImpl:接口的实现类,本身不包含具体实现语句,但是封装了SqlSessionTemplate。核心逻辑代码:

UserMapper mapper = sqlSessionTemplate.getMapper(UserMapper.class);
return mapper.selectUser();

从外部看来,UserMapperImpl实现了UserMapper接口。但内部通过反射sqlSessionTemplate.getMapper(xxx.class)来获取具体接口(映射器)UserMapper,并调用里面的具体方法。(理解起来有点绕)

8. 测试

import com.zzw.mapper.UserMapper;
import com.zzw.pojo.User;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.List;

public class Mytest {
    @Test
    public void test() {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserMapper mapper = context.getBean("userMapper", UserMapper.class);
        List<User> userList = mapper.selectUser();
        for (User user : userList) {
            System.out.println(user);
        }
    }
}

运行结果:

User(id=1, name=jzm, pwd=321asdasda)
User(id=2, name=haha, pwd=123)
User(id=3, name=ryan, pwd=123)

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>Spring-Study</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>Spring_10_mybatis</artifactId>


    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.2</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.3.5</version>
        </dependency>
        <!--    Spring操作数据库的话,还需要一个Spring-JDBC    -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>5.3.5</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.6</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>2.0.6</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.18</version>
        </dependency>
    </dependencies>

    <build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>

</project>

项目结构

在这里插入图片描述

整合方法(二)

Spring整合的第二种方法本质就是第一种方法,只是在原来基础上省去了sqlSession的注入,而使用SqlSessionDaoSupport调用getSqlSession()来获取sqlSession可参考官方文档

调用getSqlSession() 方法你会得到一个SqlSessionTemplate,之后可以用于执行 SQL 方法。

原理就是,省去SqlSessionTemplate的注入,即以下的代码:

在这里插入图片描述
SqlSessionTemplate的注入会在SqlSessionDaoSupport这个类中完成(可参考源码):SqlSessionDaoSupport构造器需要传入一个SqlSessionFactory,然后在构造器中再利用这个Factory初始化SqlSessionTemplate。使用的时候正如上文所说,直接调用getSqlSession(),会得到一个SqlSessionTemplate

SqlSessionDaoSupport.java

public abstract class SqlSessionDaoSupport extends DaoSupport {

  private SqlSessionTemplate sqlSessionTemplate;

  /**
   * Set MyBatis SqlSessionFactory to be used by this DAO. Will automatically create SqlSessionTemplate for the given
   * SqlSessionFactory.
   *
   * @param sqlSessionFactory
   *          a factory of SqlSession
   */
  public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
    if (this.sqlSessionTemplate == null || sqlSessionFactory != this.sqlSessionTemplate.getSqlSessionFactory()) {
      this.sqlSessionTemplate = createSqlSessionTemplate(sqlSessionFactory);
    }
  }

  /**
   * Return the MyBatis SqlSessionFactory used by this DAO.
   *
   * @return a factory of SqlSession
   */
  public final SqlSessionFactory getSqlSessionFactory() {
    return (this.sqlSessionTemplate != null ? this.sqlSessionTemplate.getSqlSessionFactory() : null);
  }

采取这种方式后,spring-dao.xml中不再需要注册sqlSessionTemplate,只需要dataSourcesqlSessionFactory。然后在applicationContext.xml中注册一下UserMapperImpl2即可:

UserMapperImpl2.java

import com.zzw.pojo.User;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import java.util.List;

public class UserMapperImpl2 extends SqlSessionDaoSupport implements UserMapper{

    @Override
    public List<User> selectUser() {
        return getSqlSession().getMapper(UserMapper.class).selectUser();
    }
}

注意注册UserMapperImpl2时候需要注入sqlSessionFactory

applicationContext.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:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       https://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/aop
       https://www.springframework.org/schema/aop/spring-aop.xsd">

    <import resource="spring-dao.xml" />
    
    <bean id="userMapper2" class="com.zzw.mapper.UserMapperImpl2">
        <property name="sqlSessionFactory" ref="sqlSessionFactory" />
    </bean>

</beans>

Spring-dao.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:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       https://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/aop
       https://www.springframework.org/schema/aop/spring-aop.xsd">

<!-- DataSource: 使用Spring的数据源替换MyBatis的配置,这里使用Spring提供的JDBC:org.springframework.jdbc.datasource -->
    <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=false&amp;useUnicode=true&amp;characterEncoding=UTF-8" />
        <property name="username" value="root" />
        <property name="password" value="azhouzw94" />
    </bean>

<!-- sqlSessionFactory -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <!-- 绑定mybatis配置文件 -->
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
        <property name="mapperLocations" value="classpath:com/zzw/mapper/*.xml" />
    </bean>

</beans>

参考:

  1. 狂神说Java】Spring5最新完整教程IDEA版通俗易懂,P24
  2. Mybatis-Spring官方文档
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值