1. Pendahuluan
Saat menggunakan Java untuk mengembangkan perangkat lunak aplikasi perusahaan, Spring+MyBatis+MySQL sering digunakan untuk membangun kerangka kerja basis data. Jika volume data besar, perpustakaan MySQL menyimpan efisiensi akses data sangat rendah, dan sering menggunakan metode manajemen penyimpanan sub-repositori. Artikel ini menjelaskan cara membangun arsitektur akses multi-database melalui Spring+Mybatis dan menggunakan multi-threading untuk meningkatkan efisiensi akses database.
Perlu dicatat bahwa metode ini hanya cocok untuk situasi di mana jumlah database dan nama diperbaiki, dan tidak terlalu besar. Menanggapi situasi di mana jumlah database tidak diperbaiki, saya akan menulis rencana pemrosesan lain nanti.
2. Rencana keseluruhan
3. Persiapan Lingkungan Pengembangan
3.1 Unduh Spring, Mybatis, MySQL Components.
3.2 Eclipse: IDE PEMBANGUNAN JAVA. Paket toples berikut diperkenalkan:
Struktur kode adalah sebagai berikut:
4. Bangun Cluster Database
Buat 11 database di MySQL (test1/2/3/4/5/6/7/8/9/10/11) Untuk membuat tabel sederhana:
Masukkan 50 juta lembar data ke dalam tabel TBL_DEMO di Test1, dan 5 juta lembar data ke dalam tabel TBL_DEMO di 10 database lainnya (menggunakan fungsi).
Masukkan 50 juta lembar data ke dalam tabel TBL_DEMO di Test1, dan 5 juta lembar data ke dalam tabel TBL_DEMO di 10 database lainnya (menggunakan fungsi).
5. Buat antarmuka pemetaan database mybatis
/** * Antarmuka Pemetaan MyBatis * * * @Author Elon * @Version 1.0, 23 Oktober 2015 */Antarmuka Publik Idemo {public void InsertDemo (demo demodao); Daftar Publik <Integer> SelectGroup ();}/** * * Antarmuka Layanan Pemetaan MyBatis * * @Author Elon * @Version 1.0, 23 Oktober 2015 */Antarmuka Publik IdemoService {public void InsertDemo (demo demodao); Daftar Publik <Integer> SelectGroup ();}/** * * Implementasi Layanan Pemetaan MyBatis * * @Author Elon * @Version 1.0, 23 Oktober 2015 */Kelas Publik DemoserviceImpl mengimplementasikan IdemoService {Private Idemo Idea = Null; public void setidemo (Idemo Idea) {this.idemo = ide; } @Override public void InsertDemo (demo demodao) {ideamo.insertDemo (demo); } @Override Daftar publik <Integer> selectGroup () {return ide.selectgroup (); }}6. Buat Manajemen Identitas Database dan Sumber Data Dinamis
/** * * Simpan ID database. Setiap utas disimpan oleh objek independen * * @author elon * @Version 1.0, 23 Oktober 2015 */kelas publik DBIndetifier {private static Threadlocal <string> dbkey = threadlocal baru <string> (); public static void setDBKey (string final dbkeypara) {dbkey.set (dbkeypara); } public static string getDbKey () {return dbkey.get (); }}/*** Sumber data dinamis. Basis data yang berbeda dapat dihubungkan sesuai dengan indeks data yang berbeda * * @Author elon * @Version 1.0, 23 Oktober 2015 */kelas publik DynamicDataSource meluas AbstractroutingDataSource {@Override Public Object DetectionLookUpkey () {return dbindetifier.getdbkey (); }}7. Buat Objek Akses Database
/** * * Objek akses basis data. Digunakan untuk memasukkan data. * * @author elon * @Version 1.0, 23 Oktober 2015 */kelas publik demodao {private int a; string pribadi b; int c private; publik 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; }}/** * Definisi hasil pemetaan * * @author elon * @Version 1.0, 23 Oktober 2015 */kelas publik demoresult mengimplementasikan serializable {/** * Komentar untuk <code> serialVersionuid </code> <br> */final serialversionuid final serialversion = -4130011111383; jumlah panjang pribadi; public long getsum () {return sum; } public void setsum (jumlah panjang) {this.sum = sum; } @Override public string toString () {return string.valueof (sum); }}8. Buat tugas akses basis data
/*** Definisi tugas akses basis data. Kemas setiap permintaan ke akses database ke objek tugas, masukkan ke dalam manajemen tugas, dan kemudian tunggu eksekusi tugas untuk menyelesaikan dan mengambil hasil eksekusi. * * @author elon * @Version 1.0, 23 Oktober 2015 */kelas publik DBTASK mengimplementasikan runnable {// Operation Database Identity, digunakan untuk menentukan database yang diakses. Konsisten dengan definisi sumber data dinamis data dalam file konfigurasi pegas. string final pribadi dbkey; // mybatis basis data akses objek pribadi objek akhir dbaccessObject; // nama metode akses basis data mysbatis, digunakan untuk mencerminkan call private final string methodName; // Simpan nilai parameter variabel objek akhir pribadi [] paraarray; // Simpan tipe parameter variabel @suppresswarnings ("RawTypes") kelas akhir pribadi [] ParaclassArray; // Hasil operasi basis data. Operasi kueri mengembalikan hasil kueri; The Insert, Delete, dan Modify Operations Return NULL. Operateresult objek pribadi; // informasi pengecualian yang dilemparkan oleh Pengecualian Pengecualian Privat Database Operasi; // Identifikasi apakah tugas telah dieksekusi finishing boolean pribadi; / *** Konstruktor* @param DBKEY ID Database* @param DBAccessObject Objek Akses Database* @param MetodeName Metode Database Metode Nama Metode* @param ParAarray Daftar Parameter*/ Public DBtask (String Final DBKEY, Objek Akhir DBAccessObject, Final String MethodName, Obyek Final ... PARAARRAY) {Thisarray) {this. this.dbaccessObject = dbaccessObject; this.methodname = methodName; this.paraArray = paraarray; finish = false; pengecualian = null; ParaclassArray = kelas baru [ParaArray.Length]; untuk (int index = 0; index <paraarray.length; ++ index) {paraClassArray [index] = paraarray [index] .getClass (); } operateresult = null; } / *** Fungsi Eksekusi Tugas** / @Override public void run () {coba {dbIndetifier.setDbkey (dbKey); Metode metode = dbaccessObject.getClass (). GetMethod (methodName, paraclassarray); // Operasi kueri mengembalikan hasil kueri; The Insert, Delete, dan Modify Operations Return Null Operateresult = Method.Invoke (DBAccessObject, ParaArray); } catch (Exception e) {exception = e; e.printstacktrace (); } finish = true; } /** * * Mengembalikan hasil operasi. Operasi Kueri Mengembalikan hasil kueri; Masukkan, hapus, dan ubah operasi pengembalian null * * @Return hasil operasi */ objek publik getRetValue () {return operateReSult; } / *** Pengecualian Operasi Basis Data Lempar** @Return Exception* / Public Exception getException () {return Exception; } / **** Kembalikan apakah tugas telah dieksekusi** @return tag* / public boolean isFinish () {return finish; }}9. Buat manajer tugas database
/*** Manajemen tugas akses basis data. Masukkan tugas akses basis data ke dalam kumpulan utas untuk dieksekusi. * * * @author elon * @Version 1.0, 23 Oktober 2015 */kelas publik dbtaskmgr {private static class dbtaskmgrinstance {public static final dbtaskmgr instance = new dbtaskmgr (); } public static DBTaskMgr instance () {return dbtaskmgrinstance.instance; } private ThreadPoolExecutor Pool; DbtaskMgr publik () {pool = ThreadPoolExecutor baru (10, 50, 60, TimeUnit.Seconds, ArrayBlockingQueue baru <RUNNABLE> (10000), ThreadPoolExecutor.CallerRunSpolicy ()) baru; } public void excute (Runnable Task) {pool.execute (tugas); }}10. Buat file konfigurasi 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"/> </phappers> </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 napper = "com.mybatis-3-mapper.dtd"> <mapper napper = "com." id = "insertDemo" parameTerType = "com.elon.demodao"> masukkan ke dalam tbl_demo (a, b, c) nilai ( #{a}, #{b}, #{c}); </sert> <resultMap id = "demoresult" type = "com.elon.demoresult"> <id properti = "sum" column = "sumcolum"/> </resultMap> <pilih id = "selectgroup" resultMap = "demoresult"> sums (a) sebagai sumcolum dari tbl_demo group oleh c; </pilih> </shapper>11. Buat file konfigurasi pegas
11.1 Spring.xml
<? XML Versi = "1.0" encoding = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://www.w3.org/2001/xmls XSI: schemalocation = "http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id = "datasurce_1> name properten <pore ="> "" Datasnce_1> 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> <properti name = "maxIdle" value = "30"> </property> <properti name = "maxwait" value = "500"> </property> <Properti name = "DefaultAutOcmit" value = "true"> </properti> </bean name </bean <bean iD = "DataSource_" 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> <Properti name = "maxidle" value = "30"> </property> <properti name = "maxwait" value = "500"> </property> <Properti name = "DefaultAutocommit" value = "true"> </propert> </bean name </bean> <bean iD = "DATASOURCE =" value = "com.mysql.jdbc.driver"> </property> <properti name = "url" value = "jdbc: mysql: //10.70.69.69: 3306/test3"> </properti name = "name USERNAME" = "user123"> </properti> </property name = "value =" User123 "> </properti> </property name =" name = "UserName" = "user123"> </property name = "Properti =" USERNAME "=" USER123 "> </Properti> </Properti =" Name = "UserName" = "USER123"> </Properti> </Properti = "NAME =" USERNAME = "User123"> </Properti> </Properti = "Properti =" USERNAME " name = "MaxActive" value = "100"> </property> <Properti name = "maxidle" value = "30"> </property> <properti name = "maxwait" value = "500"> </property> <Properti name = "DefaultAutocommit" value = "true"> </propert> </tean> <beane name </bean name = "DataSource =" 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> <properti name = "maxidle" value = "30"> </property> <properti name = "maxwait" value = "500"> </property> <Properti name = "DefaultAutocommit" value = "true"> </properti> </bean> <bean name iD = "DataSource_" 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> <Properti name = "maxidle" value = "30"> </property> <properti name = "maxwait" value = "500"> </property> <Property Name = "DefaultAutocommit" Value = "True"> </propert> </tean> </bean name </bean name = "DataSoUrCENOME =" " 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> <Properti name = "maxidle" value = "30"> </property> <properti name = "maxwait" value = "500"> </property> <Properti name = "DefaultAutocommit" value = "true"> </propert> </tean> </bean name </bean name = "DataSourCE =" 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> <Properti name = "maxidle" value = "30"> </property> <properti name = "maxwait" value = "500"> </property> <Properti name = "DefaultAutocommit" value = "true"> </properti> </bean name </bean> <bean iD = "DataSource_" 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> <properti name = "maxIdle" value = "30"> </property> <properti name = "maxwait" value = "500"> </property> <Properti name = "DefaultAutocommit" value = "true"> </properti> </bean> <bean name iD = "DATASURCE_"> </properti> </bean> <bean id iD = "DATASOURCE =" 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> <properti name = "maxidle" value = "30"> </property> <properti name = "maxwait" value = "500"> </property> <Properti name = "DefaultAutOcmit" value = "true"> </properti> </bean name </bean <bean iD = "DataSource =" 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> <properti name = "maxIdle" value = "30"> </property> <properti name = "maxwait" value = "500"> </property> <Properti name = "DefaultAutocommit" value = "true"> </properti> </bean name </bean> <beane id = "DATASOURCE = "11"> </bean> </bean name </bean name = "DataSource_11 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 tey = "test9" value-ref = "DataSource_9"/> <entri = "test10" value "value =" DataSource_9 "/> <entri =" test10 "value" value = "datasource_9"/> <entri = "test10" value "value =" datasoure_9 "/<entri =" test10 "value" value = "DATASERE =" ENTER = "ENTER =" Test10 "value =" DATAS "" "" "" "" test10 "test11" dATasOURCE_10 " value-ref="dataSource_11"/> </map> </property> </bean> <bean id="sqlSessionFactory"> <property name="configLocation" value="classpath:cfg/mybatis.xml"></property> <property name="dataSource" ref="dataSource" /> </bean> <bean id="iDemo"> <property name = "mapperInterface" value = "com.elon.idemo"> </property> <name properti = "sqlSessionfactory" ref = "sqlsessionfactory"> </proper
12. Kode Uji
TestMain kelas publik {/** * Kode tes * * * @param args */public static void main (string [] args) {@suppressWarnings ("Resource") ApplicationContext Context = new ClassPathXMLapPlicationContext ("cfg/spring.xml"); IDeMoService service1 = (ideMoService) context.getBean ("IdeMoService"); // Buat Objek Tugas DBTASK Task1 = dbtask baru ("test1", service1, "selectgroup"); Dbtask Task2 = dbtask baru ("test2", service1, "selectgroup"); Dbtask Task3 = dbtask baru ("test3", service1, "selectgroup"); Dbtask Task4 = dbtask baru ("test4", service1, "selectgroup"); Dbtask Task5 = dbtask baru ("test5", service1, "selectgroup"); Dbtask Task6 = dbtask baru ("test6", service1, "selectgroup"); Dbtask Task7 = dbtask baru ("test7", service1, "selectgroup"); Dbtask Task8 = dbtask baru ("test8", service1, "selectgroup"); Dbtask Task9 = dbtask baru ("test9", service1, "selectgroup"); Dbtask Task10 = dbtask baru ("test10", service1, "selectgroup"); Dbtask Task11 = dbtask baru ("test11", service1, "selectgroup"); Demodao demo = demodao baru (); demo.seta (10000000); demo.setb ("12121212"); demo.setc (100); Dbtask taskinsert = dbtask baru ("test2", service1, "insertDemo", demo); Format SimpleDateFormat = new SimpleDateFormat ("yyyy-mm-dd hh: mm: ss"); System.out.println ("Mulai Sisipkan Data:" + Format.Format (Tanggal Baru ())); Dbtaskmgr.instance (). Excute (Taskinsert); while (true) {if (! TaskInsert.isfinish ()) {coba {thread.sleep (1000); } catch (InterruptedException e) {E.PrintStackTrace (); }} else {break; }} System.out.println ("Masukkan Data End:" + Format.Format (Tanggal Baru ())); System.out.println ("Mulai meminta tabel data 50 juta:" + format.format (tanggal baru ())); Dbtaskmgr.instance (). Excute (Task1); while (true) {if (! Task1.isfinish ()) {coba {thread.sleep (1000); } catch (InterruptedException e) {E.PrintStackTrace (); }} else {break; }} System.out.println (Tugas1.getRetValue ()); System.out.println ("Query 50 Juta Tabel Data Akhir:" + Format.Format (Tanggal Baru ())); Daftar <DBTask> TaskList = ArrayList baru <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 ("Mulai kueri 10 5 juta tabel data:" + format.format (tanggal baru ())); untuk (dbtask tugas: TaskList) {dbtaskmgr.instance (). Excute (Task); } while (true) {int Success = 0; untuk (dbtask tugas: taskList) {if (! Task.isfinish ()) {coba {thread.sleep (1000); } catch (InterruptedException e) {E.PrintStackTrace (); }} else {++ sukses; }} if (success == 10) {break; }} untuk (DBTask Task: TaskList) {System.out.println (Task.GetRetValue ()) ;; } System.out.println ("10 5 juta tabel data berakhir:" +format.format (tanggal baru ())); }}13. Hasil tes
Dibutuhkan 45 -an untuk secara langsung menanyakan database 50 juta data.
Dibutuhkan 22 -an untuk menanyakan 10 database dengan 5 juta data secara sinkron.
Karena 10 database ditempatkan di dua server, satu server memiliki 5 database. Jika 10 data digunakan ke 10 server secara terpisah, efisiensinya akan lebih tinggi.
Meringkaskan
Di atas adalah pengantar editor untuk Spring+mybatis+mysql untuk membangun kerangka akses basis data terdistribusi. Saya harap ini akan membantu semua orang. Jika Anda memiliki pertanyaan, silakan tinggalkan saya pesan dan editor akan membalas semua orang tepat waktu. Terima kasih banyak atas dukungan Anda ke situs web Wulin.com!