zoukankan      html  css  js  c++  java
  • spring+mybatis管理多个数据源(非分布式事务)

    本文通过一个demo,介绍如何使用spring+mybatis管理多个数据源,注意,本文的事务管理并非之前博文介绍的分布式事务。

    这个demo将使用两个事务管理器分别管理两个数据源。对于每一个独立的事务,只涉及一个数据源。

    demo功能:实现一个能依靠两个独立的事务管理器互不干涉的管理自己的数据源的web demo。

    demo将实现:

    1.独立地控制两个不同的数据源的事务管理器。

    测试方式:restful web api

     

    使用工具:

    spring 4.1.1.RELEASE

    mybatis 3.2.7

    tomcat 7

     

    在mysql中建立两个schema,分别为dev和qa。并在里面分别建立一张名字表。

    schema:dev

    table:namaDev

    id | nameDev

     

    scheme:qa

    table:nameQa

    id  |  nameQa

    对应的sql为

     1 CREATE SCHEMA `qa` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ;
     2 CREATE SCHEMA `dev` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci ;
     3 
     4  CREATE  TABLE `dev`.`nameDev` (
     5   `id` BIGINT NOT NULL AUTO_INCREMENT ,
     6   `nameDev` VARCHAR(45) NULL ,
     7   PRIMARY KEY (`id`) ,
     8   UNIQUE INDEX `id_UNIQUE` (`id` ASC) );
     9 
    10   CREATE  TABLE `qa`.`nameQa` (
    11   `id` BIGINT NOT NULL AUTO_INCREMENT ,
    12   `nameQa` VARCHAR(45) NULL ,
    13   PRIMARY KEY (`id`) ,
    14   UNIQUE INDEX `id_UNIQUE` (`id` ASC) );
    create sql

    代码分析:

    本项目使用spring框架,因此首先配置相关bean

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     3        xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context"
     4        xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
     5        xmlns:rabbit="http://www.springframework.org/schema/rabbit"
     6        xmlns:cache="http://www.springframework.org/schema/cache" xmlns:task="http://www.springframework.org/schema/task"
     7        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/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd http://www.springframework.org/schema/rabbit http://www.springframework.org/schema/rabbit/spring-rabbit.xsd
     8        http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task.xsd">
     9     <context:component-scan base-package="com.xy">
    10         <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    11     </context:component-scan>
    12     <context:property-placeholder location="classpath:context/database.properties"/>
    13     <tx:annotation-driven/>
    14 
    15     <bean id="qadataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
    16                  destroy-method="close">
    17         <property name="jdbcUrl" value="${qa.db.url}"></property>
    18         <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
    19         <property name="user" value="${qa.db.user}"></property>
    20         <property name="password" value="${qa.db.password}"></property>
    21         <property name="maxPoolSize" value="20"></property>
    22         <property name="minPoolSize" value="20"></property>
    23         <property name="initialPoolSize" value="20"></property>
    24         <property name="maxIdleTime" value="200"></property>
    25         <!--<property name="numHelperThreads" value="50"></property>-->
    26     </bean>
    27 
    28     <bean id="devdataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
    29           destroy-method="close">
    30         <property name="jdbcUrl" value="${dev.db.url}"></property>
    31         <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
    32         <property name="user" value="${dev.db.user}"></property>
    33         <property name="password" value="${dev.db.password}"></property>
    34         <property name="maxPoolSize" value="20"></property>
    35         <property name="minPoolSize" value="20"></property>
    36         <property name="initialPoolSize" value="20"></property>
    37         <property name="maxIdleTime" value="200"></property>
    38         <!--<property name="numHelperThreads" value="50"></property>-->
    39     </bean>
    40 
    41 
    42 
    43 
    44 
    45     <bean id="qasqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    46         <property name="dataSource" ref="qadataSource" />
    47         <!--<property name="mapperLocations" value="classpath*:mapper/**/*.xml" />-->
    48     </bean>
    49 
    50     <bean id="devsqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    51         <property name="dataSource" ref="devdataSource" />
    52         <!--<property name="mapperLocations" value="classpath*:mapper/**/*.xml" />-->
    53     </bean>
    54 
    55     <bean id="qaManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    56         <property name="dataSource" ref="qadataSource" />
    57     </bean>
    58 
    59     <bean id="devManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    60         <property name="dataSource" ref="devdataSource" />
    61     </bean>
    62 
    63 
    64 
    65     <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    66         <property name="basePackage" value="com.xy.dao"/>
    67         <property name="sqlSessionFactoryBeanName" value="qasqlSessionFactory" />
    68     </bean>
    69 
    70     <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    71         <property name="basePackage" value="com.xy.daodev"/>
    72         <property name="sqlSessionFactoryBeanName" value="devsqlSessionFactory" />
    73     </bean>
    74 
    75 
    76 </beans>

    其中qadataSource和devdataSource是对应两个数据库的数据源,qasqlSessionFactory和devsqlSessionFactory是mybatis的sessionfactory,两个MapperScannerConfigurer自动将不同数据源的sql语句文件与interface自动装配起来。qaManager与devManage分别管理qadataSource和devdataSource的事务,互不干涉。

    Model类如下:package com.xy.model

    package com.xy.model;
    
    /**
     * Created by helloworld on 2015/1/30.
     */
    public class NameDev {
        private long id;
        private String nameDev;
    
        public long getId() {
            return id;
        }
    
        public void setId(long id) {
            this.id = id;
        }
    
        public String getNameDev() {
            return nameDev;
        }
    
        public void setNameDev(String nameDev) {
            this.nameDev = nameDev;
        }
    }
    NameDev
     1 package com.xy.model;
     2 
     3 /**
     4  * Created by helloworld on 2015/1/30.
     5  */
     6 public class NameQa {
     7     private long id;
     8     private String nameQa;
     9 
    10     public long getId() {
    11         return id;
    12     }
    13 
    14     public void setId(long id) {
    15         this.id = id;
    16     }
    17 
    18     public String getNameQa() {
    19         return nameQa;
    20     }
    21 
    22     public void setNameQa(String nameQa) {
    23         this.nameQa = nameQa;
    24     }
    25 }
    NameQa

    qa数据源的mybatis mapper接口 package com.xy.dao

     1 package com.xy.dao;
     2 
     3 import com.xy.model.NameQa;
     4 
     5 /**
     6  * Created by helloworld on 2015/1/30.
     7  */
     8 public interface NameQaMapper {
     9     int insert(NameQa nameQa);
    10 }
    NameQaMapper

    dev数据源的mybatis mapper接口 package com.xy.devdao

     1 package com.xy.daodev;
     2 
     3 import com.xy.model.NameDev;
     4 
     5 /**
     6  * Created by helloworld on 2015/1/30.
     7  */
     8 public interface NameDevMapper {
     9     int insert(NameDev nameDev);
    10 }
    NameDevMapper

    处理事务的service

     1 package com.xy.service;
     2 
     3 import com.xy.dao.NameQaMapper;
     4 import com.xy.daodev.NameDevMapper;
     5 import com.xy.model.NameDev;
     6 import com.xy.model.NameQa;
     7 import org.springframework.beans.factory.annotation.Autowired;
     8 import org.springframework.stereotype.Service;
     9 import org.springframework.transaction.annotation.Transactional;
    10 
    11 /**
    12  * Created by helloworld on 2015/1/30.
    13  */
    14 @Service
    15 public class NameService {
    16     @Autowired
    17     NameQaMapper nameQaMapper;
    18     @Autowired
    19     NameDevMapper nameDevMapper;
    20 
    21     @Transactional(value = "qaManager", rollbackFor = Exception.class)
    22     public void addQa(boolean withQaException) throws Exception {
    23         NameQa nameQa = new NameQa();
    24         nameQa.setNameQa("hello");
    25         nameQaMapper.insert(nameQa);
    26 
    27         if(withQaException){
    28             throw new Exception();
    29         }
    30     }
    31 
    32     @Transactional(value = "devManager", rollbackFor = Exception.class)
    33     public void addDev(boolean withDevException) throws Exception {
    34         NameDev nameDev = new NameDev();
    35         nameDev.setNameDev("hello");
    36         nameDevMapper.insert(nameDev);
    37 
    38         if(withDevException){
    39             throw new Exception();
    40         }
    41     }
    42 
    43 }
    NameService

    controller代码

     1 package com.xy.controller;
     2 
     3 import com.xy.service.NameService;
     4 import org.springframework.beans.factory.annotation.Autowired;
     5 import org.springframework.stereotype.Controller;
     6 import org.springframework.ui.ModelMap;
     7 import org.springframework.web.bind.annotation.RequestMapping;
     8 import org.springframework.web.bind.annotation.RequestMethod;
     9 import org.springframework.web.bind.annotation.RequestParam;
    10 
    11 /**
    12  * Created by helloworld on 2014/11/22.
    13  */
    14 @Controller
    15 public class mybatisController {
    16 
    17     @Autowired
    18     NameService nameService;
    19 
    20     @RequestMapping(value = "/addName", method = RequestMethod.POST)
    21     ModelMap addName(@RequestParam("withDevException") boolean withDevException,
    22                      @RequestParam("witQaException") boolean witQaException ) {
    23         try {
    24             nameService.addDev(withDevException);
    25         } catch (Exception e) {
    26             e.printStackTrace();
    27         }
    28 
    29         try {
    30             nameService.addQa(witQaException);
    31         } catch (Exception e) {
    32             e.printStackTrace();
    33         }
    34         return new ModelMap("true");
    35     }
    36 
    37 
    38 }
    controller

    将项目打成war包,命名为mybatis.war部署在tomcat上。

    测试:

    1.POST  http://localhost:8080/mybatis/addName.json

    request parameters:
    withDevException=false
    witQaException=false
    返回:true 两个数据都添加成功

    2.POST  http://localhost:8080/mybatis/addName.json

    request parameters:
    withDevException=false
    witQaException=true
    返回:true 只有dev添加成功
    源码下载:https://files.cnblogs.com/files/rain-in-sun/springmvc-mybatis-multidatasource.rar
  • 相关阅读:
    程序自动更新版本
    [.NET] Rough Dependency Injection
    Python标准库存储对象(pickle包,cPickle包)
    发送邮件,支持群发
    css3传送带示例
    “计算机之子”的MVVM框架源码学习笔记
    Windows 8 应用商店正式面向全部开发者开放
    MVVM框架 v1发布
    Python学习索引
    注册 windows 8 开发者账号
  • 原文地址:https://www.cnblogs.com/rain-in-sun/p/4314283.html
Copyright © 2011-2022 走看看