栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring+Mybatis+Mysql搭建分布式数据库访问框架的方法

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring+Mybatis+Mysql搭建分布式数据库访问框架的方法

一、前言

用Java开发企业应用软件, 经常会采用Spring+MyBatis+Mysql搭建数据库框架。如果数据量很大,一个MYSQL库存储数据访问效率很低,往往会采用分库存储管理的方式。本文讲述如何通过Spring+Mybatis构建多数据库访问的架构,并采用多线程提升数据库的访问效率。

需要说明一下,这种方式只适合数据库数量、名称固定,且不是特别多的情况。针对数据库数量不固定的情况,后面再写一篇处理方案。

二、整体方案

三、开发环境准备

3.1 下载Spring、Mybatis、Mysql组件。

3.2 Eclipse:Java开发IDE。引入如下jar包:

代码结构如下:

四、构建数据库集群

在MYSQL中创建11个数据库(test1/2/3/4/5/6/7/8/9/10/11)创建一个简单的表:

在test1的tbl_Demo表中插入5千万条数据,其它10个数据库的tbl_Demo表中分别插入5百万条数据(用函数)。

在test1的tbl_Demo表中插入5千万条数据,其它10个数据库的tbl_Demo表中分别插入5百万条数据(用函数)。

五、创建Mybatis数据库映射接口


public interface IDemo 
{ 
 public void insertDemo(DemoDAO demo);
 public List selectGroup();
}

public interface IDemoService
{ 
 public void insertDemo(DemoDAO demo);
 public List selectGroup();
}

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 selectGroup()
 { 
  return idemo.selectGroup();
 }
}

六、创建数据库标识管理和动态数据源


public class DBIndetifier
{ 
 private static ThreadLocal dbKey = new ThreadLocal();
 public static void setDBKey(final String dbKeyPara)
 { 
  dbKey.set(dbKeyPara);
 }
 public static String getDBKey()
 {
  return dbKey.get();
 }
}

public class DynamicDataSource extends AbstractRoutingDataSource
{
 @Override
 public Object determineCurrentLookupKey()
 {
  return DBIndetifier.getDBKey();
 }
}

七、创建数据库访问对象


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;
 }
}

public class DemoResult implements Serializable
{
 
 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);
 }
}

八、创建数据库访问任务


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;
 
 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;
 }
 
 public Object getRetValue()
 {
  return operateResult;
 }
 
 public Exception getException()
 {
  return exception;
 }
 
 public boolean isFinish()
 {
  return finish;
 }
}

九、创建数据库任务管理器


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(10000),
   new ThreadPoolExecutor.CallerRunsPolicy());
 }
 public void excute(Runnable task)
 {
  pool.execute(task);
 }
}

十、创建MyBatis配置文件

10.1 mybatis.xml




 
  
 

10.2 demoMapper.xml

 
 
 
 
  insert into tbl_demo(a, b, c) values(#{a}, #{b}, #{c});
 
 
  
 
 

十一、创建Spring配置文件

11.1 spring.xml



 
  
  
  
  
  
  
  
  
 
 
  
  
  
  
  
  
  
  
 
 
  
  
  
  
  
  
  
  
 
 
  
  
  
  
  
  
  
  
 
 
  
  
  
  
  
  
  
  
 
 
  
  
  
  
  
  
  
  
 
 
  
  
  
  
  
  
  
  
 
 
  
  
  
  
  
  
  
  
 
 
  
  
  
  
  
  
  
  
 
 
  
  
  
  
  
  
  
  
 
 
  
  
  
  
  
  
  
  
 
 
  
   
    
    
    
    
    
    
    
    
    
    
    
   
  
 
 
  
  
 
 
  
  
 
 
  
 

十二、测试代码

public class TestMain
{
 
 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 taskList = new ArrayList();
  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()));
 }
}

十三、测试结果

直接查询一个5千万条数据的数据库用时:45s。

多线程同步查询10个5百万数据的数据库用时: 22s。

由于10个数据库放在两台服务器上,一个服务器5个数据库。如果将10个数据分别部署到10个服务器,效率将更高。

总结

以上所述是小编给大家介绍的Spring+Mybatis+Mysql搭建分布式数据库访问框架,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对考高分网网站的支持!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/141512.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号