溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

SpringBoot怎么使用Sharding-JDBC實(shí)現(xiàn)數(shù)據(jù)分片和讀寫(xiě)分離

發(fā)布時(shí)間:2021-10-23 16:35:25 來(lái)源:億速云 閱讀:124 作者:iii 欄目:開(kāi)發(fā)技術(shù)

本篇內(nèi)容介紹了“SpringBoot怎么使用Sharding-JDBC實(shí)現(xiàn)數(shù)據(jù)分片和讀寫(xiě)分離”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!

目錄
  • 一、Sharding-JDBC簡(jiǎn)介

  • 二、具體的實(shí)現(xiàn)方式

    •  1、maven引用

    • 2、數(shù)據(jù)庫(kù)準(zhǔn)備

    • 3、Spring配置

    • 4、精準(zhǔn)分片算法和范圍分片算法的Java代碼

    • 5、測(cè)試

一、Sharding-JDBC簡(jiǎn)介

Sharding-JDBC是Sharding-Sphere的一個(gè)產(chǎn)品,它有三個(gè)產(chǎn)品,分別是Sharding-JDBC、Sharding-Proxy和Sharding-Sidecar,這三個(gè)產(chǎn)品提供了標(biāo)準(zhǔn)化的數(shù)據(jù)分片、讀寫(xiě)分離、柔性事務(wù)和數(shù)據(jù)治理功能。我們這里用的是Sharding-JDBC,所以想了解后面兩個(gè)產(chǎn)品的話(huà)可以去它們官網(wǎng)查看。

Sharding-JDBC為輕量級(jí)Java框架,使用客戶(hù)端直連數(shù)據(jù)庫(kù),以jar包形式提供服務(wù),無(wú)需額外部署和依賴(lài),可理解為增強(qiáng)版的JDBC驅(qū)動(dòng),兼容性特別強(qiáng)。適用的ORM框架有JPA, Hibernate, Mybatis, Spring JDBC Template或直接使用JDBC;第三方的數(shù)據(jù)庫(kù)連接池有DBCP, C3P0, BoneCP, Druid等;支持的數(shù)據(jù)庫(kù)有MySQL,Oracle,SQLServer和PostgreSQL;多樣化的配置文件Java,yaml,Spring Boot ,Spring命名空間。其實(shí)這里說(shuō)的都是廢話(huà),大家可以不看,下面我們動(dòng)手開(kāi)始正式配置。

二、具體的實(shí)現(xiàn)方式

 1、maven引用

我這里用的配置方式是Spring命名空間配置,所以只需要引用sharding-jdbc-spring-namespace就可以了,還有要注意的是我用的不是當(dāng)當(dāng)網(wǎng)的sharding,注意groupId是io.shardingsphere。如果用的是其它配置方式可以去http://maven.aliyun.com/nexus/#nexus-search;quick~io.shardingsphere網(wǎng)站查找相應(yīng)maven引用

<dependency>
    <groupId>io.shardingsphere</groupId>
    <artifactId>sharding-jdbc-spring-namespace</artifactId>
    <version>3.0.0.M1</version>
</dependency>

2、數(shù)據(jù)庫(kù)準(zhǔn)備

我這里用的是mysql數(shù)據(jù)庫(kù),根據(jù)我們項(xiàng)目的具體需求,我準(zhǔn)備了三個(gè)主庫(kù)和對(duì)應(yīng)的從庫(kù)。模擬的主庫(kù)名有master,暫時(shí)沒(méi)有做對(duì)應(yīng)從庫(kù),所以對(duì)應(yīng)的從庫(kù)還是指向master;第二個(gè)主庫(kù)有master_1,對(duì)應(yīng)的從庫(kù)有master_1_slaver_1,master_1_slave_2;第三個(gè)主庫(kù)有master_2,對(duì)應(yīng)的從庫(kù)有master_2_slave_1,master_2_slave_2。
數(shù)據(jù)庫(kù)中的表也做了分表,下面是對(duì)應(yīng)的mysql截圖。

SpringBoot怎么使用Sharding-JDBC實(shí)現(xiàn)數(shù)據(jù)分片和讀寫(xiě)分離

這第一幅圖上的主從庫(kù)都應(yīng)該在不同的服務(wù)器上的,但這里只是為了模擬所以就建在了本地服務(wù)器上了。我們讀寫(xiě)分離中的寫(xiě)操作只會(huì)發(fā)生在主庫(kù)上,從庫(kù)會(huì)自動(dòng)同步主庫(kù)上的數(shù)據(jù)并為讀提供數(shù)據(jù)。數(shù)據(jù)庫(kù)的主從復(fù)制在上篇博文中做了詳細(xì)的介紹,大家可以去看看http://www.kemok4.com/article/226077.htm

SpringBoot怎么使用Sharding-JDBC實(shí)現(xiàn)數(shù)據(jù)分片和讀寫(xiě)分離

這幅圖作為我們本來(lái)的主庫(kù),下面做的分庫(kù)和分表都是基于這個(gè)庫(kù)中的訂單表分的。所以分庫(kù)中的表只有訂單表和訂單明細(xì)表。

SpringBoot怎么使用Sharding-JDBC實(shí)現(xiàn)數(shù)據(jù)分片和讀寫(xiě)分離

第三幅圖截的是第二個(gè)主庫(kù),里面對(duì)訂單和訂單明細(xì)表做了分表操作,具體的分片策略和分片算法下面再做介紹。第三個(gè)主表和第二個(gè)主表是一樣的,所有的從表都和對(duì)應(yīng)的主表是一致的。

3、Spring配置

數(shù)據(jù)庫(kù)信息配置文件db.properties配置可以配置兩份,分為開(kāi)發(fā)版和測(cè)試版,如下:

# master
Master.url=jdbc:mysql://localhost:3306/master?useUnicode=true&characterEncoding=utf8&autoReconnect=true&rewriteBatchedStatements=true
Master.username=root
Master.password=123456
Slave.url=jdbc:mysql://localhost:3306/master?useUnicode=true&characterEncoding=utf8&autoReconnect=true&rewriteBatchedStatements=true
Slave.username=root
Slave.password=123456

# maste_1
Master_1.url=jdbc:mysql://localhost:3306/master_1?useUnicode=true&characterEncoding=utf8&autoReconnect=true&rewriteBatchedStatements=true
Master_1.username=root
Master_1.password=123456
Master_1_Slave_1.url=jdbc:mysql://localhost:3306/master_1_slave_1?useUnicode=true&characterEncoding=utf8&autoReconnect=true&rewriteBatchedStatements=true
Master_1_Slave_1.username=root
Master_1_Slave_1.password=123456
Master_1_Slave_2.url=jdbc:mysql://localhost:3306/master_1_slave_2?useUnicode=true&characterEncoding=utf8&autoReconnect=true&rewriteBatchedStatements=true
Master_1_Slave_2.username=root
Master_1_Slave_2.password=123456

# master_2
Master_2.url=jdbc:mysql://localhost:3306/master_2?useUnicode=true&characterEncoding=utf8&autoReconnect=true&rewriteBatchedStatements=true
Master_2.username=root
Master_2.password=123456
Master_2_Slave_1.url=jdbc:mysql://localhost:3306/master_2_slave_1?useUnicode=true&characterEncoding=utf8&autoReconnect=true&rewriteBatchedStatements=true
Master_2_Slave_1.username=root
Master_2_Slave_1.password=123456
Master_2_Slave_2.url=jdbc:mysql://localhost:3306/master_2_slave_2?useUnicode=true&characterEncoding=utf8&autoReconnect=true&rewriteBatchedStatements=true
Master_2_Slave_2.username=root
Master_2_Slave_2.password=123456

Spring對(duì)應(yīng)的配置:
Spring-Sphere官網(wǎng)中的demo里用的都是行表達(dá)式的分片策略,但是行表達(dá)式的策略不利于數(shù)據(jù)庫(kù)和表的橫向擴(kuò)展,所以我這里用的是標(biāo)準(zhǔn)分片策略,精準(zhǔn)分片算法和范圍分片算法。因?yàn)槲覀冺?xiàng)目中暫時(shí)用的分片鍵都是user_id單一鍵,所以說(shuō)不存在復(fù)合分片策略,也用不到Hint分片策略,行表達(dá)式分片策略和不分片策略。

<?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:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:sharding="http://shardingsphere.io/schema/shardingsphere/sharding"
       xmlns:master-slave="http://shardingsphere.io/schema/shardingsphere/masterslave"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
                        http://www.springframework.org/schema/beans/spring-beans.xsd 
                        http://www.springframework.org/schema/context 
                        http://www.springframework.org/schema/context/spring-context.xsd
                        http://www.springframework.org/schema/tx 
                        http://www.springframework.org/schema/tx/spring-tx.xsd
                        http://shardingsphere.io/schema/shardingsphere/sharding 
                        http://shardingsphere.io/schema/shardingsphere/sharding/sharding.xsd 
                        http://shardingsphere.io/schema/shardingsphere/masterslave  
                        http://shardingsphere.io/schema/shardingsphere/masterslave/master-slave.xsd">
                        
    <context:component-scan base-package="com.jihao" />
    
    <!-- db.properties數(shù)據(jù)庫(kù)信息配置 -->
    <bean id="property" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
	    <property name="location" value="classpath:property/db_dev.properties" />
	</bean>
	<!-- 主庫(kù) -->
    <bean id="master" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="${Master.url}"/>
        <property name="username" value="${Master.username}"/>
        <property name="password" value="${Master.password}"/>
    </bean>
	<!-- 主庫(kù)的從庫(kù) -->
    <bean id="slave" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="${Slave.url}"/>
        <property name="username" value="${Slave.username}"/>
        <property name="password" value="${Slave.password}"/>
    </bean>
    <!-- 主庫(kù)的分庫(kù)1 -->
    <bean id="master_1" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="${Master_1.url}"/>
        <property name="username" value="${Master_1.username}"/>
        <property name="password" value="${Master_1.password}"/>
    </bean>
    
    <!-- 分庫(kù)1的從庫(kù)1 -->
    <bean id="master_1_slave_1" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="${Master_1_Slave_1.url}"/>
        <property name="username" value="${Master_1_Slave_1.username}"/>
        <property name="password" value="${Master_1_Slave_1.password}"/>
    </bean>
    
    <!-- 分庫(kù)1的從庫(kù)2 -->
    <bean id="master_1_slave_2" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="${Master_1_Slave_2.url}"/>
        <property name="username" value="${Master_1_Slave_2.username}"/>
        <property name="password" value="${Master_1_Slave_2.password}"/>
    </bean>

    <!-- 主庫(kù)的分庫(kù)2 -->
    <bean id="master_2" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="${Master_2.url}"/>
        <property name="username" value="${Master_2.username}"/>
        <property name="password" value="${Master_2.password}"/>
    </bean>

    <!-- 分庫(kù)2的從庫(kù)1 -->
    <bean id="master_2_slave_1" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="${Master_2_Slave_1.url}"/>
        <property name="username" value="${Master_2_Slave_1.username}"/>
        <property name="password" value="${Master_2_Slave_1.password}"/>
    </bean>

    <!-- 分庫(kù)2的從庫(kù)2 -->
    <bean id="master_2_slave_2" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="${Master_2_Slave_2.url}"/>
        <property name="username" value="${Master_2_Slave_2.username}"/>
        <property name="password" value="${Master_2_Slave_2.password}"/>
    </bean>

	<!-- 主從關(guān)系配置 -->
    <bean id="randomStrategy" class="io.shardingsphere.core.api.algorithm.masterslave.RandomMasterSlaveLoadBalanceAlgorithm" />
    <master-slave:data-source id="ms_master" master-data-source-name="master" slave-data-source-names="slave" strategy-ref="randomStrategy" />
    <master-slave:data-source id="ms_master_1" master-data-source-name="master_1" slave-data-source-names="master_1_slave_1, master_1_slave_2" strategy-ref="randomStrategy" />
    <master-slave:data-source id="ms_master_2" master-data-source-name="master_2" slave-data-source-names="master_2_slave_1, master_2_slave_2" strategy-ref="randomStrategy" />
    
    <!-- 分庫(kù)策略  精確分片算法 -->
    <bean id="preciseDatabaseStrategy" class="com.jihao.algorithm.PreciseModuleDatabaseShardingAlgorithm" />
    <!-- 分庫(kù)策略  范圍分片算法 -->
    <bean id="rangeDatabaseStrategy" class="com.jihao.algorithm.RangeModuleDatabaseShardingAlgorithm" />
    <!-- 分表策略  精確分片算法 -->
    <bean id="preciseTableStrategy" class="com.jihao.algorithm.PreciseModuleTableShardingAlgorithm" />
    <!-- 分表策略  范圍分片算法-->
    <bean id="rangeTableStrategy" class="com.jihao.algorithm.RangeModuleTableShardingAlgorithm" />
    <sharding:standard-strategy id="databaseStrategy" sharding-column="user_id" precise-algorithm-ref="preciseDatabaseStrategy" range-algorithm-ref="rangeDatabaseStrategy" />
    <!-- 分表策略 -->
    <sharding:standard-strategy id="tableStrategy" sharding-column="user_id" precise-algorithm-ref="preciseTableStrategy" range-algorithm-ref="rangeTableStrategy" />
    
    <!-- 行表達(dá)式算法 -->
    <!-- <sharding:inline-strategy id="databaseStrategy" sharding-column="user_id" algorithm-expression="demo_ds_ms_$->{user_id % 2}" />
    <sharding:inline-strategy id="orderTableStrategy" sharding-column="order_id" algorithm-expression="t_order_$->{order_id % 2}" />
    <sharding:inline-strategy id="orderItemTableStrategy" sharding-column="order_item_id" algorithm-expression="t_order_item_$->{order_item_id % 2}" /> -->
    
    <sharding:data-source id="shardingDataSource">
        <sharding:sharding-rule data-source-names="ms_master,ms_master_1,ms_master_2">
            <sharding:table-rules>
                <sharding:table-rule logic-table="t_order" actual-data-nodes="ms_master_$->{1..2}.t_order_$->{1..3}" database-strategy-ref="databaseStrategy" table-strategy-ref="tableStrategy" generate-key-column-name="order_id"/>
                <sharding:table-rule logic-table="t_order_item" actual-data-nodes="ms_master_$->{1..2}.t_order_item_$->{1..3}" database-strategy-ref="databaseStrategy" table-strategy-ref="tableStrategy" generate-key-column-name="order_item_id"/>
            </sharding:table-rules>
        </sharding:sharding-rule>
    </sharding:data-source>
    
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="shardingDataSource" />
    </bean>
    <tx:annotation-driven />
    
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
	    <!-- 用于在控制臺(tái)打印sql(不需要的可以注釋掉這一行) -->
    	<property name="configLocation" value="classpath:log/mybatis-config.xml"></property>
        <property name="dataSource" ref="shardingDataSource"/>
        <property name="mapperLocations" value="classpath*:com/jihao/mapper/*.xml"/>
    </bean>
    
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.jihao"/>
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
    </bean>
</beans>

4、精準(zhǔn)分片算法和范圍分片算法的Java代碼

標(biāo)準(zhǔn)分片策略,精準(zhǔn)分片算法

package com.jihao.algorithm;

import io.shardingsphere.core.api.algorithm.sharding.PreciseShardingValue;
import io.shardingsphere.core.api.algorithm.sharding.standard.PreciseShardingAlgorithm;

import java.util.Collection;

import com.alibaba.fastjson.JSON;

/**
 * 自定義標(biāo)準(zhǔn)分片策略,使用精確分片算法(=與IN)
 * @author JiHao
 *
 */
public class PreciseModuleDatabaseShardingAlgorithm implements PreciseShardingAlgorithm<Long>{

	@Override
	public String doSharding(Collection<String> availableTargetNames,
			PreciseShardingValue<Long> preciseShardingValue) {
		System.out.println("collection:" + JSON.toJSONString(availableTargetNames) + ",preciseShardingValue:" + JSON.toJSONString(preciseShardingValue));
        for (String name : availableTargetNames) {
        	// =與IN中分片鍵對(duì)應(yīng)的值
        	String value = String.valueOf(preciseShardingValue.getValue());
        	// 分庫(kù)的后綴
        	int i = 1;
        	// 求分庫(kù)后綴名的遞歸算法
            if (name.endsWith("_" + countDatabaseNum(Long.parseLong(value), i))) {
                return name;
            }
        }
        throw new UnsupportedOperationException();
	}

	/**
	 * 計(jì)算該量級(jí)的數(shù)據(jù)在哪個(gè)數(shù)據(jù)庫(kù)
	 * @return
	 */
	private String countDatabaseNum(long columnValue, int i){
		// ShardingSphereConstants每個(gè)庫(kù)中定義的數(shù)據(jù)量
		long left = ShardingSphereConstants.databaseAmount * (i-1);
		long right = ShardingSphereConstants.databaseAmount * i;
		if(left < columnValue && columnValue <= right){
			return String.valueOf(i);
		}else{
			i++;
			return countDatabaseNum(columnValue, i);
		}
	}

}

標(biāo)準(zhǔn)分片策略,范圍分片算法

package com.jihao.algorithm;

import io.shardingsphere.core.api.algorithm.sharding.RangeShardingValue;
import io.shardingsphere.core.api.algorithm.sharding.standard.RangeShardingAlgorithm;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Range;

/**
 * 自定義標(biāo)準(zhǔn)分庫(kù)策略,使用范圍分片算法(BETWEEN AND)
 * @author JiHao
 *
 */
public class RangeModuleDatabaseShardingAlgorithm implements RangeShardingAlgorithm<Long>{

	@Override
	public Collection<String> doSharding(
			Collection<String> availableTargetNames,
			RangeShardingValue<Long> rangeShardingValue) {
		System.out.println("Range collection:" + JSON.toJSONString(availableTargetNames) + ",rangeShardingValue:" + JSON.toJSONString(rangeShardingValue));
        Collection<String> collect = new ArrayList<>();
        Range<Long> valueRange = rangeShardingValue.getValueRange();
        // BETWEEN AND中分片鍵對(duì)應(yīng)的最小值
        long lowerEndpoint = Long.parseLong(String.valueOf(valueRange.lowerEndpoint()));
        // BETWEEN AND中分片鍵對(duì)應(yīng)的最大值
        long upperEndpoint = Long.parseLong(String.valueOf(valueRange.upperEndpoint()));
        // 分表的后綴
        int i = 1;
        List<Integer> arrs = new ArrayList<Integer>();
        // 求分表后綴名的遞歸算法
        List<Integer> list = countDatabaseNum(i, lowerEndpoint, upperEndpoint, arrs);
        for (Integer integer : list) {
			for (String each : availableTargetNames) {
				if (each.endsWith("_" + integer)) {
                  collect.add(each);
				}
			}
		}
        return collect;
	}
	
	/**
	 * 計(jì)算該量級(jí)的數(shù)據(jù)在哪個(gè)表
	 * @param columnValue
	 * @param i
	 * @param lowerEndpoint 最小區(qū)間
	 * @param upperEndpoint 最大區(qū)間
	 * @return
	 */
	private List<Integer> countDatabaseNum(int i, long lowerEndpoint, long upperEndpoint, List<Integer> arrs){
		long left = ShardingSphereConstants.databaseAmount * (i-1);
		long right = ShardingSphereConstants.databaseAmount * i;
		// 區(qū)間最大值小于分庫(kù)最大值
		if(left < upperEndpoint && upperEndpoint <= right){
			arrs.add(i);
			return arrs;
		}else{
			if(left < lowerEndpoint && lowerEndpoint <= right){
				arrs.add(i);
			}
			i++;
			return countDatabaseNum(i, lowerEndpoint, upperEndpoint, arrs);
		}
	}
}

分庫(kù)的策略用的和分庫(kù)的代碼是一樣的,不同之處就是分庫(kù)用的是databaseAmount,分表用的是tableAmount。下面的ShardingSphereConstants的代碼。

package com.jihao.algorithm;

/**
 * ShardingSphere中用到的常量
 * @author JiHao
 *
 */
public class ShardingSphereConstants {
	
	/**
	 * 訂單、優(yōu)惠券相關(guān)的表,按用戶(hù)數(shù)量分庫(kù),64w用戶(hù)數(shù)據(jù)為一個(gè)庫(kù)
	 * (0,64w]
	 */
	public static int databaseAmount = 640000;
	
	/**
	 * 一個(gè)訂單表里存10000的用戶(hù)訂單
	 * (0,1w]
	 */
	public static int tableAmount = 10000;
	
}

到這里所有的配置基本上都已經(jīng)完成了,下面的測(cè)試。

5、測(cè)試

下面是測(cè)試的mybatis的測(cè)試文件,都是最基礎(chǔ)的就不講解了。

<?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 namespace="com.jihao.dao.TestShardingMapper">

	<resultMap id="BaseResultMap" type="com.jihao.entity.Order">
	    <id column="order_id" jdbcType="INTEGER" property="orderId" />
	    <result column="user_id" jdbcType="INTEGER" property="userId" />
	    <result column="status" jdbcType="INTEGER" property="status" />
  	</resultMap>
  
  	<insert id="insert" parameterType="com.jihao.entity.Order" useGeneratedKeys="true" keyProperty="orderId">
    	INSERT INTO t_order (
    		user_id, status
   		)
    	VALUES (
    		#{userId,jdbcType=INTEGER}, 
    		#{status,jdbcType=VARCHAR}
   		)
  	</insert>

	<insert id="insertItem" useGeneratedKeys="true" keyProperty="orderItemId">
        INSERT INTO t_order_item (
          order_id, user_id
        )
        VALUES (
        	#{orderId,jdbcType=INTEGER},
        	#{userId,jdbcType=INTEGER}
        )
    </insert>
    
    <select id="searchOrder" resultMap="BaseResultMap">
    	SELECT * from t_order
    </select>
    
    <select id="queryWithEqual" resultMap="BaseResultMap">
    	SELECT * FROM t_order WHERE user_id=51
    </select>
    
    <select id="queryWithIn" resultMap="BaseResultMap">
    	SELECT * FROM t_order WHERE user_id IN (50, 51)
    </select>
    
    <select id="queryWithBetween" resultMap="BaseResultMap">
    	SELECT * FROM t_order WHERE user_id between 10000 and 30000
    </select>
    
    <select id="queryUser" resultType="Map">
    	SELECT * FROM t_user
    </select>
    
</mapper>

下面對(duì)應(yīng)的mapper的Java代碼

package com.jihao.dao;

import java.util.List;
import java.util.Map;

import org.apache.ibatis.annotations.Mapper;

import com.jihao.entity.Order;
import com.jihao.entity.OrderItem;

@Mapper
public interface TestShardingMapper {
	
    int insert(Order record);
    
    int insertItem(OrderItem record);
    
    List<Order> searchOrder();
    
    List<Order> queryWithEqual();
    
    List<Order> queryWithIn();
    
    List<Order> queryWithBetween();
    
    List<Map<String, Object>> queryUser();
    
}

下面是對(duì)應(yīng)的訂單entity代碼

package com.jihao.entity;


/**
 * 訂單
 * @author JiHao
 */
public class Order {
	
    private Long orderId;

    private Integer userId;
    
    private String status;

	public Long getOrderId() {
		return orderId;
	}

	public void setOrderId(Long orderId) {
		this.orderId = orderId;
	}

	public Integer getUserId() {
		return userId;
	}

	public void setUserId(Integer userId) {
		this.userId = userId;
	}

	public String getStatus() {
		return status;
	}

	public void setStatus(String status) {
		this.status = status;
	}
    
}

下面是對(duì)應(yīng)的訂單明細(xì)entity代碼

package com.jihao.entity;


/**
 * 測(cè)試分片
 * @author JiHao
 */
public class OrderItem {
	
	private Long orderItemId;
	
    private Long orderId;

    private Integer userId;
    

	public Long getOrderId() {
		return orderId;
	}

	public void setOrderId(Long orderId) {
		this.orderId = orderId;
	}

	public Integer getUserId() {
		return userId;
	}

	public void setUserId(Integer userId) {
		this.userId = userId;
	}

	public Long getOrderItemId() {
		return orderItemId;
	}

	public void setOrderItemId(Long orderItemId) {
		this.orderItemId = orderItemId;
	}
}

下面是測(cè)試的controller,并沒(méi)有寫(xiě)Junit測(cè)試。

package com.jihao.controller.test;


import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.jihao.dao.TestShardingMapper;
import com.jihao.entity.Order;
import com.jihao.entity.OrderItem;
import com.jihao.result.Result;
import com.jihao.result.ResultUtil;

/**
 * 測(cè)試分片
 * @author JiHao
 *
 */
@Controller
@RequestMapping(value = "test")
public class TestShardingController {

	@Autowired
    private TestShardingMapper testShardingMapper;

    /**
     * 測(cè)試添加
     * @return
     */
    @ResponseBody
    @GetMapping(value = "/testAdd")
    public String testAdd(){
    	for (int i = 0; i < 10; i++) {
            Order order = new Order();
//            order.setUserId(50);
//            order.setUserId(51);
//            order.setUserId(10001);
            order.setUserId(20001);
            order.setStatus("INSERT_TEST");
            int count = testShardingMapper.insert(order);
            System.out.println(count);
            long orderId = order.getOrderId();
            System.out.println(order.getOrderId());
            OrderItem item = new OrderItem();
            item.setOrderId(orderId);
//            order.setUserId(50);
//            order.setUserId(51);
//            order.setUserId(10001);
            order.setUserId(20001);
            testShardingMapper.insertItem(item);
        }
        return "success";
    }
    
    /**
     * 測(cè)試搜索
     * @return
     */
    @ResponseBody
    @GetMapping(value = "/testSearch")
    public Result searchData(){
    	List<Order> list = testShardingMapper.searchOrder();
    	System.out.println(list.size() + " all");
    	List<Order> list1 = testShardingMapper.queryWithIn();
    	System.out.println(list1.size() + " In");
    	List<Order> list2 = testShardingMapper.queryWithEqual();
    	System.out.println(list2.size() + " Equal");
    	List<Order> list3 = testShardingMapper.queryWithBetween();
    	System.out.println(list3.size() + " Between");
    	List<Map<String, Object>> list4 = testShardingMapper.queryUser();
    	System.out.println(list4.size() + " user");
    	return ResultUtil.success(null);
    }
}

這里要重點(diǎn)提出來(lái)的是做搜索測(cè)試的時(shí)候,因?yàn)橹鲝膸?kù)都在我本地服務(wù)器上,并沒(méi)有做主從復(fù)制,大家可以根據(jù)我上篇博文配置一下就可以順利操作了,如果沒(méi)有配置的話(huà)從庫(kù)里是不會(huì)有數(shù)據(jù)的,所以在做完寫(xiě)操作時(shí)把主庫(kù)中的數(shù)據(jù)手動(dòng)傳輸給從庫(kù),這樣才能讀出數(shù)據(jù)。

“SpringBoot怎么使用Sharding-JDBC實(shí)現(xiàn)數(shù)據(jù)分片和讀寫(xiě)分離”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI