1. Предисловие
При использовании Java для разработки корпоративного прикладного программного обеспечения Spring+Mybatis+MySQL часто используется для создания структуры базы данных. Если объем данных большой, библиотека MySQL сохраняет эффективность доступа к данным очень низкую, и она часто использует метод управления хранением субрепозирования. В этой статье описывается, как построить архитектуру доступа к нескольким датабазам через Spring+Mybatis и использовать многопоточное для повышения эффективности доступа к базе данных.
Следует отметить, что этот метод подходит только для ситуаций, когда количество баз данных и имен является фиксированным и не особенно большим. В ответ на ситуацию, когда количество баз данных не установлено, я напишу еще один план обработки позже.
2. Общий план
3. Подготовка среды развития
3.1 Скачать Spring, Mybatis, компоненты MySQL.
3.2 Eclipse: Java Development IDE. Введены следующие пакеты JAR:
Структура кода заключается в следующем:
4. Создайте кластер базы данных
Создайте 11 баз данных в MySQL (Test1/2/3/4/5/6/7/8/9/10/11), чтобы создать простую таблицу:
Вставьте 50 миллионов деталей данных в таблицу TBL_DEMO в Test1 и 5 миллионов данных в таблицу TBL_DEMO в других 10 базах данных (с использованием функций).
Вставьте 50 миллионов деталей данных в таблицу TBL_DEMO в Test1 и 5 миллионов данных в таблицу TBL_DEMO в других 10 базах данных (с использованием функций).
5. Создать интерфейс картирования базы данных Mybatis
/** * Интерфейс отображения mybatis * * * @author elon * @version 1.0, 23 октября 2015 г. */Публичный интерфейс idemo {public void insertdemo (demodao demo); Общественный список <integer> selectGroup ();}/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Общественный список <integer> selectGroup ();}/** * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * public void setIdemo (Idemo Idea) {this.idemo = Idea; } @Override public void insertDemo (demodao demo) {ideamo.insertdemo (demo); } @Override public list <integer> selectGroup () {return Idea.selectGroup (); }}6. Создание управления идентификацией базы данных и динамические источники данных
/** * * Сохранить идентификатор базы данных. Каждый поток хранится независимым объектом * * @author elon * @version 1.0, 23 октября 2015 г. */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, 23 октября 2015 г. */public Class DynamicDatasource Extress AbstractroutingDataSource {@Override public ObjectEcurrentLookupkey () {return dbindetifier.getDbkey ();); }}7. Создать объект доступа к базе данных
/** * * * Объект доступа к базе данных. Используется для вставки данных. * * @author elon * @version 1.0, 23 октября 2015 г. */public class demodao {private int a; частная строка B; частный 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 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, 23 октября 2015 г. */Public Class DBTSK реализует runnable {// идентификация базы данных операции, используемая для указания доступной базы данных. В соответствии с определением динамического источника данных данных в файле конфигурации пружины. частная финальная строка dbkey; // Mybatis Database Access Object Private конечный объект dbaccessObject; // имя метода доступа к базе данных MySbatis, используемое для отражения Call Private Final String Methodname; // Хранить значение переменных параметров частный конечный объект [] paraarray; // Хранить тип параметра переменной @suppresswarnings ("rawtypes") частный окончательный класс [] paraclassarray; // Результат работы базы данных. Операция запроса возвращает результат запроса; Вставка, удаление и изменение операций возвращает NULL. Оператор частного объекта; // Информация об исключении, брошенная базой данных Operation Private Exception Exception; // определить, была ли задача выполнена частная логическая отделка; /** * Constructor* @param dbKey Database ID* @param dbAccessObject Database access object* @param methodName Database access method name* @param paraArray Parameter list*/ 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 = новый класс [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); Метод метода = dbaccessObject.getClass (). GetMethod (MethodName, ParaclassArray); // операция запроса возвращает результат запроса; Вставка, удаление и изменение операций возвращает null operateresult = method.invoke (dbaccessobject, paraarray); } catch (Exception e) {exception = e; e.printstacktrace (); } finish = true; } /** * * вернуть результат операции. Операция запроса возвращает результаты запроса; Вставить, удалить и изменить операции возвращать null * * @return result result */ public getretvalue () {return operateresult; } / *** Выбросить операцию базы данных исключение** @return Exception* / public Exception getException () {return Exception; } / ***** Верните, была ли задача выполнена** @return Tag* / public boolean isfinish () {return finish; }}9. Создайте диспетчер задач базы данных
/*** Управление задачами доступа к базе данных. Поместите задачу доступа к базе данных в пул потоков для выполнения. * * * @author elon * @version 1.0, 23 октября 2015 г. */public class dbtaskmgr {private static class dbtaskmgrinstance {public static final dbtaskmgr Encance = new dbtaskmgr (); } public static dbtaskmgr ancess () {return dbtaskmgrinstance.instance; } private ThreadPoolexeCutor Pool; public dbtaskmgr () {pool = new ThreadPoolexeCutor (10, 50, 60, TimeUnit.seconds, New ArrayBlockingQueue <lunnable> (10000), New ThreadPoolexeCutor.CallerRunSpolicy ()); } public void Excute (выполняемая задача) {pool.execute (task); }}10. Создать файл конфигурации mybatis
10.1 mybatis.xml
<? xml version = "1.0" Encoding = "UTF-8"?> <! Конфигурация doctype public "-// mybatis.org//dtd config 3.0 // en" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <ponfiguration> <mappers> 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. id = "INSERTDEMO" PARAMETERTYPE = "com.elon.demodao"> вставьте в 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) как sumcolum из tbl_demo group by c; </select> </mapper>11. Создать файл конфигурации пружины
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"> <perity nelight = "DriverClassname" value = "com.mysql.jdbc.driver"> </property> <name = "url" value = "jdbc: mysql: //10.70.69.69: 3306/test1"> </property> <name = "username" value = "user123"> </property> <property = "palshy" value = "user123"> </propertive> </valy = "value =" user123 "> </valy"> </"/" "/" "/" "/свойство"/""/". value = "100"> </property> <name = "maxidle" value = "30"> </property> <name = "maxwait" value = "500"> </property> <name = "defaultautocommit" value = "true"> </property> </bean> <bean id = "dataSource_2"> <property name = "riverclassname". 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> <name = "maxidle" value = "30"> </property> <name = "maxwait" value = "500"> </property> <name = "defaultautocommit" value = "true"> </property> </bean> <bean id = "dataSource_3"> <property name = "riverclassname" bean id = "dataSource_3"> <property name = "riverclassname" riverclassname "riverClassnam value = "com.mysql.jdbc.driver"> </property> <name = "url" value = "jdbc: mysql: //10.70.69.69: 3306/test3"> </property> <name = "username" value = "user123"> </property> <stame = "palshy" value = "user123"> </valy "> </valy"> </""/"Property"> </""/""/""/Property "> </" Property "> </" "/". value = "100"> </property> <name = "maxidle" value = "30"> </property> <name = "maxwait" value = "500"> </property> <name = "defaultautocommit" value = "true"> </property> </bean> <bean id = "dataSource_4"> <property name = "riverclassname" bean> <bean id = "dataSource_4"> <property "=" riverclassname "railclassname"> "dataSource_4"> <property "=" riverclassname> </bean> <bean id = "dataSource_4" value = "com.mysql.jdbc.driver"> </property> <name = "url" value = "jdbc: mysql: //10.70.69.69: 3306/test4"> </property> <name = "username" value = "user123"> </property> <valy = "palshy" value = "user123"> </property> </vame = "value =" user123 "> </" "/". value = "100"> </property> <name = "maxidle" value = "30"> </property> <name = "maxwait" value = "500"> </property> <name = "defaultautocommit" value = "true"> </property> </bean> <bean id = "dataSource_5"> <property name = "riverclassname" bean id = "dataSource_5"> <property "=" riverclassname "dirc. value = "com.mysql.jdbc.driver"> </property> <name = "url" value = "jdbc: mysql: //10.70.69.69: 3306/test5"> </property> <name = "username" value = "user123"> </property> <stame = "palshy" value = "user123"> </propertive> </property = "value =" user123 "> </stopport"> </""/""/Property "> </" "/" "/Property"> </". value = "100"> </property> <name = "maxidle" value = "30"> </property> <name = "maxwait" value = "500"> </property> <name = "defaultautocommit" value = "true"> </property> </bean> <bean id = "dataSource_6"> <property name = "riverclassname"> <bean id = "dataSource_6"> <property "=" riverclassname "railclassNam value = "com.mysql.jdbc.driver"> </property> <name = "url" value = "jdbc: mysql: //10.70.69.69: 3306/test6"> </property> <name = "username" value = "user123"> </property> <valy = "palshy" value = "user123"> </valy "> </" "/свойство"/""/". value = "100"> </property> <name = "maxidle" value = "30"> </property> <name = "maxwait" value = "500"> </property> <name = "defaultautocommit" value = "true"> </property> </bean> <bean id = "dataSource_7"> <property name = "riverclassname". 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> <name = "maxwait" value = "500"> </property> <name = "defaultautocommit" value = "true"> </propetion> </bean> <bean id = "dataSource_8"> </property> </bean> <bean id = ". 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> <name = "maxwait" value = "500"> </property> <name = "defaultautocommit" value = "true"> </propetion> </bean> <bean id = "dataSource_9"> </property> </bean> <bean id = "name '>" hilamc. 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> <name = "maxwait" value = "500"> </property> <name = "defaultautocommit" value = "true"> </properation> </bean> <bean id = "dataSource_10"> name </property> </bean> <bean id = ". 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> <name = "maxwait" value = "500"> </property> <name = "defaultautocommit" value = "true"> </propetion> </bean> <bean id = "dataSource_11"> name ">" hraim11 "> </property> </bean> <bean id =". 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"> <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"> <name = "configlocation" value = "classPath: cfg/mybatis.xml"> </propetion> <propatore = "dataSource" id = "idemo"> <property name = "mapperinterface" value = "com.elon.idemo"> </property> <name = "sqlSessionFactory" ref = "sqlSessionFactory"> </property> </bean> <bean id = "idemoservice"> <propatore = "idemo" ref = "
12. Тестовый код
открытый класс testmain {/** * Тестовый код * * * @param args */public static void main (string [] args) {@suppresswarnings ("resource") 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 dbtsk ("test4", service1, "selectGroup"); DBTASK TASS5 = NEW DBTASK ("test5", Service1, "SelectGroup"); Dbtask task6 = new dbtask ("test6", service1, "selectGroup"); Dbtask task7 = new dbtask ("test7", service1, "selectGroup"); DBTASK TASS8 = новый DBTASK ("test8", Service1, "SelectGroup"); DBTASK TASK9 = новый 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 ("Start Insert Data:" + format.format (new Date ())); Dbtaskmgr.instance (). Excute (Taskinsert); while (true) {if (! taskinsert.isfinish ()) {try {thread.sleep (1000); } catch (прерванное искусство e) {e.printstacktrace (); }} else {break; }} System.out.println ("Вставьте данные конец:" + format.format (new Date ())); System.out.println («Начать запрос 50 миллионов данных таблицы данных:» + format.format (new Date ())); Dbtaskmgr.instance (). Excute (task1); while (true) {if (! task1.isfinish ()) {try {thread.sleep (1000); } catch (прерванное искусство e) {e.printstacktrace (); }} else {break; }} System.out.println (task1.getretvalue ()); System.out.println ("запрос 50 миллионов данных таблицы данных:" + format.format (new Date ())); Список <dbtask> taskList = new ArrayList <dbtask> (); asselist.add (task2); asklist.add (task3); tasklist.add (task4); assistlist.add (task5); asklist.add (task6); asklist.add (task7); asklist.add (task8); asklist.add (task9); asklist.add (task10); asklist.add (task11); System.out.println ("Start Query 10 5 миллионов таблиц данных:" + format.format (new Date ())); для (DBTSK TASCE: TASCELILD) {DBTASKMGR.INSTANCE (). Excute (задача); } while (true) {int success = 0; для (dbtask задача: задача) {if (! task.isfinish ()) {try {thread.sleep (1000); } catch (прерванное искусство e) {e.printstacktrace (); }} else {++ успех; }} if (успех == 10) {break; }} for (dbtsk task: tasklist) {System.out.println (task.getRetvalue ()) ;; } System.out.println ("10 5 миллионов таблиц данных заканчивается:" +format.format (new Date ())); }}13. Результаты теста
Требуется 45 -е, чтобы напрямую запросить базу данных из 50 миллионов данных.
Требуется 22, чтобы запросить 10 баз данных с 5 миллионами данных в синхронном виде.
Поскольку 10 баз данных размещены на двух серверах, один сервер имеет 5 баз данных. Если 10 данных развернуты на 10 серверах отдельно, эффективность будет еще выше.
Суммировать
Выше приведено введение редактора в Spring+Mybatis+MySQL для создания распределенной структуры доступа к базе данных. Я надеюсь, что это будет полезно для всех. Если у вас есть какие -либо вопросы, пожалуйста, оставьте мне сообщение, и редактор ответит всем вовремя. Большое спасибо за вашу поддержку сайту wulin.com!