1. 程式人生 > >shareding-jdbc實現讀寫分離最簡單的容易理解示例

shareding-jdbc實現讀寫分離最簡單的容易理解示例

資料庫建立

create database demo_ds_master; //建立主庫

create database demo_ds_slave_0; //建立從庫1

create database demo_ds_slave_1; //建立從庫2

匯入依賴

<dependencies>

<dependency>

<groupId>junit</groupId>

<artifactId>junit</artifactId>

<version>4.0</version>

<scope>test</scope>

</dependency>

<dependency>

<groupId>io.shardingjdbc</groupId>

<artifactId>sharding-jdbc-core</artifactId>

<version>2.0.0.M2</version>

</dependency>

<dependency>

<groupId>io.shardingjdbc</groupId>

<artifactId>sharding-jdbc-spring-namespace

</artifactId>

<version>2.0.0.M2</version>

</dependency>

<dependency>

<groupId>com.alibaba</groupId>

<artifactId>druid</artifactId>

<version>1.0.13</version>

</dependency>

<dependency>

<groupId>mysql</groupId>

<artifactId>mysql

-connector-java</artifactId>

<version>5.1.28</version>

</dependency>

<dependency>

<groupId>org.slf4j</groupId>

<artifactId>slf4j-api</artifactId>

<version>1.7.7</version>

</dependency>

<dependency>

<groupId>ch.qos.logback</groupId>

<artifactId>logback-classic</artifactId>

<version>1.0.13</version>

</dependency>

</dependencies>

程式碼:

1.建立資料來源的工具類:package com.irisian.sharedjdbc.masterandslave;

import javax.sql.DataSource;

import com.alibaba.druid.pool.DruidDataSource;

public class DataSourceUtil {

    private static final String URL_PREFIX = "jdbc:mysql://localhost:3306/";

    private static final String USER_NAME = "root";

    private static final String PASSWORD = "123456";

    public static DataSource createDataSource(final String dataSourceName) {

DruidDataSource result = new DruidDataSource();

        result.setDriverClassName(com.mysql.jdbc.Driver.class.getName());

        result.setUrl(URL_PREFIX + dataSourceName);

        result.setUsername(USER_NAME);

        result.setPassword(PASSWORD);

        return result;

    }

}

2.主從資料庫配置

package com.irisian.sharedjdbc.masterandslave;

import java.sql.SQLException;

import java.util.Arrays;

import java.util.HashMap;

import java.util.Map;

import javax.sql.DataSource;

import io.shardingjdbc.core.api.MasterSlaveDataSourceFactory;

import io.shardingjdbc.core.api.config.MasterSlaveRuleConfiguration;

public final class RawJdbcJavaMasterSlaveOnlyMain {

public static void main(String[] args) throws SQLException {

new RawJdbcRepository(getMasterSlaveDataSource()).demo();

}

public static DataSource getMasterSlaveDataSource() throws SQLException {

MasterSlaveRuleConfiguration masterSlaveRule = new MasterSlaveRuleConfiguration();

masterSlaveRule.setName("demo_ds_master_slave");//主從規則的名稱,此名稱隨意起

masterSlaveRule.setMasterDataSourceName("demo_ds_master");//主資料來源名稱,和createDataSourceMap物件

masterSlaveRule.setSlaveDataSourceNames(Arrays.asList("demo_ds_slave_0", "demo_ds_slave_1"));//從資料來源名稱,和createDataSourceMap物件

masterSlaveRule.setLoadBalanceAlgorithmClassName(

"io.shardingjdbc.core.api.algorithm.masterslave.RandomMasterSlaveLoadBalanceAlgorithm");//負載平衡的策略

return MasterSlaveDataSourceFactory.createDataSource(createDataSourceMap(), masterSlaveRule);

}

private static Map<String, DataSource> createDataSourceMap() {

final Map<String, DataSource> result = new HashMap<>(3, 1);

result.put("demo_ds_master", DataSourceUtil.createDataSource("demo_ds_master"));//建立主庫的資料來源連線

result.put("demo_ds_slave_0", DataSourceUtil.createDataSource("demo_ds_slave_0"));//建立從庫的資料來源連線

result.put("demo_ds_slave_1", DataSourceUtil.createDataSource("demo_ds_slave_1"));//建立從庫的資料來源連線

return result;

}

}

3.測試的類

package com.irisian.sharedjdbc.masterandslave;

import io.shardingjdbc.core.api.HintManager;

import javax.sql.DataSource;

import java.sql.Connection;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.sql.Statement;

public class RawJdbcRepository {

private final DataSource dataSource;

public RawJdbcRepository(final DataSource dataSource) {

this.dataSource = dataSource;

}

public void demo() throws SQLException {

// createTable();      //建立表的語句

// insertData();//插入僅僅會插入到主資料來源裡面,然後配置mysql主從同步(需要自己配置,shareding-jdbc無法自動完成),配置了之後就可以從從庫中讀取了

//for (int i = 0; i < 30; i++) {//查詢均從從庫中讀取,如果從庫集中有一個數據庫中沒有資料,剛好從此資料庫中讀取資料,則讀取不到任何的資料

//System.out.println("1.Equals Select--------------");

//printEqualsSelect();

//}

System.out.println("1.Equals Select--------------");

printEqualsSelect();

// System.out.println("2.In Select--------------");

// printInSelect();

// System.out.println("3.Hint Select--------------");

// printHintSimpleSelect();

// dropTable();

}

public void createTable() throws SQLException {

execute(dataSource,

"CREATE TABLE IF NOT EXISTS t_order (order_id BIGINT NOT NULL AUTO_INCREMENT, user_id INT NOT NULL, status VARCHAR(50), PRIMARY KEY (order_id))");

execute(dataSource,

"CREATE TABLE IF NOT EXISTS t_order_item (order_item_id BIGINT NOT NULL AUTO_INCREMENT, order_id BIGINT NOT NULL, user_id INT NOT NULL, PRIMARY KEY (order_item_id))");

}

public void dropTable() throws SQLException {

execute(dataSource, "DROP TABLE t_order_item");

execute(dataSource, "DROP TABLE t_order");

}

public void insertData() throws SQLException {

for (int i = 1; i < 10; i++) {

long orderId = executeAndGetGeneratedKey(dataSource,

"INSERT INTO t_order (user_id, status) VALUES (10, 'INIT')");

execute(dataSource, String.format("INSERT INTO t_order_item (order_id, user_id) VALUES (%d, 10)", orderId));

orderId = executeAndGetGeneratedKey(dataSource,

"INSERT INTO t_order (user_id, status) VALUES (11, 'INIT')");

execute(dataSource, String.format("INSERT INTO t_order_item (order_id, user_id) VALUES (%d, 11)", orderId));

}

}

public void printEqualsSelect() throws SQLException {

String sql = "SELECT i.* FROM t_order o JOIN t_order_item i ON o.order_id=i.order_id WHERE o.user_id=?";

try (Connection conn = dataSource.getConnection();

PreparedStatement preparedStatement = conn.prepareStatement(sql)) {

preparedStatement.setInt(1, 10);

printSimpleSelect(preparedStatement);

}

}

public void printInSelect() throws SQLException {

String sql = "SELECT i.* FROM t_order o JOIN t_order_item i ON o.order_id=i.order_id WHERE o.user_id IN (?, ?)";

try (Connection conn = dataSource.getConnection();

PreparedStatement preparedStatement = conn.prepareStatement(sql)) {

preparedStatement.setInt(1, 10);

preparedStatement.setInt(2, 11);

printSimpleSelect(preparedStatement);

}

}

public void printHintSimpleSelect() throws SQLException {

String sql = "SELECT i.* FROM t_order o JOIN t_order_item i ON o.order_id=i.order_id";

try (HintManager hintManager = HintManager.getInstance();

Connection conn = dataSource.getConnection();

PreparedStatement preparedStatement = conn.prepareStatement(sql)) {

hintManager.addDatabaseShardingValue("t_order", "user_id", 11);

printSimpleSelect(preparedStatement);

}

}

private void printSimpleSelect(final PreparedStatement preparedStatement) throws SQLException {

StringBuilder builder = new StringBuilder();

try (ResultSet rs = preparedStatement.executeQuery()) {

while (rs.next()) {

System.out.print("order_item_id:" + rs.getLong(1) + ", ");

System.out.print("order_id:" + rs.getLong(2) + ", ");

System.out.print("user_id:" + rs.getInt(3));

System.out.println();

}

}

}

private void execute(final DataSource dataSource, final String sql) throws SQLException {

try (Connection conn = dataSource.getConnection(); Statement statement = conn.createStatement()) {

statement.execute(sql);

}

}

private long executeAndGetGeneratedKey(final DataSource dataSource, final String sql) throws SQLException {

long result = -1;

try (Connection conn = dataSource.getConnection(); Statement statement = conn.createStatement()) {

statement.executeUpdate(sql, Statement.RETURN_GENERATED_KEYS);

ResultSet resultSet = statement.getGeneratedKeys();

if (resultSet.next()) {

result = resultSet.getLong(1);

}

}

return result;

}

}


相關推薦

shareding-jdbc實現分離簡單容易理解示例

資料庫建立create database demo_ds_master; //建立主庫create database demo_ds_slave_0; //建立從庫1create database

sharding-JDBC 實現分離

aso engine lec bus manage 均衡 map 如果 use 需求 一主兩從,做讀寫分離。 多個從庫之間實現負載均衡。 可手動強制部分讀請求到主庫上。(因為主從同步有延遲,對實時性要求高的系統,可以將部分讀請求也走主庫) 本次不討論 MySQL如何配置

mysql jdbc 實現分離

這種方式直接在程式碼級別實現了mysql 讀寫分離 很簡單,只需要改一下配置檔案,就搞定了,是不是很嗨? jdbc.driverClassName=com.mysql.jdbc.ReplicationDriver jdbc.url=jdbc:mysql

springboot2.x 整合mybatis-plus sharding-jdbc實現分離

首先,匯入依賴,下面只展示核心依賴 <dependency> <groupId>com.baomidou</groupId> <artifactId>my

Mycat簡單實現分離與分庫分表

mycatMycat數據庫讀寫分離 環境: 客戶端1.13 ↓ mycat中間件1.11 ↙ ↘ master主機1.12 slave主機1.10 一、master主機(

無需第三方軟體實現Mac支援ntfs簡單操作

參照此方法在自己的Mac上試驗成功,現記錄此方法如下(略有改動): 本機環境:  macOS Sierra version 10.12.6  2017 款 MacBook Pro   2017.9.10 此方法對10.6以前版本的OS理論上是無效的  蘋果理論上是支援

Spring 簡單實現分離

讀寫分離,基本原理是讓主資料庫處理事務性增、改、刪操作,而從資料庫處理查詢操作。資料庫複製被用來把事務性操作導致的變更同步到叢集的從資料庫。 一般常用實現方式有以下兩種: 1,主從分離,更新操作主資料庫,查詢操作從資料庫 2,動態資料來源切換。 下面利用

mysql+mysql_proxy實現分離

mysql-_proxymysql讀寫分離需要基於主從架構實現 mysql主從配置:http://hongchen99.blog.51cto.com/12534281/1917137 mysql-proxy:用於實現mysql主從分離,基於主從架構讀寫分離存在的最大問題就是主從同步延遲 安裝my

使用spring實現分離

item ger [] 依據 sign batis repl arch 定義 1. 背景 我們一般應用對數據庫而言都是“讀多寫少”,也就說對數據庫讀取數據的壓力比較大,有一個思路就是說采用數據庫集群的方案, 其中一個是主庫,負責寫入數據,我們稱之為:寫庫; 其它都是從庫,

Spring動態數據源實現分離

character count 方法 cdata mas ebe aso nds evict 一、創建基於ThreadLocal的動態數據源容器,保證數據源的線程安全性 package com.bounter.mybatis.extension; /** * 基

Mysql主從配置,實現分離

windows安裝 建議 xid 分布式 唯一標識 -1 在線下載 命令 進行 大型網站為了軟解大量的並發訪問,除了在網站實現分布式負載均衡,遠遠不夠。到了數據業務層、數據訪問層,如果還是傳統的數據結構,或者只是單單靠一臺服務器扛,如此多的數據庫連接操作,數據庫必然會崩潰,

Mycat實現分離(一)

mycatMycat介紹Mycat是一個國產中間件產品,作用在應用層和數據庫之間架橋,使應用通過MyCat來對後端數據庫進行管理,是一款國人自主的開源的中間件產品。算是比較優秀的一款,前身是阿裏公司在維護,很多公司也慢慢的在嘗試接入這個產品,但不得不說官方文檔似乎做的不太友好。至於為什麽選擇MyCat可能只有

MySQL主從復制 + Mycat實現分離

date windows repl ron 信息 決定 不用 ati 刪掉 說明:兩臺MySQL服務器都是使用CentOS6.5系統,MySQL版本為mysql-5.7.17 MySQL一主一被實現主從復制 註意:寫包括insert,delete,update 操作;讀只有

使用Spring實現分離( MySQL實現主從復制)

sign eve replicat win [] 做了 用戶名 指定 ati 1. 背景 我們一般應用對數據庫而言都是“讀多寫少”,也就說對數據庫讀取數據的壓力比較大,有一個思路就是說采用數據庫集群的方案, 其中一個是主庫,負責寫入數據,我們稱之為:寫庫; 其它都是從庫,

使用Spring+MySql實現分離(二)spring整合多數據庫

ont 依據 xml配置 實現 整合 配置 item 匹配 mic 緊接著上一章,因為現在做的項目還是以spring為主要的容器管理框架,所以寫以下spring如何整合多個數據源。 1. 背景 我們一般應用對數據庫而言都是“讀多寫少”,也就說對數據庫讀取數據的壓力比較大

kylin跨集群配置實現分離

KYLIN HBASE HIVE 讀寫分離 跨集群 社區提供的讀寫分離架構圖如下:通過架構圖可以看到Kylin會訪問兩個集群的HDFS,建議兩個集群的NameService務必不能相同,尤其是集群啟用NameNode HA時,相同的NameService會導致組件在跨集群訪問HDFS時因無

Spring AOP 實現分離

靈活 結果 only method 行為 execution adl 數據源 tps 原文地址:Spring AOP 實現讀寫分離 博客地址:http://www.extlight.com 一、前言 上一篇《MySQL 實現主從復制》 文章中介紹了 MySQL 主從復制

Mysql使用ProxySQL實現分離

mysql讀寫分離 讀寫分離 proxysql proxysql讀寫分離 mysql proxysql ProxySQL簡介: ProxySQL是一個高性能的MySQL中間件,擁有強大的規則引擎。 詳細的中文介紹:別人寫的,基本跟官方無差別 官方文檔:https://github.c

搭建Mycat實現分離

mycat、Linux、讀寫分離、主從同 環境mycat 192.168.43.160 master 192.168.43.109 slave 192.168.43.200 1 服務安裝與配置 (1) [root@

mysql+mycat實現分離

-- sys prop lse 版本 text oss 機制 mys centos7 master slave mycat1.6 client 192.168.41.10 192.168.41.11 192.168.41.12 192.168.41.13