Spring+SpringMVC+Mybatis 多數據源整合(轉)


轉載自:http://blog.csdn.net/q908555281/article/details/50316137

目錄(?)[-]
拷貝所需jar
拷貝jar文件需要的jar文件入下圖所示因為我的項目中用到了json解析所以導入了json相關的包
寫一個數據庫切換的工具類DataSourceContextHolder用來切換數據庫
寫一個DynamicDataSource類來繼承AbstractRoutingDataSource並重寫determineCurrentLookupKey方法來達到動態切換數據庫
在beansxml文件中配置數據源我這里配置的三個數據源不過在配置數據源之前先配置一下注解掃描器然后我接着配置了三個數據源然后配置動態數據源
在beansxml文件中創建sqlSessionFactory實例
在beansxml文件中配置事物事物的傳播性
在beansxml文件中配置AOP注意這里expression 后面一定要是自己程序所在包名復制的時候一定要改掉
創建一個User對象配置Userxml文件寫一個UserMapper接口用來操作User對象的接口 User類屬性有點長請忽略這些屬性
將User類的路徑以及Userxml文件的路徑在mybatis-configxml文件中配置
寫一個UserService接口接口里面的方法和UserMapper接口里面的方法一致返回值和參數可不同方法名最好一致並寫UserServiceImpl來實現UserService接口
demo下載地址httpdownloadcsdnnetdetailq9085552819357757

 

此篇文章是基於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文件

 

 

下面一步步的來講解:

1、拷貝jar文件。需要的jar文件入下圖所示,因為我的項目中用到了json解析,所以導入了json相關的包

 

2.寫一個數據庫切換的工具類:DataSourceContextHolder,用來切換數據庫

public class DataSourceContextHolder {  
     private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();  
  
     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文件

<?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"  
       xmlns:mvc= "http://www.springframework.org/schema/mvc"  
       xsi:schemaLocation= "http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd  
            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-3.0.xsd">  
  
      <!-- 注解掃描器 -->  
      <context:component-scan base-package ="com.baimi.routerweb"/>  
        
      <!-- 配置試圖解析器 -->  
      <bean class= "org.springframework.web.servlet.view.InternalResourceViewResolver" >  
             <property name ="prefix" value="/"></ property>  
             <property name ="suffix" value=".jsp"></ property>  
      </bean >  
        
      <import resource ="classpath:beans.xml"/>  
  
</beans>  

 

5. 在beans.xml文件中配置數據源。我這里配置的三個數據源,不過在配置數據源之前,先配置一下注解掃描器。然后我接着配置了三個數據源,然后配置動態數據源

<context:component-scan base-package ="com" />  
  
   <!-- 多數據源配置 -->  
   <bean id ="ds_admin" class= "org.apache.commons.dbcp.BasicDataSource" >  
          <property name ="driverClassName" value= "com.mysql.jdbc.Driver"></property >  
          <property name ="url" value= "jdbc:mysql://192.168.19.72:3307/100msh_admin" ></property >  
          <property name ="username" value="root"></ property>  
          <property name ="password" value="root"></ property>  
   </bean >  
   <bean id ="ds_partner" class= "org.apache.commons.dbcp.BasicDataSource" >  
          <property name ="driverClassName" value= "com.mysql.jdbc.Driver"></property >  
          <property name ="url"  
                value= "jdbc:mysql://192.168.19.72:3308/100msh_partner" ></property >  
          <property name ="username" value="root"></ property>  
          <property name ="password" value="root"></ property>  
   </bean >  
   <bean id ="ds_mop" class="org.apache.commons.dbcp.BasicDataSource">  
          <property name ="driverClassName" value= "com.mysql.jdbc.Driver"></property >  
          <property name ="url" value= "jdbc:mysql://192.168.19.72:3309/100msh_mop" ></property >  
          <property name ="username" value="root"></ property>  
          <property name ="password" value="root"></ property>  
   </bean >  
  
   <!-- 動態配置數據源 -->  
   <bean id ="dataSource" class= "com.baimi.routerweb.datasource.DynamicDataSource" >  
          <property name ="targetDataSources">  
                <map key-type ="java.lang.String">  
                      <entry value-ref ="ds_admin" key= "ds_admin"></entry >  
                      <entry value-ref ="ds_partner" key= "ds_partner"></entry >  
                      <entry value-ref ="ds_mop" key="ds_mop"></ entry>  
                </map >  
          </property >  
          <property name ="defaultTargetDataSource" ref= "ds_mop"></property >      <!-- 默認使用ds1的數據源 -->  
   </bean >  
<context:component-scan base-package ="com" />  
  
   <!-- 多數據源配置 -->  
   <bean id ="ds_admin" class= "org.apache.commons.dbcp.BasicDataSource" >  
          <property name ="driverClassName" value= "com.mysql.jdbc.Driver"></property >  
          <property name ="url" value= "jdbc:mysql://192.168.19.72:3307/100msh_admin" ></property >  
          <property name ="username" value="root"></ property>  
          <property name ="password" value="root"></ property>  
   </bean >  
   <bean id ="ds_partner" class= "org.apache.commons.dbcp.BasicDataSource" >  
          <property name ="driverClassName" value= "com.mysql.jdbc.Driver"></property >  
          <property name ="url"  
                value= "jdbc:mysql://192.168.19.72:3308/100msh_partner" ></property >  
          <property name ="username" value="root"></ property>  
          <property name ="password" value="root"></ property>  
   </bean >  
   <bean id ="ds_mop" class="org.apache.commons.dbcp.BasicDataSource">  
          <property name ="driverClassName" value= "com.mysql.jdbc.Driver"></property >  
          <property name ="url" value= "jdbc:mysql://192.168.19.72:3309/100msh_mop" ></property >  
          <property name ="username" value="root"></ property>  
          <property name ="password" value="root"></ property>  
   </bean >  
  
   <!-- 動態配置數據源 -->  
   <bean id ="dataSource" class= "com.baimi.routerweb.datasource.DynamicDataSource" >  
          <property name ="targetDataSources">  
                <map key-type ="java.lang.String">  
                      <entry value-ref ="ds_admin" key= "ds_admin"></entry >  
                      <entry value-ref ="ds_partner" key= "ds_partner"></entry >  
                      <entry value-ref ="ds_mop" key="ds_mop"></ entry>  
                </map >  
          </property >  
          <property name ="defaultTargetDataSource" ref= "ds_mop"></property >      <!-- 默認使用ds1的數據源 -->  
   </bean >  

 

6. 在beans.xml文件中創建sqlSessionFactory實例

<!-- 創建SqlSessionFactory -->  
<bean id ="sqlSessionFactoryBean" class= "org.mybatis.spring.SqlSessionFactoryBean" >  
       <!-- 指定數據源 -->  
       <property name ="dataSource" ref="dataSource" />  
       <!-- 指定mybatis 的配置文件 -->  
       <property name ="configLocation" value= "classpath:mybatis-config.xml" />  
</bean >  

 

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

<!-- 配置事務 -->  
      <bean id ="transactionManager"  
             class= "org.springframework.jdbc.datasource.DataSourceTransactionManager" >  
             <property name ="dataSource" ref="dataSource"></ property>  
      </bean >  
  
      <!-- 映射接口 -->  
      <bean class ="org.mybatis.spring.mapper.MapperScannerConfigurer">  
             <property name ="basePackage" value= "com.baimi.routerweb.mapper"></property >  
      </bean >  
  
      <!-- 配置事務的傳播特性 -->  
      <tx:advice id ="txAdvice" transaction-manager="transactionManager">  
             <tx:attributes >  
                   <tx:method name ="find*" read-only="true" />  
                   <tx:method name ="get*" read-only="true" />  
                   <tx:method name ="query*" read-only="true" />  
                   <tx:method name ="add*" propagation="REQUIRED" />  
                   <tx:method name ="update*" propagation="REQUIRED" />  
                   <tx:method name ="del*" propagation="REQUIRED" />  
             </tx:attributes >  
      </tx:advice >  

 

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

<!-- 配置AOP -->  
<aop:config >  
       <!-- 切點 -->  
       <aop:pointcut expression ="execution(* com.baimi.routerweb.service..*.*(..))"  
             id= "pointcut" />  
       <aop:advisor advice-ref ="txAdvice" pointcut-ref="pointcut" />  
</aop:config >  

 

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 表

<?xml version="1.0" encoding= "UTF-8" ?>  
<!DOCTYPE mapper  
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"  
"http://mybatis.org/dtd/mybatis-3-mapper.dtd" >  
  
<mapper namespace= "com.baimi.routerweb.mapper.UserMapper" >  
      <resultMap type ="User" id="usermap">  
             <result property ="userId" column="euser_id" />  
             <result property ="compId" column="comp_id" />  
             <result property ="euserName" column="euser_name" />  
             <result property ="euserPhone" column="euser_phone" />  
             <result property ="euserStatus" column="euser_status" />  
             <result property ="eAddTime" column="e_add_time" />  
             <result property ="eLeaveTime" column="e_leave_time" />  
             <result property ="eUserNameCn" column="euser_name_cn" />  
             <result property ="cUserId" column="user_id" />  
             <result property ="scDown" column="sc_own" />  
             <result property ="userDesc" column="euser_desc" />  
      </resultMap >  
  
      <!-- 查詢一條記錄 -->  
      <select id ="getUser" parameterType="java.lang.String" resultMap= "usermap">  
            select * from t_expand_user where euser_phone=#{euserPhone}  
      </select >  
  
</mapper> 

10. 將User類的路徑以及User.xml文件的路徑在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>  
  
      <!-- 別名 -->  
      <typeAliases >  
             <typeAlias type ="com.baimi.routerweb.entity.User" alias= "User" />  
      </typeAliases >  
      <mappers >  
             <mapper resource ="com/baimi/routerweb/mapper/User.xml" />  
      </mappers >  
</configuration>  

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM