Heutzutage verwenden großflächige E-Commerce-Systeme auf Datenbankebene hauptsächlich Lese- und Schreib-Trennungstechnologie, die eine Master-Datenbank und mehrere Slave-Datenbanken sind. Die Master-Bibliothek ist für Datenaktualisierungen und Echtzeit-Datenabfragen verantwortlich, und die Slave-Bibliothek ist für die Abfrage "Nicht-Real-Zeit" verantwortlich. Da in tatsächlichen Anwendungen Datenbanken mehr lesen und weniger schreiben (die Häufigkeit der Lesen von Daten ist hoch und die Häufigkeit der Aktualisierung von Daten relativ gering), und das Lesen von Daten in der Regel länger ist und mehr CPUs auf dem Datenbankserver einnimmt, was sich auf die Benutzererfahrung auswirkt. Unser üblicher Ansatz besteht darin, die Abfrage aus der Hauptbibliothek zu extrahieren, mehrere Sklavenbibliotheken zu verwenden und den Lastausgleich zu verwenden, um den Abfragedruck jeder Sklavenbibliothek zu verringern.
Das Ziel der Verwendung von Lese- und Schreib -Trennungstechnologie besteht darin, den Druck auf die Masterbibliothek effektiv zu reduzieren und Datenanfragen von Benutzern an verschiedene Sklavenbibliotheken zu verteilen, wodurch die Robustheit des Systems sichergestellt wird. Werfen wir einen Blick auf den Hintergrund der Verwendung von Leseschreiber-Trennung.
Da das Geschäft der Website weiter erweitert wird, erhöht sich die Daten weiter und mehr Benutzer werden immer größer.
Insbesondere in der Entwicklung erreichen Sie leicht Lesen und Schreiben von Trennung?
1 Die erste Methode ist die am häufigsten verwendete Methode, bei der zwei Datenbankverbindungen definiert werden. Einer ist MasterDataSource und der andere ist Slavedatasource. Bei der Aktualisierung der Daten lesen wir die MasterDataSource und beim Abfragen der Daten die Sklavenatasource. Diese Methode ist sehr einfach, daher werde ich nicht auf Details eingehen.
2 Die zweite Methode der dynamischen Datenquellenschaltung besteht darin, die Datenquelle dynamisch in das Programm zu weben, wenn das Programm ausgeführt wird, um die Masterbibliothek oder die Slave -Bibliothek zu lesen. Die verwendeten Haupttechnologien sind: Annotation, Frühlings -AOP, Reflexion. Die Implementierungsmethode wird nachstehend ausführlich beschrieben.
Bevor wir die Implementierungsmethode einführen, werden wir einige notwendige Kenntnisse vorbereiten, die AbstractroutingDataSource -Klasse von Frühling
AbstractroutingDataSource -Klasse wurde nach dem Frühjahr 2.0 hinzugefügt.
Die Codekopie lautet wie folgt:
öffentliche abstrakte Klasse AbstractroutingDataSource erweitert AbstractDataSource implementiert Initialisierungsbean {}
AbstractroutingDataSource erbt AbstractDataSource, eine Unterklasse von DataSource. DataSource ist die Datenquellenschnittstelle von javax.sql, die wie folgt definiert ist:
Die öffentliche Schnittstelle erweitert CommondataSource, Wraper { /** * <p> Versucht, eine Verbindung mit der Datenquelle herzustellen, die * CODE> DATASORCE < /code> -Objekt darstellt. dass * dieses <code> dataSource </ code> Objekt darstellt. Die DataSource -Schnittstelle definiert zwei Methoden, die beide Datenbankverbindungen erhalten. Schauen wir uns an, wie AbstraproutingDataSource die DataSource -Schnittstelle implementiert:
öffentliche Verbindung getConnection () löscht sqlexception {return DeterInetargetDataSource (). GetConnection (); Offensichtlich soll Ihre eigene DeterminetargetDataSource () -Methode aufrufen, um die Verbindung zu erhalten. Die DeterminetargetDataSource -Methode wird wie folgt definiert:
geschütztes dataSource determinetargetDataSource () {assert.notnull (this.ResolvedDataSources, "DataSource -Router nicht initialisiert"); UpKey == null)) {dataSource = this.ResolvedDefaultDataSource; if (dataSource == null) {neue IllegalStateException werfen ("Die Zieldatenquelle kann nicht bestimmen.Was uns am meisten interessiert, sind die folgenden zwei Sätze:
Object Lookupkey = DeterInecurrentLookupkey (); DataSource DataSource = this.ResolvedDataSources.get (Lookupkey);
Die DeterminecurrentLookupkey -Methode gibt Lookupkey zurück, die methode für die ResoledDataSources besteht darin, die Datenquelle von der Karte basierend auf Lookupkey zu erhalten. ResoledDataSources und DesticurrentLookupkey werden wie folgt definiert:
private map <Objekt, DataSource> Auflösende DataSources;
Haben wir nach der oben genannten Definition einige Ideen?
| Schlüssel | Wert |
| Master | MasterdataSource |
| Sklave | Slavedatasource |
Wir schreiben eine KlassendynamicDataSource, die das AbstractroutingDataSource erbt und seine methodische Methode implementiert, die den Schlüssel, den Master oder den Sklaven der Karte zurückgibt.
Okay, nachdem ich so viel gesagt habe, ich bin ein wenig nervig.
Die Technologie, die wir verwenden möchten, wurde oben erwähnt.
@Retention (retentionPolicy.runtime) @target (elementtype.method) public @Interface DataSource {String value ();} Wir müssen auch die abstrakte AbstractroutingDataSource -Abstract -Klasse von Spring implementieren, weshalb die bestimmte Methode für die DeterminalentLookupkey implementiert wird:
öffentliche Klasse DynamicDataSource erweitert AbstractroutingDataSource {@Oversride geschütztes Objekt DeterminecurrentLookupkey () {// todo automatisch generierte Stub-Return DynamicDataSourceHolder. DataSource (String Name) {Holder.set (Name); Aus der Definition von DynamicDataSource gibt es den Wert von DynamicDataSourceholder.getDatasouce () zurück. Das Folgende ist der zentrale Teil unserer Implementierung, dh der AOP -Teil.
public class dataSourceAwt {public void vor (joinpoint point) {Object target = point.gettarget (); {Methode m = classz [0] .GetMethod (Methode, Parametertype); Ausnahme e) {// todo: Handlungsausnahme}}}Für die Bequemlichkeit des Tests habe ich 2 Datenbanken definiert, die Shop Mock Master Library, die Testerdaten -Slave -Bibliothek, die Einkaufstabellenstrukturen gleich sind, aber die Daten sind unterschiedlich und die Datenbankkonfiguration lautet wie folgt:
<bean id = "MasterDataSource"> <Eigenschaft name = "TRAVERCLASSNAME" value = "com.mysql.jdbc.driver </bean> <bean id = "slavedatasource"> <Eigenschaft name = "driverClassName" value = "com.mysql.jdbc.driver" /> <Eigenschaft name = "url" value = "jdbc: mysql: //127.0.1: 3306/test"/> <Eigenschaft name = "userername" value = "root"/> <Eigenschaft name = "passwesen" value = "yangyanping0615"/> </ban> <beans: meldeources " Ava.lang.String "> <!-Write-> <Eintragsschlüssel =" Master "Value-ref =" MasterDataSource "/> <!-Read-> <Eintrag Key = "Slave" Value-ref = "Slavedatasource"/> </map> </property> <Eigenschaft name = "defaultTargetDataSource" Ref = "MasterDataSource"/> </beans: bohne> <bean id = "transactionManager"> <property name = "dataSource" dataSource " "SQLSessionFactory"> <Eigenschaft name = "dataSource" ref = "dataSource" /> <Eigenschaft name = "configLocation" " value = "classPath: config/mybatis-config.xml"/> </bean>
Fügen Sie der Federkonfiguration AOP -Konfiguration hinzu
<!-Datenbankannotation AOP-> <AOP: Aspektj-autoproxy> < /aop: Aspektj-autoproxy> <Beans: Bean ID = "ManyDataSourceAsPe" /> <AOP: config> <AOP: Aspekt = "C" c "c" teuredataSPect ". *.*(..)) "/> <AOP: vor pointcut-ref =" tx "method =" vor "/> </aoP: Aspekt> </aop: config> <!-Konfigurieren Sie die Datenbankannotation AOP->
Das Folgende ist die Definition von MyBatis UsMapper.
public interface usermapper {@dataSource ("Master") öffentlicher void (Benutzer Benutzer); .OK, führen Sie unsere Sonnenfinsternis aus, um den Effekt zu sehen, geben Sie den Benutzernamen -Administrator ein und melden Sie sich an, um den Effekt anzuzeigen
Das oben genannte ist der Inhalt dieses Artikels.