1。序文
分散環境でのデータベースの読み取りおよび書き込み分離戦略は、データベースの読み取りと書き込みパフォーマンスのボトルネックを解決するための重要なソリューションであり、アプリケーションの読み取り(読み取り)データの速度と同時性も最大化します。
データベースの読み取りと書き込みを分離するときは、最初にデータベースマスターとスレーブを構成する必要があります。最も単純なものはマスターと奴隷です(もちろん、大規模なWebサイトシステムの場合、それは非常に複雑になります。ここでは、最も単純な状況を分析します)。マスタースレーブ構成を通じて、マスタースレーブデータベースは同じデータを維持します。読み取り操作を実行するときにスレーブデータベーススレーブにアクセスし、書き込み操作を実行するときにマスターデータベースマスターにアクセスします。これにより、サーバーへの圧力が軽減されます。
読み取りおよび書き込み分離のケース分析を実施するとき。まず、データベースのマスタースレーブレプリケーションを構成し、MySQL5.6データベースマスタースレーブ(マスター/スレーブ)の同期インストールと構成の詳細な説明を提供します
もちろん、それはコードを使用してデータベースの読み取りと書き込みの分離を実現する方法を見る簡単な方法であり、マスターとスレーブデータベースを構成する必要はありません。同じデータベースがインストールされている2つのマシンのみが必要です。
2。読み取りと書き込みの分離を達成する2つの方法
具体的には、開発において、読み取りと執筆の分離を達成するための2つの一般的な方法があります。
1.最初の方法は、2つのデータベース接続を定義するための最も一般的に使用される方法です。1つはMasterDataSource、もう1つはSlavedataSourceです。データを更新するとき、MasterDataSourceを読み取り、データを照会するときはSlaveDataSourceを読み取ります。この方法は非常に簡単なので、詳細は説明しません。
2。動的なデータソーススイッチングの2番目の方法は、マスターライブラリまたはスレーブライブラリを読むことを選択するために、プログラムが実行されているときにデータソースをプログラムに動的に織り込むことです。使用される主なテクノロジーは、注釈、スプリングAOP、反射です。
実装方法については、以下で詳しく説明します。
3.AOPは、マスタースレーブデータベースの読み取りおよび書き込み分離ケースを実現します
1。プロジェクトコードアドレス
このデモの現在のプロジェクトアドレス:デモ
2。プロジェクト構造
上記の図では、マークされたコードに加えて、その他は主に構成コードとビジネスコードです。
3。特定の分析
このプロジェクトは、SSMフレームワーク、春、Spring MVC、MyBatisのデモです。特定の構成ファイルはあまり導入されていません。
(1)usercontollerは、読み書きデータをシミュレートします
/*** 2016/5/4にXuliugenによって作成されました。 */@controller@requestmapping(value = "/user"、droces = {"application/json; charset = utf-8"})public class usercontroller {@inject private iuserservice userservice; //http://localhost:8080/user/select.do @responsebody @requestmapping(value = "/select.do"、method = requestmethod.get)public string select(){user user = userservice.selectuserbyid(123); return user.toString(); } //http://localhost:8080/user/add.do @responsebody @requestmapping(value = "/add.do"、method = requestmethod.get)public string add(){boolean isok = userservice.adduser(new user( "333"、 "444"); ISOK == trueを返しますか? 「シバイ」:「チェンゴン」; }}読み取りと書き込みのデータをシミュレートし、iuserserviceに電話します。
(2)Spring-db.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" 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/spring-aop/spring- id = "statfilter" lazy-init = "true"> <プロパティname = "logslowsql" value = "true"/> <property name = "mergesql" value = "true"/> </bean> <! - > <bean id = "readdatasource" destroy-method = "close" init-meth = "init-methin =" "init-methin =" lazy-nit ">" lazy-nit " value = "$ {driver}"/> <プロパティ名= "url" value = "$ {url1}"/> <プロパティ名= "username" value = "root"/> <プロパティ名= "パスワード" value = "$ {パスワード}"/> < lazy-init = "true"> <Property name = "driverclassname" value = "$ {driver}"/> <プロパティ名= "url" value = "$ {url}"/> <プロパティ名= "username" value = "root"/> <プロパティ名= "パスワード" value = "$ {password}"/> - > <bean id = "dataSource" lazy-init = "true"> <プロパティ名= "ターゲットダタソース"> <map key-type = "java.lang.string" value-type = "javax.sql.datasource"> <! - write-> <write "read" write-ref = "wriref-ref ="> < value-ref = "readdatasource"/> </map> </property> <property name = "defaulttargetdatasource" ref = "writedatasource"/> <プロパティname = "methodtype"> <map key-type = "java.lang.string"> <! - read " <entry key = "write" value = "、追加、作成、更新、削除、削除、"/> </map> </property> </bean> </beans>上記の構成では、ReadDataSourceとWritedAtaSourceが構成されていますが、DataSourceのみが管理のためにsqlsessionFactorybeanに引き渡され、com.xuliugen.choososedb.demo.aspect.chooedatasourceこれはデータベース選択に使用されます。
<プロパティ名= "MethodType"> <Map key-type = "java.lang.string"> <! - read-> <entry key = "readキー="、get、select、count、list、query "/> <! - > <entry key =" write "value ="、add、create、update、delete、 "
データベース固有のプレフィックスキーワードが構成されています。 ChoosedataSourceの特定のコードは次のとおりです。
(3)Choosedatasource
/***データソースを動的に切り替えるために使用されるデータソースを取得します*/public class choedatasource extends abstractroutingdatasource {public static map <string、list <string >> method_type_map = new hashmap <string、list <string >>(); / ***親クラスに抽象メソッドを実装し、データソース名を取得* @return*/保護されたオブジェクトsecurrentlookupkey(){return dataSourceHandler.getDataSource(); } //メソッド名に対応するデータソースを設定しますprefix 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は、特定の方法に対してAOPインターセプトを実行します
/** *データソースの切り替え(異なる方法は異なるデータソースを呼び出す) @pointcut( "execution(*com.xuliugen.choososeb.demo.mybatis.dao。*。*(..)")public void aspect(){} / ***configure pre-notifications、method aspect()* / before( "aspeat()"){aspect() "){join point(" aspeat( " point.getTarget()。getClass()。getName(); string method = point.getSignature()。getName(); logger.info(classname + "。" + method + "(" + stringutils.join(point.getargs()、 "、") + ")"); try {for(string key:choosedatasource.method_type_map.keyset()){for(string:choosedatasource.method_type_map.get(key)){if(method.startswith){datasourcehandler.putasource(key); }}}} catch(Exception e){e.printstacktrace(); }}}(5)データソースのハンドラークラス、DataSourceHandler
パッケージcom.xuliugen.choosedb.demo.aspect;/***ハンドラーデータソースのクラス*/public class datasourcehandler {//データソース名スレッドプールpublic static final threadlocal <string> holder = new threadlocal <string>(); / ***プロジェクトが開始されたときに構成された読み取りおよび書き込みデータソースを所有者に追加*/ public static void putdatasource(string dataSource){Holder.set(dataSource); } / *** holerからデータソース文字列を取得* / public static string getDataSource(){return holder.get(); }}上記のように、メインコード。
この記事のコード:デモ
上記はこの記事のすべての内容です。みんなの学習に役立つことを願っています。誰もがwulin.comをもっとサポートすることを願っています。