1. Préface
La stratégie de séparation de lecture et d'écriture des bases de données dans un environnement distribué est une solution clé pour résoudre le goulot d'étranglement des performances de lecture et d'écriture de la base de données, et il maximise également la vitesse et la concurrence des données de lecture (lecture) dans les applications.
Lors de la séparation de la base de données lus et écrits, nous devons d'abord configurer le maître et l'esclave de la base de données. Le plus simple est un maître et un esclave (pour les grands systèmes de sites Web, bien sûr, il sera très compliqué. Ici, nous analysons simplement la situation la plus simple). Grâce à la configuration maître-esclave, la base de données maître-esclave conserve les mêmes données. Nous accédons à l'esclave de la base de données des esclaves lors de l'exécution des opérations de lecture et du maître de base de données Master lors de l'exécution d'opérations d'écriture. Cela réduira la pression sur un serveur.
Lors de l'analyse de cas de la séparation de lecture et d'écriture. Tout d'abord, configurez la réplication maître-esclave de la base de données et fournissez une explication détaillée de l'installation et de la configuration synchrones de la base de données MySQL5.6 Master-Slave (maître / esclave)
Bien sûr, c'est juste un moyen simple de voir comment utiliser le code pour réaliser la séparation de la base de données lue et écriture, et il n'est pas nécessaire de configurer la base de données maître et esclave. Il ne nécessite que deux machines avec la même base de données installée.
2. Deux façons d'atteindre la séparation de lecture et d'écriture
Plus précisément dans le développement, il existe deux façons courantes d'atteindre la séparation de lecture et d'écriture:
1. La première méthode est la méthode la plus couramment utilisée, qui consiste à définir deux connexions de base de données, l'une est MasterDataSource et l'autre est esclavédataSource. Lors de la mise à jour des données, nous lisons le MasterDataSource et lors de l'interrogation des données, nous lisons le SlavedataSource. Cette méthode est très simple, donc je n'entrerai pas dans les détails.
2. La deuxième méthode de commutation de source de données dynamique consiste à tisser dynamiquement la source de données dans le programme lorsque le programme est en cours d'exécution, afin de choisir de lire la bibliothèque maître ou la bibliothèque des esclaves. Les principales technologies utilisées sont: Annotation, printemps AOP, réflexion.
La méthode de mise en œuvre sera décrite en détail ci-dessous.
3. AOP réalise le cas de séparation de lecture et d'écriture de la base de données maître-esclave
1. Adresse du code du projet
L'adresse du projet actuelle de cette démo: démo
2. Structure du projet
Dans la figure ci-dessus, en plus du code marqué, les autres sont principalement le code de configuration et le code métier.
3. Analyse spécifique
Ce projet est une démo du cadre SSM, du printemps, du printemps MVC et MyBatis. Les fichiers de configuration spécifiques ne sont pas trop introduits.
(1) UserContoller simule les données de lecture et d'écriture
/ ** * Créé par Xuliugen le 2016/5/4. * / @ Contrôleur @ requestmapping (value = "/ user", produit = {"application / json; charset = utf-8"}) public class userController {@Inject private iuserservice userService; //http://localhost:8080/user/select.do @ResponseBody @RequestMapping (value = "/select.do", méthode = requestMethod.get) public String select () {user user = userservice.selectUserById (123); return user.toString (); } //http://localhost:8080/user/add.do @ResponseBody @RequestMapping (value = "/add.do", méthode = requestMethod.get) public string add () {boolean isok = userservice.adduser (nouvel utilisateur ("333", "444")); return isok == true? "Shibai": "CHENGGONG"; }}Simulez la lecture et l'écriture de données et appelez iUserService.
(2) Spring-db.xml Lire et écrire la configuration de la source de données
<? xml version = "1.0" encoding = "utf-8"?> <beans xmlns = "http://www.springframework.org/schema/beans" xmlns: xsi = "http://www.w3.org/2001/xmlschema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd "> <bean id =" statfilter "Lazzy init =" true "> <propriété name =" LogsLowsql "value =" Vrait = "true" / * Value = "true" /> </ bean> <! - Connexion de base de données -> <bean id = "ReadDataSource" destre-Method = "close" init-méthod = "init" lazy-init = "true"> <propriété name = "driverclassname" value = "$ {driver}" /> <propriété name = "url" value = "$ {url1}" /> <woftway name = "user) <propriété name = "mot de passe" value = "$ {mot de passe}" /> <! - omettez certains contenus -> </Ean> <bean id = "wredataSource" destrement-méthod = "close" init-méthod = "init" lazy-init = "true"> <propriété name = "driverclassname" value = "$ {driver}" /> <propriété name = "url" value = "value =" $ {url} " name = "username" value = "root" /> <propriété name = "mot de passe" value = "$ {mot de passe}" /> <! - omettez certains contenus -> </Ean> <! - Configurer dynamiquement les sources de données de lecture et d'écriture -> <bean id = "dataSource" Lazy-Init = "true"> <propriété name = "TargetDatasources"> <map valeur-type = "javax.sql.datasource"> <! - write -> <entrée key = "write" value-ref = "wredataSource" /> <! - read -> <entrée key = "read" ref = "readdatasource" /> </ map> </ / propriété> <propriété name = "defaultargetDataSource" Ref = "werteaTasour" name = "MethodType"> <map key-type = "java.lang.string"> <! - read -> <entrée key = "read" value = ", get, select, count, list, redes" /> <! - write -> <entrée key = "write" value = ", ajouter, créer, mettre à jour, supprimer," /> </ map> </ / propriété> </fean>Dans la configuration ci-dessus, ReadDataSource et WriteDataSource sont configurés, mais seule DataSource est remise à SQLSessionFactoryBean pour la gestion, et l'utilisation de: com.xuliugen.choosedb.demo.aspect.choosedatasource Ceci est utilisé pour la sélection de la base de données.
<propriété name = "MethodType"> <map key-type = "java.lang.string"> <! - read -> <entrée key = "read" value = ", get, select, compter, list, redester" /> <! - write -> <entry key = "write" vawe
Les mots clés de préfixe spécifiques à la base de données sont configurés. Le code spécifique de ChoosedAnataSource est le suivant:
(3) Choosedatasource
/ ** * Obtenez la source de données, utilisée pour changer dynamiquement les sources de données * / la classe publique ChoosedataSource étend AbstractroutingDataSource {public static map <string, list <string>> method_type_map = new hashmap <string, list <string> (); / ** * Implémentez la méthode abstraite de la classe parent et obtenez le nom de la source de données * @return * / objet protégé déterminantCurrentlookupkey () {return dataSourceHandler.getDataSource (); } // Définissez la source de données correspondant au nom de méthode préfixe public void setMethodType (map <string, string> map) {for (String key: map.keyset ()) {list <string> v = new ArrayList <string> (); String [] types = map.get (key) .split (","); for (string type: types) {if (stringUtils.isnotblank (type)) {v.add (type); }} Method_type_map.put (key, v); }}}(4) DataSourCeaspect effectue une interception AOP pour des méthodes spécifiques
/ ** * Switch Data Source (différentes méthodes appellent différentes sources de données) * / @ aspect @ composant @ perteaSpectJautOproxy (proxytargetClass = true) classe publique DataSourCesePect {Protected Logger Logger = LoggerFactory.GetLogger (this.getClass ()); @Pointcut ("EXECUTION (* com.xuliugen.choosedb.demo.mybatis.dao. *. * (..))") public void aspect () {} / ** * configurer les pré-notifications, utiliser le point d'entrée enregistré sur la méthode aspect de la méthode Point.getTarget (). getClass (). getName (); String méthode = point.getSignature (). GetName (); logger.info (className + "." + méthode + "(" + stringUtils.join (point.getargs (), ",") + ")"); try {for (String key: choosedatasource.method_type_map.keyset ()) {for (string type: choosedataSource.method_type_map.get (key)) {if (method.startswith (type)) {dataSourceHandler.putDataSource (key); }}}} catch (exception e) {e.printStackTrace (); }}}(5) DataSourceHandler, la classe du gestionnaire de la source de données
package com.xuliugen.choosedb.demo.aspect; / ** * Handler classe de la source de données * / classe publique DataSourceHandler {// Nom de la source de données Threadpool public statique final fileLocal <string> Holder = new ThreadLocal <string> (); / ** * Ajouter les sources de données de lecture et d'écriture configurées au titulaire lorsque le projet démarre * / public static void putDataSource (String dataSource) {Holder.set (dataSource); } / ** * Obtenez la chaîne de source de données de la chaîne de trait * / public statique getDataSource () {return holder.get (); }} Le code principal, comme mentionné ci-dessus.
Code dans cet article: démo
Ce qui précède est tout le contenu de cet article. J'espère que cela sera utile à l'apprentissage de tous et j'espère que tout le monde soutiendra davantage Wulin.com.