Spring+SpringMVC+Mybatis 多数据源整合

此篇文章是基于Spring3.0和mybatis3.2的
总体大概流程

1. 拷贝所需jar

2.写一个数据库切换的工具类:DataSourceContextHolder,用来切换数据库
3.写一个DynamicDataSource类来继承AbstractRoutingDataSource,并重写determineCurrentLookupKey()方法,来达到动态切换数据库
4. 创建springmvc-servlet.xml文件,然后创建spring配置文件(beans.xml)
5. 在beans.xml文件中配置数据源。我这里配置的三个数据源
6. 在beans.xml文件中创建sqlSessionFactory实例
7. 在beans.xml文件中配置事物、事物的传播性
8. 在beans.xml文件中配置AOP
9. 创建一个User对象,配置User.xml文件。写一个UserMapper接口,用来操作User对象的接口
10. 将User类的路径以及User.xml文件的路径在mybatis-config.xml文件中配置
11. 写一个UserService接口(接口里面的方法和UserMapper接口里面的方法一致,返回值和参数可不同,方法名最好一致),并写UserServiceImpl来实现UserService接口
12.写Controller类,并在其中写相对应的方法,给外部调用


下面看一下我的工程的目录:
common包存放的是一些公用类
controller包下放的是提供给外部访问的接口的(.do)类
datasource包下是用来配置数据库
entity:实体类

mapper:.....存放XXMapper以及实体类的对应表的关系的xml文件

Spring+SpringMVC+Mybatis 多数据源整合_第1张图片




下面一步步的来讲解:

1、拷贝jar文件。需要的jar文件入下图所示,因为我的项目中用到了json解析,所以导入了json相关的包

Spring+SpringMVC+Mybatis 多数据源整合_第2张图片


2.写一个数据库切换的工具类:DataSourceContextHolder,用来切换数据库

public class DataSourceContextHolder {
     private static final ThreadLocal contextHolder = new ThreadLocal();

     public static void setDbType(String dbType) {
            contextHolder.set(dbType);
     }

     public static String getDbType() {
            return ((String) contextHolder.get());
     }

     public static void clearDbType() {
            contextHolder.remove();
     }
}

3.写一个DynamicDataSource类来继承AbstractRoutingDataSource,并重写determineCurrentLookupKey()方法,来达到动态切换数据库

import java.sql.SQLFeatureNotSupportedException;
import java.util.logging.Logger;

import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

public class DynamicDataSource extends AbstractRoutingDataSource {

     @Override
     public Logger getParentLogger() throws SQLFeatureNotSupportedException {
            return null;
     }

     @Override
     protected Object determineCurrentLookupKey() {
            return DataSourceContextHolder. getDbType();
     }

}

4. 创建springmvc-servlet.xml文件,然后创建spring配置文件(beans.xml),看一下我的springmvc-servlet.xml文件。
   这里配置了一个注解扫描器,一般填自己的主包名就可以了,他会自动扫描我的com.baimi.routerweb包下面所有的带注解的类或者方法,常变量等。
   还配置了一个视图解析器(如果需要用到jsp文件,就需要配置此解析器)
   最后引入我的spring的配置文件:beans.xml文件




      
      
      
      
      
             
             
      
      
      




5. 在beans.xml文件中配置数据源。我这里配置的三个数据源,不过在配置数据源之前,先配置一下注解扫描器。然后我接着配置了三个数据源,然后配置动态数据源

   

      
      
             
             
             
             
      
      
             
             
             
             
      
      
             
             
             
             
      

      
      
             
                   
                         
                         
                         
                   
             
                   
      

6. 在beans.xml文件中创建sqlSessionFactory实例

      
      
             
             
             
             
      

7. 在beans.xml文件中配置事物、事物的传播性


      
             
      

      
      
             
      

      
      
             
                   
                   
                   
                   
                   
                   
             
      

8. 在beans.xml文件中配置AOP,注意这里,expression 后面一定要是自己程序所在包名,复制的时候一定要改掉

      
      
             
             
             
      

9. 创建一个User对象,配置User.xml文件。写一个UserMapper接口,用来操作User对象的接口。
    User类属性有点长,请忽略这些属性

  public class User {
     private int userId;
     private int compId;
     private String euserName;
     private String euserPhone;
     private int euserStatus;
     private String eAddTime;
     private String eLeaveTime;
     private String eUserNameCn;
     private int cUserId;
     private String scDown;
     private String userDesc;

     public int getUserId() {
            return userId;
     }

     public void setUserId( int userId) {
            this. userId = userId;
     }

     public int getCompId() {
            return compId;
     }

     public void setCompId( int compId) {
            this. compId = compId;
     }

     public String getEuserName() {
            return euserName;
     }

     public void setEuserName(String euserName) {
            this. euserName = euserName;
     }

     public String getEuserPhone() {
            return euserPhone;
     }

     public void setEuserPhone(String euserPhone) {
            this. euserPhone = euserPhone;
     }

     public int getEuserStatus() {
            return euserStatus;
     }

     public void setEuserStatus( int euserStatus) {
            this. euserStatus = euserStatus;
     }

     public String geteAddTime() {
            return eAddTime;
     }

     public void seteAddTime(String eAddTime) {
            this. eAddTime = eAddTime;
     }

     public String geteLeaveTime() {
            return eLeaveTime;
     }

     public void seteLeaveTime(String eLeaveTime) {
            this. eLeaveTime = eLeaveTime;
     }

     public String geteUserNameCn() {
            return eUserNameCn;
     }

     public void seteUserNameCn(String eUserNameCn) {
            this. eUserNameCn = eUserNameCn;
     }

     public int getcUserId() {
            return cUserId;
     }

     public void setcUserId( int cUserId) {
            this. cUserId = cUserId;
     }

     public String getScDown() {
            return scDown;
     }

     public void setScDown(String scDown) {
            this. scDown = scDown;
     }

     public String getUserDesc() {
            return userDesc;
     }

     public void setUserDesc(String userDesc) {
            this. userDesc = userDesc;
     }
}  


编写UserMapper接口,这里面的方法是用来操作User对象的,我这里只是一个简单的根据手机号码,得到这个User对象
public interface UserMapper {
     public User getUser(String euserPhone);
}

编写User.xml文件,该文件里面配置User类里面的属性和表中的那些字段进行对应,以及在UserMapper中定义的查询的方法,在User.xml中写上对应的查询语句,我这里是查的t_expand_user 表





      
             
             
             
             
             
             
             
             
             
             
             
      

      
      




10. 将User类的路径以及User.xml文件的路径在mybatis-config.xml文件中配置





      
      
             
      
      
             
      


11. 写一个UserService接口(接口里面的方法和UserMapper接口里面的方法一致,返回值和参数可不同,方法名最好一致),并写UserServiceImpl来实现UserService接口

public interface UserService {
     public User getUser(String euserPhone);
}

UserServiceImpl里面要做的就是调用UserMapper中的方法
import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.baimi.routerweb.datasource.DataSourceContextHolder;
import com.baimi.routerweb.datasource.DataSourceType;
import com.baimi.routerweb.entity.User;
import com.baimi.routerweb.mapper.UserMapper;
import com.baimi.routerweb.service.UserService;

@Service
public class UserServiceImpl implements UserService {

     @Resource(name = "userMapper")
     private UserMapper userMapper;

     @Override
     public User getUser(String euserPhone) {
          DataSourceContextHolder. setDbType(DataSourceType.SOURCE_MOP);
            return userMapper.getUser(euserPhone);
     }

}


12.写Controller类,并在其中写相对应的方法,给外部调用,这里主要就是两行代码:注意每次要和数据库打交道之前,切换到相对应的数据库,我的DataSourceType. SOURCE_MOP="ds_mop"; 这里的名字一定要和beans.xml里面配置的数据源的名称一样

//切换数据库
DataSourceContextHolder. setDbType(DataSourceType. SOURCE_MOP);
//从数据库中得到该用户的数据
User user= userService.getUser(userId);

整个Controller类的代码

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONObject;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import com.baimi.routerweb.common.Constant;
import com.baimi.routerweb.common.ErrorHandle;
import com.baimi.routerweb.datasource.DataSourceContextHolder;
import com.baimi.routerweb.datasource.DataSourceType;
import com.baimi.routerweb.entity.User;
import com.baimi.routerweb.service.UserService;
import com.baimi.routerweb.util.HttpUtil;

@Controller
public class MainController {

     @Resource(name = "userServiceImpl")
     private UserService userService;

     @RequestMapping("/login.do")
     public String login(HttpServletRequest request, HttpServletResponse response) {
            // 获取客户端传过来的code的值
           String code = request.getParameter( "code");
            if (code == null || "".equals(code)) {
                 return ErrorHandle.getError(ErrorHandle.INVALID_TOKEN, "invalid token");
           }
            // 从微信得到token的值
           JSONObject objToken = HttpUtil.httpRequest(Constant.URL_WEIXIN_TOKEN, "GET", null);
            if (objToken == null || "".equals(objToken)) {
                 return ErrorHandle.getError(ErrorHandle.SERVICE_UNRESPONSE, "service unresponse");
           }
            if (!objToken.has( "access_token")) {
                 return ErrorHandle.getError(ErrorHandle.INVALID_TOKEN, "invalid token");
           }
            //根据token和code得到UserId
           JSONObject objUser = HttpUtil.httpRequest(Constant.URL_GET_USERID,
                      "POST", "access_token=" + objToken.getString("access_token" )+ "&code=" + code + "&agentid=1");
            if(objUser== null|| "".equals(objUser)){
                 return ErrorHandle.getError(ErrorHandle.SERVICE_UNRESPONSE, "service unresponse");
           }
            if(!objUser.has( "UserId")){
                 return ErrorHandle.getError(ErrorHandle.INVALID_TOKEN, "invalid token");
           }
           String userId=objUser.getString( "UserId");
            //切换数据库
          DataSourceContextHolder. setDbType(DataSourceType.SOURCE_MOP);
            //从数据库中得到该用户的数据
           User user= userService.getUser(userId);
            if(user!= null){
                JSONObject rtObj = new JSONObject();
                rtObj.put( "userId", String.valueOf(user.getUserId()));
                 return rtObj.toString();   
           }
            return ErrorHandle.getError(ErrorHandle.INVALID_USER,"invalid user");
     }
}

访问路径:locahost:8080/RouterWeb/login.do


demo下载地址:http://download.csdn.net/detail/q908555281/9357757



你可能感兴趣的:(JAVA,WEB开发技术)