Spring 集成 MyBatis 笔记(Mybatis-Spring 的用法)-理论部分

Spring 集成 MyBatis 笔记(Mybatis-Spring 的用法)

说明:本文完全基于以下参考资料编写:
(1)mybatis-spring – MyBatis-Spring | 简介
http://mybatis.github.io/spring/zh/
请关注:第六章 注入映射器 这一章节。

(2)Mybatis整合Spring - 好好学习,天天向上 - ITeye技术网站
http://haohaoxuexi.iteye.com/blog/1843309

最重要的部分:

(1)通过 Mybatis-Spring 基于 SqlSessionFactoryBean
(2)配置两个 FactoryBean,一个是 SqlSessionFactoryBean,另一个是 MapperFactoryBean(不是最佳实践)。

下面的介绍来自《好好学习,天天向上》的博客:

Mybatis 的所有操作都是基于一个 SqlSession 的,而 SqlSession 是由 SqlSessionFactory 来产生的, SqlSessionFactory 又是由 SqlSessionFactoryBuilder 来生成的。但是 Mybatis-Spring 是基于SqlSessionFactoryBean 的。在使用 Mybatis-Spring 的时候,我们也需要 SqlSession ,而且这个 SqlSession 是内嵌在程序中的,一般不需要我们直接访问。 SqlSession 也是由 SqlSessionFactory 来产生的,但是 Mybatis-Spring 给我们封装了一个 SqlSessionFactoryBean ,在这个 bean 里面还是通过 SqlSessionFactoryBuilder 来建立对应的 SqlSessionFactory ,进而获取到对应的 SqlSession 。通过SqlSessionFactoryBean 我们可以通过对其指定一些属性来提供 Mybatis 的一些配置信息。所以接下来我们需要在 Spring 的 applicationContext 配置文件中定义一个 SqlSessionFactoryBean 。

集成步骤 1:配置数据源

说明:这里配置的的是 dbcp 的数据源,我们还可以配置 c3p0 或者 druid 数据源。

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
    <property name="driverClassName" value="${jdbc.driverClassName}"/>
    <property name="url" value="${jdbc.url}"/>
    <property name="username" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
</bean>

集成步骤 2:配置 SqlSessionFactoryBean

说明:id 应写为 sqlSessionFactory

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="mapperLocations" value="classpath:com/liwei/ssm/mapper/*Mapper.xml" />
    <property name="typeAliasesPackage" value="com.tiantian.ckeditor.model" />
    <property name="typeAliases">
    <array>
        <value>com.tiantian.mybatis.model.Blog</value>
        <value>com.tiantian.mybatis.model.Comment</value>
    </array>
</property>
</bean>

在定义 SqlSessionFactoryBean 的时候,dataSource 属性是必须指定的,它表示用于连接数据库的数据源。当然,我们也可以指定一些其他的属性,下面简单列举几个:
(1)apperLocations:它表示我们的 Mapper 文件存放的位置,当我们的 Mapper 文件跟对应的 Mapper 接口处于同一位置的时候可以不用指定该属性的值。
说明:约定大于配置的时候,可以不用配置。
(2)configLocation:用于指定 Mybatis 的配置文件位置。如果指定了该属性,那么会以该配置文件的内容作为配置信息构建对应的 SqlSessionFactoryBuilder ,但是后续属性指定的内容会覆盖该配置文件里面指定的对应内容。
说明:曹锋老师的项目一般都配置了这个。但是实际上是可以不配置这个属性的。
(3)typeAliasesPackage:它一般对应我们的实体类所在的包,如果配置了会自动取对应包中不包括包名的简单类名作为包括包名的别名。多个 package 之间可以用逗号或者分号等来进行分隔。
(4)typeAliases:数组类型,用来指定别名的。指定了这个属性后, Mybatis 会把这个类型的短名称作为这个类型的别名,前提是该类上没有标注 @Alias 注解,否则将使用该注解对应的值作为此种类型的别名。

还可以配置的信息有(我们学习到 MyBatis 的插件的时候,会用到,暂时可以略过):
plugins:数组类型,用来指定Mybatis的Interceptor。
typeHandlersPackage:用来指定TypeHandler所在的包,如果指定了该属性,SqlSessionFactoryBean会自动把该包下面的类注册为对应的TypeHandler。多个package之间可以用逗号或者分号等来进行分隔。
typeHandlers:数组类型,表示TypeHandler。

集成步骤 3 :配置 MapperFactoryBean(不是最佳实践)

接下来就是在 Spring 的 applicationContext 文件中定义我们想要的 Mapper 对象对应的 MapperFactoryBean 了。通过 MapperFactoryBean 可以获取到我们想要的Mapper 对象。 MapperFactoryBean 实现了 Spring 的 FactoryBean 接口,所以MapperFactoryBean 是通过 FactoryBean 接口中定义的 getObject 方法来获取对应的 Mapper 对象的。在定义一个 MapperFactoryBean的时候有两个属性需要我们注入,一个是 Mybatis-Spring 用来生成实现了 SqlSession 接口的SqlSessionTemplate 对象的 sqlSessionFactory ;另一个就是我们所要返回的对应的 Mapper 接口了。

定义好相应 Mapper 接口对应的 MapperFactoryBean 之后,我们就可以把我们对应的 Mapper 接口注入到由 Spring 管理的 bean 对象中了,比如 Service bean 对象。这样当我们需要使用到相应的 Mapper 接口时, MapperFactoryBean 会从它的 getObject 方法中获取对应的 Mapper 接口,而 getObject 内部还是通过我们注入的属性调用 SqlSession 接口的 getMapper ( Mapper 接口) 方法来返回对应的 Mapper 接口的。这样就通过把 SqlSessionFactory 和相应的 Mapper 接口交给 Spring 管理实现了 Mybatis 跟 Spring 的整合。

示例代码:

<bean id="blogMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
   <property name="mapperInterface"
       value="com.tiantian.mybatis.mapper.BlogMapper" />
   <property name="sqlSessionFactory" ref="sqlSessionFactory" />
</bean>

集成步骤 3:配置 MapperScannerConfigurer(最佳实践,配置了它就自动注册了 MapperFactoryBean )

利用上面的方法进行整合的时候,我们有一个 Mapper 就需要定义一个对应的 MapperFactoryBean ,当我们的 Mapper 比较少的时候,这样做也还可以,但是当我们的 Mapper 相当多时我们再这样定义一个个 Mapper 对应的 MapperFactoryBean 就显得速度比较慢了。为此 Mybatis-Spring 为我们提供了一个叫做 MapperScannerConfigurer 的类,通过这个类 Mybatis-Spring 会自动为我们注册 Mapper 对应的 MapperFactoryBean 对象

如果我们需要使用 MapperScannerConfigurer 来帮我们自动扫描和注册 Mapper 接口的话我们需要在 Spring 的 applicationContext 配置文件中定义一个 MapperScannerConfigurer 对应的 bean 。对于 MapperScannerConfigurer 而言有一个属性是我们必须指定的,那就是 basePackagebasePackage 是用来指定 Mapper 接口文件所在的基包的,在这个基包或其所有子包下面的 Mapper 接口都将被搜索到。多个基包之间可以使用逗号或者分号进行分隔。最简单的MapperScannerConfigurer 定义就是只指定一个 basePackage 属性,如:

参考代码:

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
   <property name="basePackage" value="com.tiantian.mybatis.mapper" />
</bean>

这样 MapperScannerConfigurer 就会扫描指定基包下面的所有接口,并把它们注册为一个个 MapperFactoryBean 对象。

有时候我们指定的基包下面的并不全是我们定义的 Mapper 接口,为此 MapperScannerConfigurer 还为我们提供了另外两个可以缩小搜索和注册范围的属性。一个是 annotationClass,另一个是 markerInterface
(1)annotationClass:
当指定了annotationClass 的时候,MapperScannerConfigurer将只注册使用了 annotationClass 注解标记的接口。
(2)markerInterface:
markerInterface 是用于指定一个接口的,当指定了 markerInterface 之后,MapperScannerConfigurer 将只注册继承自 markerInterface 的接口。

如果上述两个属性都指定了的话,那么 MapperScannerConfigurer 将取它们的并集,而不是交集。即使用了 annotationClass 进行标记或者继承自 markerInterface 的接口都将被注册为一个 MapperFactoryBean
现在假设我们的 Mapper 接口都继承了一个 SuperMapper 接口,那么我们就可以这样来定义我们的 MapperScannerConfigurer

参考代码:

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
   <property name="basePackage" value="com.tiantian.mybatis.mapper" />
   <property name="markerInterface" value="com.tiantian.mybatis.mapper.SuperMapper"/>
</bean>

如果是都使用了注解 MybatisMapper 标记的话,那么我们就可以这样来定义我们的MapperScannerConfigurer

参考代码:

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
   <property name="basePackage" value="com.tiantian.mybatis.mapper" />
   <property name="annotationClass" value="com.tiantian.mybatis.annotation.MybatisMapper"/>
</bean>

笔者说明:下面的描述很重要。

除了用于缩小注册 Mapper 接口范围的属性之外,我们还可以指定一些其他属性,如:
(1)sqlSessionFactory:这个属性已经废弃。当我们使用了多个数据源的时候我们就需要通过sqlSessionFactory来指定在注册MapperFactoryBean的时候需要使用的SqlSessionFactory,因为在没有指定sqlSessionFactory的时候,会以Autowired的方式自动注入一个。换言之当我们只使用一个数据源的时候,即只定义了一个SqlSessionFactory的时候我们就可以不给MapperScannerConfigurer指定SqlSessionFactory。
(2)sqlSessionFactoryBeanName(最佳实践):它的功能跟 sqlSessionFactory 是一样的,只是它指定的是定义好的 SqlSessionFactory 对应的 bean 名称。

参考代码:

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
   <property name="basePackage" value="com.tiantian.mybatis.mapper" />
   <property name="markerInterface" value="com.tiantian.mybatis.mapper.SuperMapper"/>
   <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>

注意:使用 IntelliJ IDEA 工具建 package 的时候,一定要在自己的文件夹看一看是否已经成功建夹。

(3)sqlSessionTemplate:这个属性已经废弃。它的功能也是相当于 sqlSessionFactory 的,因为就像前面说的那样, MapperFactoryBean 最终还是使用的 SqlSession 的 getMapper 方法取的对应的 Mapper 对象。当定义有多个 SqlSessionTemplate 的时候才需要指定它。对于一个 MapperFactoryBean 来说 SqlSessionFactory 和 SqlSessionTemplate 只需要其中一个就可以了,当两者都指定了的时候, SqlSessionFactory 会被忽略。
(4)sqlSessionTemplateBeanName:指定需要使用的sqlSessionTemplate对应的bean名称。

注意:由于使用 sqlSessionFactory 和 sqlSessionTemplate 属性时会使一些内容在 PropertyPlaceholderConfigurer 之前加载,导致在配置文件中使用到的外部属性信息无法被及时替换而出错,因此官方现在新的 Mybatis-Spring 中已经把 sqlSessionFactory 和 sqlSessionTemplate 属性废弃了,推荐大家使用 sqlSessionFactoryBeanName 属性和 sqlSessionTemplateBeanName 属性。


我们这里以 dbcp 数据源为例。

1、引入相关的 jar 包坐标依赖

        <!-- 引入 Spring 的坐标依赖 -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${spring.version}</version>
        </dependency>

        <!-- dbcp 数据源 -->
        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>1.4</version>
        </dependency>

        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.2.3</version>
        </dependency>

2、编写 Spring4 的核心配置文件

配置文件参考片段:

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

    <context:property-placeholder location="classpath:datasource.properties" />

    <!-- 第 1 步:配置数据源 -->
    <!--本示例采用 DBCP 连接池,应预先把 DBCP 的 jar 包复制到工程的 lib 目录下。 -->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="${jdbc.driverClassName}" />
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
        <!-- 查这里配置的意思 -->
        <!-- MaxActive,连接池的最大数据库连接数。设为0表示无限制。 -->
        <property name="maxActive" value="10"></property>
        <!-- maxIdle,最大空闲数,数据库连接的最大空闲时间。超过空闲时间,数据库连接将被标记为不可用,然后被释放。设为 0 表示无限制。 -->
        <property name="maxIdle" value="10"></property>
        <!-- 查这里配置的意思 -->
    </bean>

    <!-- 第 2 步:SqlSessionFactoryBean (这里须要 MyBatis 与 Spring 整合的 jar 包) -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- dataSource 属性指定要用到的连接池 -->
        <property name="dataSource" ref="dataSource" />
        <!-- configLocation 属性指定 mybatis 的核心配置文件 -->
        <property name="configLocation" value="classpath:config.xml" />
    </bean>

    <!-- 第 3 步:注册接口 -->
    <bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
        <property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
        <property name="mapperInterface" value="com.liwei.mybatis.mapper.IUserOper"></property>
    </bean>

</beans>

3、编写测试代码

private ApplicationContext ctx;
    @Before
    public void before(){
        ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
    }

    @Test
    public void test01(){

        DataSource dataSource = (DataSource) ctx.getBean("dataSource");
        System.out.println(dataSource);
    }
    @Test
    public void test02(){
        IUserOper userDao = (IUserOper)ctx.getBean("userMapper");
        List<Article> articles = userDao.getUserArticles(1);
        for(Article a : articles){
            System.out.println(a);
        }
    }

补充:数据库连接的配置文件。

# 说明:如果这里直接写 username , MyBatis 会使用系统的 username 值注入进入,就会出现莫名其妙的情况了。
jdbc.driverClassName = com.mysql.jdbc.Driver
jdbc.url = jdbc:mysql://127.0.0.1:3306/mybatisinaction?characterEncoding=utf8
jdbc.username = root
jdbc.password = 123456

补充:在我们使用 maven 的过程中,如果发现默认的中央仓库比较慢,可以配置一下镜像,参考的镜像为:

<mirror>
      <id>UK</id>
      <name>UK Central</name>
      <url>http://uk.maven.org/maven2</url>
      <mirrorOf>central</mirrorOf>
    </mirror>
<build>
        <defaultGoal>compile</defaultGoal>
        <plugins>
            <!-- 编译的时候使用JDK7和UTF8编码 -->
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>1.7</source>
                    <target>1.7</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
        </plugins>
    </build>
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值