首页 > 技术文章 > Mybatis和spring整合

hfx123 2018-09-26 11:18 原文

mybatis和spring整合也就是把两者的优点集合到一起下面我们看下配置步骤

  1. 导入jar

    1. 整合spring和mybatis需要mybatis-spring.jar我用的是1.2.0版本
    2. 整合需要用到spring数据源和事物支持,需要spring-jdbc和spring-tx的包
    3. spring中使用具体的数据源实现,此次需要dbcp,commons-dbcp及commons-pool包
    4. 导入后如图所示
    5. spring官网下载地址:https://repo.spring.io/webapp/#/artifacts/browse/tree/General/libs-release-local/org/springframework/spring/4.3.2.RELEASE
    6. 另一个地址:http://repo.spring.io/release/org/springframework/spring/
    7. mybatis官网下载地址:https://github.com/mybatis/mybatis-3/releases
  2. mybatis的配置请参考我之前的这篇:https://www.cnblogs.com/hfx123/p/9590509.html

  3. 搭建好mybatis框架后确保mybatis环境搭建没有错误,在此基础上进行spring融合

    1. 修改配置文件
      1. 首先需要把mybatis中数据库连接和映射mapper文件的部分删除 如下
      2. <properties resource="database.properties"/>
      3. <environments default="dpCommodity">
                <environment id="dpCommodity">
                    <transactionManager type="JDBC"/>
                    <dataSource type="POOLED">
                        <property name="driver" value="${driver}"/>
                        <property name="url" value="${url}"/>
                        <property name="username" value="${user}"/>
                        <property name="password" value="${pwd}"/>
                    </dataSource>
                </environment>
            </environments>
            <mappers>
                <mapper resource="cn/dao/CommodityMapper.xml"/>
            </mappers>
    2. 删除之后新建spring配置文件导入database.properties文件
      <!-- 引入properties文件 -->
           <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
               <property name="location" value="classpath:database.properties"/>
           </bean>

      之后配置数据源其中大括号里面的名称对应 database.properties文件中的名称

    3. <!-- 配置数据源 -->
           <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
               <property name="driverClassName" value="${driver}"/>
               <property name="url" value="${url}"/>
               <property name="username" value="${user}"/>
               <property name="password" value="${pwd}"/>
           </bean>

       database文件内容如下:

    4. 配置sqlSessionFactory
      <!-- 配置sqlSessionFactory -->
          <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
              <!-- 引用数据源组件 -->
              <property name="dataSource" ref="dataSource"/>
              <!-- 引用mybatis配置文件中的配置 -->
              <property name="configLocation" value="classpath:mybatis-config.xml"/>
              <!-- 配置SQL映射文件信息 -->
              <property name="mapperLocations">
                  <list>
                      <value>classpath:cn/dao/**/*.xml</value>
                  </list>
              </property>
          </bean>

      其他配置 

<!-- 配置SQLsessionTemplate -->
    <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
        <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory"/>
    </bean>
    <!--  配置dao组件并注入SQLsession  session为实现类中的属性 class中的路径为 所需要使用接口的实现类路径--> 
    <bean id="workinggMapper" class="cn.dao.impl.WorkinggMapperImpl">
        <property name="session" ref="sqlSessionTemplate"/>
    </bean>
    <!-- 配置业务bean并且注入 wM为业务bean中的属性 class中的路径为 所需要使用接口的业务实现bean路径 -->
    <bean id="workinggService" class="cn.service.impl.WorkinggServiceImpl">
        <property name="wM" ref="workinggMapper"/>
    </bean>
  1. 测试

    1. 测试类代码如下
      public class Test {
          public static void main(String[] args) {
              ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
              WorkinggService cs = (WorkinggServiceImpl)ctx.getBean("workinggService");
              List<Workingg> cList = cs.allWorking();
              for (Workingg w : cList) {
                  System.out.println(w.getTitle());
              }
          }
      }

自动生成映射器实现类

    1. 其实还有另外一种配置方法,因为上面的配置方法如果我换一个接口,那么又要修改配置文件那么有没有好点的方法呢

        <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
              <!-- basePackage属性指定了扫描的基准包,MapperScannerConfigurer将递归扫描基准包(包括下面的子包)下所有接口
                  如果他们在sql映射文件中定义过,则将他们动态注册为mapperFactoryBean,这样既可批量产生映射器实现类
              -->
              <property name="basePackage" value="cn.dao"/>    
          </bean>

      通过上面这一步就可以让它自动生成映射器实现类,其中basePackage属性中可以包含多个包名,多个包名直接使用逗号或分号隔开

    2. 注意如果sqlSessionFactory配置了多个那么自动装配则无法进行,需要指定 sqlSessionFactory如下

      <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
              <!-- basePackage属性指定了扫描的基准包,MapperScannerConfigurer将递归扫描基准包(包括下面的子包)下所有接口
                  如果他们在sql映射文件中定义过,则将他们动态注册为mapperFactoryBean,这样既可批量产生映射器实现类
              -->
              <property name="basePackage" value="cn.dao"/>
              <!-- 注意此属性时name,而不是sqlSessionFactory,为其赋值使用的是 value -->
              <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>    
          </bean>

      如上则可以自动生成映射器实现类 

      <!-- 定义业务bean -->
          <bean id="workinggService" class="cn.service.impl.WorkinggServiceImpl">
              <property name="wM" ref="workinggMapper"/>
          </bean>

      自动生成映射器实现类的名字默认为,接口名第一个单词小写后面的不变 如接口名:WorkinggMapper 默认名称:workinggMapper

    3. 注意:SQL映射文件中必须遵循以下命名规则
      1. 映射命名空间和映射器接口的名称相同
      2. 映射元素的id和映射器接口的方法相同

使用注解定义业务bean

    通过上面的改造,可不用手动生成映射器实现类了但是去依然要写业务bean,这时候就有了注解当需要某种业务bean时执行添加注解即可

    如下吧之前生成业务bean的代码替换成

  <!-- 自动扫描cn下面所包(包括子包)下面所有类 -->
    <context:component-scan base-package="cn"/>

再在业务bean中写两个注释即可如下

 

业务bean继承SqlSessionDaoSupport类

  修改之前的业务bean如下

package cn.service.impl;

import java.util.List;

import javax.annotation.Resource;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Service;

import cn.dao.WorkinggMapper;
import cn.pojo.Workingg;
import cn.service.WorkinggService;

//加上这行注释扫描的时候则 会自动生成名为workinggService的业务bean
@Service("workinggService")
public class WorkinggServiceImpl implements WorkinggService {
    //扫描时会自动注入 WorkinggMapper
    @Resource
    WorkinggMapper wM;
    public WorkinggMapper getwM() {
        return wM;
    }

    public void setwM(WorkinggMapper wM) {
        this.wM = wM;
    }

    @Override
    public int screenTitle(String title) {
        
        return wM.screenTitle(title);
    }

    @Override
    public Workingg screenId(Integer id) {
        // TODO Auto-generated method stub
        return wM.screenId(id);
    }

    @Override
    public List<Workingg> allWorking() {
        // TODO Auto-generated method stub
        return wM.allWorking();
    }

    @Override
    public int count() {
        // TODO Auto-generated method stub
        return wM.count();
    }

    @Override
    public int addWorking(Workingg workingg) {
        // TODO Auto-generated method stub
        return wM.addWorking(workingg);
    }

    @Override
    public int del(Integer id) {
        // TODO Auto-generated method stub
        return wM.del(id);
    }

    @Override
    public int modify(Workingg workingg) {
        // TODO Auto-generated method stub
        return wM.modify(workingg);
    }
    public static WorkinggService getWorkinggService() {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        WorkinggService wService = (WorkinggServiceImpl)ctx.getBean("WorkinggService");
        return wService;
    }
}

继承之后dao的实现类就没什么用了,因为业务类以及不依赖dao的实现类了,继承后代码如下

package cn.service.impl;

import java.util.List;

import org.mybatis.spring.support.SqlSessionDaoSupport;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Service;

import cn.dao.WorkinggMapper;
import cn.pojo.Workingg;
import cn.service.WorkinggService;
public class WorkinggServiceImpl extends SqlSessionDaoSupport implements WorkinggService {

    @Override
    public int screenTitle(String title) {
        
        return super.getSqlSession().getMapper(WorkinggMapper.class).screenTitle(title);
    }

    @Override
    public Workingg screenId(Integer id) {
        // TODO Auto-generated method stub
        return super.getSqlSession().getMapper(WorkinggMapper.class).screenId(id);
    }

    @Override
    public List<Workingg> allWorking() {
        // TODO Auto-generated method stub
        return super.getSqlSession().getMapper(WorkinggMapper.class).allWorking();
    }

    @Override
    public int count() {
        // TODO Auto-generated method stub
        return super.getSqlSession().getMapper(WorkinggMapper.class).count();
    }

    @Override
    public int addWorking(Workingg workingg) {
        // TODO Auto-generated method stub
        return super.getSqlSession().getMapper(WorkinggMapper.class).addWorking(workingg);
    }

    @Override
    public int del(Integer id) {
        // TODO Auto-generated method stub
        return super.getSqlSession().getMapper(WorkinggMapper.class).del(id);
    }

    @Override
    public int modify(Workingg workingg) {
        // TODO Auto-generated method stub
        return super.getSqlSession().getMapper(WorkinggMapper.class).modify(workingg);
    }
    public static WorkinggService getWorkinggService() {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        WorkinggService wService = (WorkinggServiceImpl)ctx.getBean("WorkinggService");
        return wService;
    }
}

修改前的配置文件有映射,继承之后不需要了

把这一段替换成了这段,测试类代码不变就好了

<bean id="workinggService" class="cn.service.impl.WorkinggServiceImpl">
        <property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
    </bean>

不清楚的可以去网盘下载这个项目跑下

链接:https://pan.baidu.com/s/1IaWdAkeK97V_XWcuzDdeLg 密码:l2ji

 

推荐阅读