Spring+Mybatis+Mysql 분포 식 데이터베이스 접근 프레임 워 크 구축 방법

머리말
자바 로 기업 애플 리 케 이 션 을 개발 하고 Spring+MyBatis+Mysql 로 데이터베이스 프레임 워 크 를 구축 합 니 다.데이터 양 이 많 으 면 하나의 MYSQL 라 이브 러 리 에 데 이 터 를 저장 하 는 접근 효율 이 낮 고 라 이브 러 리 저장 관리 방식 을 사용한다.본 고 는 Spring+Mybatis 를 통 해 다 중 데이터 베 이 스 를 방문 하 는 구 조 를 구축 하고 다 중 스 레 드 로 데이터 베 이 스 를 방문 하 는 효율 을 향상 시 키 는 방법 을 설명 한다.
이런 방식 은 데이터베이스 수량,명칭 고정 에 만 적합 하고 특별히 많은 상황 이 아니 라 는 것 을 설명해 야 한다.데이터베이스 수량 이 고정 되 지 않 은 상황 에 대해 서 는 처리 방안 을 한 편 더 쓰 겠 습 니 다.
2.전체 방안
这里写图片描述
3.개발 환경 준비
3.1 Spring,Mybatis,Mysql 구성 요 소 를 다운로드 합 니 다.
3.2 Eclipse:Java 개발 IDE.다음 jar 패키지 도입:
这里写图片描述
코드 구 조 는 다음 과 같다.
这里写图片描述
4.데이터베이스 클 러 스 터 구축
MYSQL 에 11 개의 데이터베이스(test 1/2/3/4/5/6/7/8/9/10/11)를 만 들 고 간단 한 표를 만 듭 니 다.
这里写图片描述
test 1 의 tbl데모 표 에 5 천만 개의 데이터,기타 10 개의 데이터 베 이 스 를 삽입 한 tbl데모 표 에 각각 5 백만 개의 데 이 터 를 삽입 합 니 다(함수 로).
test 1 의 tbl데모 표 에 5 천만 개의 데이터,기타 10 개의 데이터 베 이 스 를 삽입 한 tbl데모 표 에 각각 5 백만 개의 데 이 터 를 삽입 합 니 다(함수 로).
5.Mybatis 데이터베이스 맵 인터페이스 만 들 기

/**
 * Mybatis     
 * 
 *
 * @author elon
 * @version 1.0, 2015 10 23 
 */
public interface IDemo 
{ 
 public void insertDemo(DemoDAO demo);
 public List<Integer> selectGroup();
}
/**
 * 
 * Mybatis       
 *
 * @author elon
 * @version 1.0, 2015 10 23 
 */
public interface IDemoService
{ 
 public void insertDemo(DemoDAO demo);
 public List<Integer> selectGroup();
}
/**
 * 
 * Mybatis       
 *
 * @author elon
 * @version 1.0, 2015 10 23 
 */
public class DemoServiceImpl implements IDemoService
{
 private IDemo idemo = null;
 public void setIdemo(IDemo idemo) {
  this.idemo = idemo;
 }
 @Override
 public void insertDemo(DemoDAO demo)
 {
  idemo.insertDemo(demo);
 }
 @Override
 public List<Integer> selectGroup()
 { 
  return idemo.selectGroup();
 }
}
6.데이터베이스 표지 관리 와 동적 데이터 원본 만 들 기

/**
 * 
 *        。            
 *
 * @author elon
 * @version 1.0, 2015 10 23 
 */
public class DBIndetifier
{ 
 private static ThreadLocal<String> dbKey = new ThreadLocal<String>();
 public static void setDBKey(final String dbKeyPara)
 { 
  dbKey.set(dbKeyPara);
 }
 public static String getDBKey()
 {
  return dbKey.get();
 }
}
/**
 * 
 *      。                  
 *
 * @author elon
 * @version 1.0, 2015 10 23 
 */
public class DynamicDataSource extends AbstractRoutingDataSource
{
 @Override
 public Object determineCurrentLookupKey()
 {
  return DBIndetifier.getDBKey();
 }
}
7.데이터베이스 액세스 대상 만 들 기

/**
 * 
 *        。      。
 *
 * @author elon
 * @version 1.0, 2015 10 23 
 */
public class DemoDAO
{
 private int a;
 private String b;
 private int c;
 public int getA()
 {
  return a;
 }
 public void setA(int a)
 {
  this.a = a;
 }
 public String getB()
 {
  return b;
 }
 public void setB(String b)
 {
  this.b = b;
 }
 public int getC()
 {
  return c;
 }
 public void setC(int c)
 {
  this.c = c;
 }
}
/**
 * 
 *       
 *
 * @author elon
 * @version 1.0, 2015 10 23 
 */
public class DemoResult implements Serializable
{
 /**
  * Comment for <code>serialVersionUID</code><br>
  * 
  */
 private static final long serialVersionUID = -413001138792531448L;
 private long sum;
 public long getSum()
 {
  return sum;
 }
 public void setSum(long sum)
 {
  this.sum = sum;
 }
 @Override
 public String toString()
 {
  return String.valueOf(sum);
 }
}
8.데이터베이스 액세스 작업 생 성

/**
 *          。                      ,       ,
 *           ,      。
 *
 * @author elon
 * @version 1.0, 2015 10 23 
 */
public class DBTask implements Runnable
{ 
 //        ,          。 spring                 。
 private final String dbKey;
 // mybatis       
 private final Object dbAccessObject;
 // mysbatis         ,      
 private final String methodName;
 //         
 private final Object[] paraArray;
 //         
 @SuppressWarnings("rawtypes")
 private final Class[] paraClassArray;
 //        。          ;   、  、      null。
 private Object operateResult;
 //             
 private Exception exception;
 //           
 private boolean finish;
 /**
  *     
  * @param dbKey      
  * @param dbAccessObject        
  * @param methodName          
  * @param paraArray     
  */
 public DBTask(final String dbKey, final Object dbAccessObject, final String methodName, 
     final Object... paraArray)
 {
  this.dbKey = dbKey;
  this.dbAccessObject = dbAccessObject;
  this.methodName = methodName;
  this.paraArray = paraArray;
  finish = false;
  exception = null;
  paraClassArray = new Class[paraArray.length];
  for (int index = 0; index < paraArray.length; ++index)
  {
   paraClassArray[index] = paraArray[index].getClass();
  }
  operateResult = null;
 }
 /**
  * 
  *       
  *
  */
 @Override
 public void run()
 {
  try
  { 
   DBIndetifier.setDBKey(dbKey);
   Method method = dbAccessObject.getClass().getMethod(methodName, paraClassArray);
   //           ;   、  、      null
   operateResult = method.invoke(dbAccessObject, paraArray);
  }
  catch (Exception e)
  {
   exception = e;
   e.printStackTrace();
  }
  finish = true;
 }
 /**
  * 
  *       。          ;   、  、      null
  *
  * @return     
  */
 public Object getRetValue()
 {
  return operateResult;
 }
 /**
  *          
  * 
  * @return   
  */
 public Exception getException()
 {
  return exception;
 }
 /**
  * 
  *          
  *
  * @return   
  */
 public boolean isFinish()
 {
  return finish;
 }
}
9.데이터베이스 작업 관리자 만 들 기

/**
 *          。                。
 * 
 *
 * @author elon
 * @version 1.0, 2015 10 23 
 */
public class DBTaskMgr
{
 private static class DBTaskMgrInstance
 {
  public static final DBTaskMgr instance = new DBTaskMgr();
 }
 public static DBTaskMgr instance()
 {
  return DBTaskMgrInstance.instance;
 }
 private ThreadPoolExecutor pool;
 public DBTaskMgr()
 {
  pool = new ThreadPoolExecutor(10, 50, 60, TimeUnit.SECONDS,           
          new ArrayBlockingQueue<Runnable>(10000),
          new ThreadPoolExecutor.CallerRunsPolicy());
 }
 public void excute(Runnable task)
 {
  pool.execute(task);
 }
}
10.MyBatis 프로필 만 들 기
10.1 mybatis.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>
 <mappers>
  <mapper resource="cfg/demoMapper.xml"/>
 </mappers>
</configuration>
10.2 demoMapper.xml

<?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.elon.IDemo"> 
 <insert id="insertDemo" parameterType="com.elon.DemoDAO">
  insert into tbl_demo(a, b, c) values(#{a}, #{b}, #{c});
 </insert>
 <resultMap id="demoResult" type="com.elon.DemoResult">
  <id property="sum" column="sumColum"/>
 </resultMap>
 <select id="selectGroup" resultMap="demoResult">
  select sum(a) as sumColum from tbl_demo group by c;
 </select>
</mapper>
11.Spring 프로필 만 들 기
11.1 spring.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"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
 <bean id="dataSource_1" class="org.apache.commons.dbcp.BasicDataSource">
  <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
  <property name="url" value="jdbc:mysql://10.70.69.69:3306/test1"></property>
  <property name="username" value="user123"></property>
  <property name="password" value="user123"></property>
  <property name="maxActive" value="100"></property>
  <property name="maxIdle" value="30"></property>
  <property name="maxWait" value="500"></property>
  <property name="defaultAutoCommit" value="true"></property>
 </bean>
 <bean id="dataSource_2" class="org.apache.commons.dbcp.BasicDataSource">
  <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
  <property name="url" value="jdbc:mysql://10.70.69.69:3306/test2"></property>
  <property name="username" value="user123"></property>
  <property name="password" value="user123"></property>
  <property name="maxActive" value="100"></property>
  <property name="maxIdle" value="30"></property>
  <property name="maxWait" value="500"></property>
  <property name="defaultAutoCommit" value="true"></property>
 </bean>
 <bean id="dataSource_3" class="org.apache.commons.dbcp.BasicDataSource">
  <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
  <property name="url" value="jdbc:mysql://10.70.69.69:3306/test3"></property>
  <property name="username" value="user123"></property>
  <property name="password" value="user123"></property>
  <property name="maxActive" value="100"></property>
  <property name="maxIdle" value="30"></property>
  <property name="maxWait" value="500"></property>
  <property name="defaultAutoCommit" value="true"></property>
 </bean>
 <bean id="dataSource_4" class="org.apache.commons.dbcp.BasicDataSource">
  <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
  <property name="url" value="jdbc:mysql://10.70.69.69:3306/test4"></property>
  <property name="username" value="user123"></property>
  <property name="password" value="user123"></property>
  <property name="maxActive" value="100"></property>
  <property name="maxIdle" value="30"></property>
  <property name="maxWait" value="500"></property>
  <property name="defaultAutoCommit" value="true"></property>
 </bean>
 <bean id="dataSource_5" class="org.apache.commons.dbcp.BasicDataSource">
  <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
  <property name="url" value="jdbc:mysql://10.70.69.69:3306/test5"></property>
  <property name="username" value="user123"></property>
  <property name="password" value="user123"></property>
  <property name="maxActive" value="100"></property>
  <property name="maxIdle" value="30"></property>
  <property name="maxWait" value="500"></property>
  <property name="defaultAutoCommit" value="true"></property>
 </bean>
 <bean id="dataSource_6" class="org.apache.commons.dbcp.BasicDataSource">
  <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
  <property name="url" value="jdbc:mysql://10.70.69.69:3306/test6"></property>
  <property name="username" value="user123"></property>
  <property name="password" value="user123"></property>
  <property name="maxActive" value="100"></property>
  <property name="maxIdle" value="30"></property>
  <property name="maxWait" value="500"></property>
  <property name="defaultAutoCommit" value="true"></property>
 </bean>
 <bean id="dataSource_7" class="org.apache.commons.dbcp.BasicDataSource">
  <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
  <property name="url" value="jdbc:mysql://10.61.67.246:3306/test7"></property>
  <property name="username" value="user123"></property>
  <property name="password" value="user123"></property>
  <property name="maxActive" value="100"></property>
  <property name="maxIdle" value="30"></property>
  <property name="maxWait" value="500"></property>
  <property name="defaultAutoCommit" value="true"></property>
 </bean>
 <bean id="dataSource_8" class="org.apache.commons.dbcp.BasicDataSource">
  <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
  <property name="url" value="jdbc:mysql://10.61.67.246:3306/test8"></property>
  <property name="username" value="user123"></property>
  <property name="password" value="user123"></property>
  <property name="maxActive" value="100"></property>
  <property name="maxIdle" value="30"></property>
  <property name="maxWait" value="500"></property>
  <property name="defaultAutoCommit" value="true"></property>
 </bean>
 <bean id="dataSource_9" class="org.apache.commons.dbcp.BasicDataSource">
  <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
  <property name="url" value="jdbc:mysql://10.61.67.246:3306/test9"></property>
  <property name="username" value="user123"></property>
  <property name="password" value="user123"></property>
  <property name="maxActive" value="100"></property>
  <property name="maxIdle" value="30"></property>
  <property name="maxWait" value="500"></property>
  <property name="defaultAutoCommit" value="true"></property>
 </bean>
 <bean id="dataSource_10" class="org.apache.commons.dbcp.BasicDataSource">
  <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
  <property name="url" value="jdbc:mysql://10.61.67.246:3306/test10"></property>
  <property name="username" value="user123"></property>
  <property name="password" value="user123"></property>
  <property name="maxActive" value="100"></property>
  <property name="maxIdle" value="30"></property>
  <property name="maxWait" value="500"></property>
  <property name="defaultAutoCommit" value="true"></property>
 </bean>
 <bean id="dataSource_11" class="org.apache.commons.dbcp.BasicDataSource">
  <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
  <property name="url" value="jdbc:mysql://10.61.67.246:3306/test11"></property>
  <property name="username" value="user123"></property>
  <property name="password" value="user123"></property>
  <property name="maxActive" value="100"></property>
  <property name="maxIdle" value="30"></property>
  <property name="maxWait" value="500"></property>
  <property name="defaultAutoCommit" value="true"></property>
 </bean>
 <bean id="dataSource" class="com.elon.DynamicDataSource">
  <property name="targetDataSources">
   <map>
    <entry key="test1" value-ref="dataSource_1"/>
    <entry key="test2" value-ref="dataSource_2"/>
    <entry key="test3" value-ref="dataSource_3"/>
    <entry key="test4" value-ref="dataSource_4"/>
    <entry key="test5" value-ref="dataSource_5"/>
    <entry key="test6" value-ref="dataSource_6"/>
    <entry key="test7" value-ref="dataSource_7"/>
    <entry key="test8" value-ref="dataSource_8"/>
    <entry key="test9" value-ref="dataSource_9"/>
    <entry key="test10" value-ref="dataSource_10"/>
    <entry key="test11" value-ref="dataSource_11"/>
   </map>
  </property>
 </bean>
 <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
  <property name="configLocation" value="classpath:cfg/mybatis.xml"></property>
  <property name="dataSource" ref="dataSource" />
 </bean>
 <bean id="iDemo" class="org.mybatis.spring.mapper.MapperFactoryBean">
  <property name="mapperInterface" value="com.elon.IDemo"></property>
  <property name="sqlSessionFactory" ref="sqlSessionFactory"></property>
 </bean>
 <bean id="iDemoService" class="com.elon.DemoServiceImpl">
  <property name="idemo" ref="iDemo"></property>
 </bean>
</beans>
12.테스트 코드

public class TestMain
{
 /**
  *     
  * 
  *
  * @param args
  */
 public static void main(String[] args)
 {
  @SuppressWarnings("resource")
  ApplicationContext context = new ClassPathXmlApplicationContext("cfg/spring.xml");
  IDemoService service1 = (IDemoService)context.getBean("iDemoService");
  //       
  DBTask task1 = new DBTask("test1", service1, "selectGroup");
  DBTask task2 = new DBTask("test2", service1, "selectGroup");
  DBTask task3 = new DBTask("test3", service1, "selectGroup");
  DBTask task4 = new DBTask("test4", service1, "selectGroup");
  DBTask task5 = new DBTask("test5", service1, "selectGroup");
  DBTask task6 = new DBTask("test6", service1, "selectGroup");
  DBTask task7 = new DBTask("test7", service1, "selectGroup");
  DBTask task8 = new DBTask("test8", service1, "selectGroup");
  DBTask task9 = new DBTask("test9", service1, "selectGroup");
  DBTask task10 = new DBTask("test10", service1, "selectGroup");
  DBTask task11 = new DBTask("test11", service1, "selectGroup");
  DemoDAO demo = new DemoDAO();
  demo.setA(10000000);
  demo.setB("12121212");
  demo.setC(100);
  DBTask taskInsert = new DBTask("test2", service1, "insertDemo", demo);
  SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
  System.out.println("      :" + format.format(new Date()));
  DBTaskMgr.instance().excute(taskInsert);
  while (true)
  {
   if (!taskInsert.isFinish())
   {
    try
    {
     Thread.sleep(1000);
    }
    catch (InterruptedException e)
    {
     e.printStackTrace();
    }
   }
   else
   {
    break;
   }
  }
  System.out.println("      :" + format.format(new Date()));
  System.out.println("    5     :" + format.format(new Date()));
  DBTaskMgr.instance().excute(task1);
  while (true)
  {
   if (!task1.isFinish())
   {
    try
    {
     Thread.sleep(1000);
    }
    catch (InterruptedException e)
    {
     e.printStackTrace();
    }
   }
   else
   {
    break;
   }
  }
  System.out.println(task1.getRetValue());
  System.out.println("  5       :" + format.format(new Date()));
  List<DBTask> taskList = new ArrayList<DBTask>();
  taskList.add(task2);
  taskList.add(task3);
  taskList.add(task4);
  taskList.add(task5);
  taskList.add(task6);
  taskList.add(task7);
  taskList.add(task8);
  taskList.add(task9);
  taskList.add(task10);
  taskList.add(task11);
  System.out.println("    10 5     :" + format.format(new Date()));
  for (DBTask task : taskList)
  {
   DBTaskMgr.instance().excute(task);
  }
  while (true)
  {
   int success = 0;
   for (DBTask task : taskList)
   {
    if (!task.isFinish())
    { 
     try
     {
      Thread.sleep(1000);
     }
     catch (InterruptedException e)
     {
      e.printStackTrace();
     }
    }
    else
    {
     ++success;
    }
   }
   if (success == 10)
   {
    break;
   }
  }
  for (DBTask task : taskList)
  {
   System.out.println(task.getRetValue());;
  }
  System.out.println("10 5         :" +format.format(new Date()));
 }
}
13.테스트 결과
这里写图片描述
5 천만 개의 데이터 베 이 스 를 직접 조회 할 때:45s.
다 중 스 레 드 동기 화 5 백만 데이터 베 이 스 를 조회 할 때:22s.
10 개의 데이터 베 이 스 를 두 대의 서버 에 두 었 기 때문에,한 서버 에 5 개의 데이터 베 이 스 를 두 었 다.10 개의 데 이 터 를 각각 10 개의 서버 에 배치 하면 효율 이 높아진다.
총결산
위 에서 말 한 것 은 소 편 이 소개 한 Spring+Mybatis+Mysql 이 분포 식 데이터 베이스 방문 프레임 워 크 를 구축 하여 여러분 에 게 도움 이 되 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 메 시 지 를 남 겨 주세요.소 편 은 제때에 답 해 드 리 겠 습 니 다.여기 서도 저희 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!

좋은 웹페이지 즐겨찾기