Search Results for 'AbstractRoutingDataSource'

1 POSTS

  1. 2007.12.28 여러개의 DB에 선택적으로 커넥션하기
How do I get dynamic DataSources with iBATIS and Spring

원제는 위와 같다... 즉 여러개의 분산Database 또는 이와 유사한 환경에서 커넥션을 상황에 맞게
다르게 해야 하는경우 Spring에서 지원하는 형식은 다음과 같다.

1. datasource를 여러개 만들어 놓고
2. 해당 DataSource의 ID를 Map 형태로 지정한다.
3. 사용자 정의 datasource 클래스를 만들고
4. 각 Dao 클래스에선 사용자 정의 datasource를 이용한다.

위의 링크에 소개된 예제는 다음과 같다.

<!--
    Pulls the VendorOne DataSource from JNDI and sets up the
    SqlMapClient for VendorOne, the other vendors look the same.
    
    I also use Spring's 2.x AOP declarative transaction management
    around each vendor's DataSource, but I'm leaving that out for this
    example.

    Also, in my case, all my SqlMapClients use the same sqlmap config.
-->
<bean id="vendorOneDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName">
        <value>java:/comp/env/jdbc/VendorOne</value>
    </property>
</bean>
<bean id="vendorOneSqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
    <property name="configLocation" value="classpath:sqlmap-config.xml"/>
    <property name="dataSource" ref="vendorOneDataSource"/>
</bean>

<!--
    Sets up the RoutingSqlMapClient with a Map of vendor specific
    SqlMapClient beans and it keyed by the VendorTypes enum.
-->
<bean id="sqlMapClient" class="com.localmatters.bo.core.util.RoutingSqlMapClient">
    <property name="targetSqlMapClients">
    <map key-type="com.localmatters.bo.core.commons.VendorTypes">
        <entry key="VendorOne" value-ref="vendorOneSqlMapClient"/>
        <entry key="VendorTwo" value-ref="vendorTwoSqlMapClient"/>
        <entry key="VendorThree" value-ref="vendorThreeSqlMapClient"/>
    </map>
    </property>
</bean>

<!--
    Creates an Abator-generated DAO bean and sets the RoutableSqlMap.
-->
<bean id="userDAO" class="com.localmatters.bo.core.nontology.dao.UserDAOImpl">
    <property name="sqlMapClient" ref="sqlMapClient"/>
</bean>

public UserDAO getUserDAO(VendorTypes vendor) {
VendorContextHolder.setVendorType(vendor);
return (UserDAO) context.getBean("userDAO");
}

UserDAO vendorOneDAO = ServiceLocator.getUserDAO(VendorTypes.VendorOne);
UserDAO vendorTwoDAO = ServiceLocator.getUserDAO(VendorTYpes.VendorTwo);
vendorOneDAO.update(vendorOneUser);
vendorTwoDAO.update(vendorTwoUser);

VendorContextHolder.set(VendorTypes.VendorOne);
    vendorDAO.update(vendorOneUser);
    VendorContextHolder.set(VendorTypes.VendorTwo);
    vendorDAO.update(vendorTwoUser);

======================== RoutingSqlMapClient.java =========================
package com.localmatters.bo.core.util;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

import javax.sql.DataSource;

import com.ibatis.common.util.PaginatedList;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapSession;
import com.ibatis.sqlmap.client.event.RowHandler;
import com.ibatis.sqlmap.engine.execution.SqlExecutor;
import com.ibatis.sqlmap.engine.impl.ExtendedSqlMapClient;
import com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate;
import com.ibatis.sqlmap.engine.mapping.statement.MappedStatement;
import com.localmatters.bo.core.commons.VendorTypes;

public class RoutingSqlMapClient implements ExtendedSqlMapClient {
  private Map<VendorTypes, ExtendedSqlMapClient> targetSqlMapClients;
 
  public void flushDataCache() {
    targetSqlMapClients.get(VendorContextHolder.getVendorType()).flushDataCache();
  }
  public void flushDataCache(String cacheId) {
    targetSqlMapClients.get(VendorContextHolder.getVendorType()).flushDataCache(cacheId);
  }
  public SqlMapSession getSession() {
    return targetSqlMapClients.get(VendorContextHolder.getVendorType()).getSession();
  }
  public SqlMapSession openSession() {
    return targetSqlMapClients.get(VendorContextHolder.getVendorType()).openSession();
  }
  public SqlMapSession openSession(Connection conn) {
    return targetSqlMapClients.get(VendorContextHolder.getVendorType()).openSession(conn);
  }
  public int delete(String id, Object parameterObject) throws SQLException {
    return targetSqlMapClients.get(VendorContextHolder.getVendorType()).delete(id, parameterObject);
  }
  public int executeBatch() throws SQLException {
    return targetSqlMapClients.get(VendorContextHolder.getVendorType()).executeBatch();
  }
  public Object insert(String id, Object parameterObject) throws SQLException {
    return targetSqlMapClients.get(VendorContextHolder.getVendorType()).insert(id, parameterObject);
  }
  public List queryForList(String id, Object parameterObject)
      throws SQLException {
    return targetSqlMapClients.get(VendorContextHolder.getVendorType()).queryForList(id, parameterObject);
  }
  public List queryForList(String id, Object parameterObject, int skip,
      int max) throws SQLException {
    return targetSqlMapClients.get(VendorContextHolder.getVendorType()).queryForList(id, parameterObject, skip, max);
  }
  public Map queryForMap(String id, Object parameterObject, String keyProp)
      throws SQLException {
    return targetSqlMapClients.get(VendorContextHolder.getVendorType()).queryForMap(id, parameterObject, keyProp);
  }
  public Map queryForMap(String id, Object parameterObject, String keyProp,
      String valueProp) throws SQLException {
    return targetSqlMapClients.get(VendorContextHolder.getVendorType()).queryForMap(id, parameterObject, keyProp, valueProp);
  }
  public Object queryForObject(String id, Object parameterObject)
      throws SQLException {
    return targetSqlMapClients.get(VendorContextHolder.getVendorType()).queryForObject(id, parameterObject);
  }
  public Object queryForObject(String id, Object parameterObject,
      Object resultObject) throws SQLException {
    return targetSqlMapClients.get(VendorContextHolder.getVendorType()).queryForObject(id, parameterObject, resultObject);
  }
  public PaginatedList queryForPaginatedList(String id,
      Object parameterObject, int pageSize) throws SQLException {
    return targetSqlMapClients.get(VendorContextHolder.getVendorType()).queryForPaginatedList(id, parameterObject, pageSize);
  }
  public void queryWithRowHandler(String id, Object parameterObject,
      RowHandler rowHandler) throws SQLException {
    targetSqlMapClients.get(VendorContextHolder.getVendorType()).queryWithRowHandler(id, parameterObject, rowHandler);
  }
  public void startBatch() throws SQLException {
    targetSqlMapClients.get(VendorContextHolder.getVendorType()).startBatch();
  }
  public int update(String id, Object parameterObject) throws SQLException {
    return targetSqlMapClients.get(VendorContextHolder.getVendorType()).update(id, parameterObject);
  }
  public void commitTransaction() throws SQLException {
    targetSqlMapClients.get(VendorContextHolder.getVendorType()).commitTransaction();
  }
  public void endTransaction() throws SQLException {
    targetSqlMapClients.get(VendorContextHolder.getVendorType()).endTransaction();
  }
  public Connection getCurrentConnection() throws SQLException {
    return targetSqlMapClients.get(VendorContextHolder.getVendorType()).getCurrentConnection();
  }
  public DataSource getDataSource() {
    return targetSqlMapClients.get(VendorContextHolder.getVendorType()).getDataSource();
  }
  public Connection getUserConnection() throws SQLException {
    return targetSqlMapClients.get(VendorContextHolder.getVendorType()).getUserConnection();
  }
  public void setUserConnection(Connection connnection) throws SQLException {
    targetSqlMapClients.get(VendorContextHolder.getVendorType()).setUserConnection(connnection);
  }
  public void startTransaction() throws SQLException {
    targetSqlMapClients.get(VendorContextHolder.getVendorType()).startTransaction();
  }
  public void startTransaction(int transactionIsolation) throws SQLException {
    targetSqlMapClients.get(VendorContextHolder.getVendorType()).startTransaction(transactionIsolation);
  }
  public Map<VendorTypes, ExtendedSqlMapClient> getTargetSqlMapClients() {
    return targetSqlMapClients;
  }
  public void setTargetSqlMapClients(
      Map<VendorTypes, ExtendedSqlMapClient> targetSqlMapClients) {
    this.targetSqlMapClients = targetSqlMapClients;
  }
  public SqlMapExecutorDelegate getDelegate() {
    return targetSqlMapClients.get(VendorContextHolder.getVendorType()).getDelegate();
  }
  public MappedStatement getMappedStatement(String id) {
    return targetSqlMapClients.get(VendorContextHolder.getVendorType()).getMappedStatement(id);
  }
  public SqlExecutor getSqlExecutor() {
    return targetSqlMapClients.get(VendorContextHolder.getVendorType()).getSqlExecutor();
  }
  public boolean isEnhancementEnabled() {
    return targetSqlMapClients.get(VendorContextHolder.getVendorType()).isEnhancementEnabled();
  }
  public boolean isLazyLoadingEnabled() {
    return targetSqlMapClients.get(VendorContextHolder.getVendorType()).isLazyLoadingEnabled();
  }
}


========================= VendorContextHolder.java ==================
package
com.localmatters.bo.core.util;
import org.apache.log4j.Logger; import com.localmatters.bo.core.commons.VendorTypes; public class VendorContextHolder {
 
  private static Logger log = Logger.getLogger(VendorContextHolder.class);
  private static final ThreadLocal<VendorTypes> contextHolder
    = new ThreadLocal<VendorTypes>();
  public static void setVendorType(VendorTypes vendor) {
   
    if (contextHolder.get() != null &&
        !contextHolder.get().equals(vendor)) {
      log.warn("Resetting vendor from " + contextHolder.get() + " to "
          + vendor);
    }
   
    contextHolder.set(vendor);
  }
  public static VendorTypes getVendorType() {
   
    if (contextHolder.get() == null) {
      return VendorTypes.LocalMatters;
    }
   
    return (VendorTypes) contextHolder.get();
  }
  public static void clearVendorType() {
    contextHolder.remove();
  }
}

===================== VendorFilter.java ==========================
package com.localmatters.bo.core.nontology.servlet;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import org.apache.log4j.Logger;
import com.localmatters.bo.core.commons.VendorTypes;
import com.localmatters.bo.core.util.VendorContextHolder;
public class VendorFilter implements Filter {
  public static final String VENDOR_PARAM = "vendor";
 
  Logger log = Logger.getLogger(VendorFilter.class);
 
  public void destroy() {
  }
  public void doFilter(ServletRequest req, ServletResponse resp,
      FilterChain chain) throws IOException, ServletException {
    log.debug("Handling request");
   
    HttpServletRequest httpReq = (HttpServletRequest) req;
   
    if (req.getParameter(VENDOR_PARAM) == null) {
      throw new RuntimeException("vendor parameter must be specified");
    }
    VendorContextHolder.setVendorType(VendorTypes.valueOf(req.getParameter(VENDOR_PARAM)));
    log.debug("Setting vendor context to : " + VendorContextHolder.getVendorType());
    chain.doFilter(req, resp);
   
    log.debug("Clearing vendor");
    VendorContextHolder.clearVendorType();
  }
  public void init(FilterConfig arg0) throws ServletException {
    log.info("Initializing VendorFilter");
  }
}

============================= VendorTypes.java ==================
package
com.localmatters.bo.core.commons; public enum VendorTypes { VendorOne, VendorTwo, VendorThree }




또다른 링크 : Dynamic DataSource Routing

위의 내용은 interface21의 팀블로그에 나온 내용임.