国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

javaer你還在手寫分表分庫?來看看這個框架怎么做的 干貨滿滿

這篇具有很好參考價值的文章主要介紹了javaer你還在手寫分表分庫?來看看這個框架怎么做的 干貨滿滿。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

java orm框架easy-query分庫分表之分表

高并發(fā)三駕馬車:分庫分表、MQ、緩存。今天給大家?guī)淼木褪欠謳旆直淼母韶浗鉀Q方案,哪怕你不用我的框架也可以從中聽到不一樣的結(jié)局方案和實現(xiàn)。

一款支持自動分表分庫的orm框架easy-query 幫助您解脫跨庫帶來的復(fù)雜業(yè)務(wù)代碼,并且提供多種結(jié)局方案和自定義路由來實現(xiàn)比中間件更高性能的數(shù)據(jù)庫訪問。

  • GITHUB github地址

  • GITEE gitee地址文章來源地址http://www.zghlxwxcb.cn/news/detail-459517.html

目前市面上有的分庫分表JAVA組件有很多:中間件代理有:sharding-sphere(proxy),mycat 客戶端JDBC:sharding-sphere(jdbc)等等,中間件因為代理了一層會導(dǎo)致所有的sql執(zhí)行都要經(jīng)過中間件,性能會大大折扣,但是因為中間部署可以提供更加省的連接池,客戶端無需代理,僅需對sql進(jìn)行分析即可實現(xiàn),但是越靠近客戶的模式可以優(yōu)化的性能越高,所以本次帶來的框架可以提供前所未有的分片規(guī)則自由和前所未有的便捷高性能。

本文 demo地址 https://github.com/xuejmnet/easy-sharding-test

怎么樣的orm算是支持分表分庫

首先orm是否支持分表分庫不僅僅是看框架是否支持動態(tài)修改表名,讓數(shù)據(jù)正確存入對應(yīng)的表或者修改對應(yīng)的數(shù)據(jù),這些說實話都是最最簡單的實現(xiàn),真正需要支持分庫分表那么需要orm實現(xiàn)復(fù)雜的跨表聚合查詢,這才是分表分庫的精髓,很顯然目前的orm很少有支持的。接下來我將給大家演示基于springboot3.x的分表分庫演示,取模分片和時間分片。本章我們主要以使用為主后面下一章我們來講解優(yōu)化方案,包括原理解析,后續(xù)有更多的關(guān)于分表分庫的經(jīng)驗是博主多年下來的實戰(zhàn)經(jīng)驗分享給大家保證大家的happy coding。

初始化項目

進(jìn)入 https://start.spring.io/ 官網(wǎng)直接下載
javaer你還在手寫分表分庫?來看看這個框架怎么做的 干貨滿滿

安裝依賴


		<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>druid</artifactId>
			<version>1.2.15</version>
		</dependency>
		<!-- mysql驅(qū)動 -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>8.0.17</version>
		</dependency>
		<dependency>
			<groupId>com.easy-query</groupId>
			<artifactId>sql-springboot-starter</artifactId>
			<version>0.9.7</version>
		</dependency>
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<version>1.18.18</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

application.yml配置

server:
  port: 8080

spring:

  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://127.0.0.1:3306/easy-sharding-test?serverTimezone=GMT%2B8&characterEncoding=utf-8&useSSL=false&allowMultiQueries=true&rewriteBatchedStatements=true
    username: root
    password: root

logging:
  level:
    com.easy.query.core: debug

easy-query:
  enable: true
  name-conversion: underlined
  database: mysql

取模

常見的分片方式之一就是取模分片,取模分片可以讓以分片鍵為條件的處理完美路由到對應(yīng)的表,性能上來說非常非常高,但是局限性也是很大的因為無意義的id路由會導(dǎo)致僅支持這一個id條件而不支持其他條件的路由,只能全分片表掃描來獲取對應(yīng)的數(shù)據(jù),但是他的實現(xiàn)和理解也是最容易的,當(dāng)然后續(xù)還有基因分片一種可以部分解決僅支持id帶來的問題不過也并不是非常的完美。

簡單的取模分片

我們本次測試案例采用order表對其進(jìn)行5表拆分:order_00,order_01,order_02,order_03,order_04,采用訂單id取模進(jìn)行分表
數(shù)據(jù)庫腳本

CREATE DATABASE IF NOT EXISTS `easy-sharding-test` CHARACTER SET 'utf8mb4';
USE `easy-sharding-test`;
create table order_00
(
    id varchar(32) not null comment '主鍵ID'primary key,
    uid varchar(50) not null comment '用戶id',
    order_no int null comment '訂單號'
)comment '訂單表';
create table order_01
(
    id varchar(32) not null comment '主鍵ID'primary key,
    uid varchar(50) not null comment '用戶id',
    order_no int null comment '訂單號'
)comment '訂單表';
create table order_02
(
    id varchar(32) not null comment '主鍵ID'primary key,
    uid varchar(50) not null comment '用戶id',
    order_no int null comment '訂單號'
)comment '訂單表';
create table order_03
(
    id varchar(32) not null comment '主鍵ID'primary key,
    uid varchar(50) not null comment '用戶id',
    order_no int null comment '訂單號'
)comment '訂單表';
create table order_04
(
    id varchar(32) not null comment '主鍵ID'primary key,
    uid varchar(50) not null comment '用戶id',
    order_no int null comment '訂單號'
)comment '訂單表';
//定義了一個對象并且設(shè)置表名和分片初始化器`shardingInitializer`,設(shè)置id為主鍵,并且設(shè)置id為分表建
@Data
@Table(value = "order",shardingInitializer = OrderShardingInitializer.class)
public class OrderEntity {
    @Column(primaryKey = true)
    @ShardingTableKey
    private String id;
    private String uid;
    private Integer orderNo;
}
//編寫訂單取模初始化器,只需要實現(xiàn)兩個方法,當(dāng)然你也可以自己實現(xiàn)對應(yīng)的`EntityShardingInitializer`這邊是繼承`easy-query`框架提供的分片取模初始化器
@Component
public class OrderShardingInitializer extends AbstractShardingModInitializer<OrderEntity> {
     /**
     * 設(shè)置模幾我們模5就設(shè)置5
     * @return
     */
    @Override
    protected int mod() {
        return 5;
    }

    /**
     * 編寫模5后的尾巴長度默認(rèn)我們設(shè)置2就是左補0
     * @return
     */
    @Override
    protected int tailLength() {
        return 2;
    }
}
//編寫分片規(guī)則`AbstractModTableRule`由框架提供取模分片路由規(guī)則,如果需要自己實現(xiàn)可以繼承`AbstractTableRouteRule`這個抽象類
@Component
public class OrderTableRouteRule extends AbstractModTableRule<OrderEntity> {
    @Override
    protected int mod() {
        return 5;
    }

    @Override
    protected int tailLength() {
        return 2;
    }
}

初始化工作做好了開始編寫代碼

新增初始化


@RestController
@RequestMapping("/order")
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class OrderController {

    private final EasyQuery easyQuery;

    @GetMapping("/init")
    public Object init() {
        ArrayList<OrderEntity> orderEntities = new ArrayList<>(100);
        List<String> users = Arrays.asList("xiaoming", "xiaohong", "xiaolan");

        for (int i = 0; i < 100; i++) {
            OrderEntity orderEntity = new OrderEntity();
            orderEntity.setId(String.valueOf(i));
            int i1 = i % 3;
            String uid = users.get(i1);
            orderEntity.setUid(uid);
            orderEntity.setOrderNo(i);
            orderEntities.add(orderEntity);
        }
        long l = easyQuery.insertable(orderEntities).executeRows();
        return "成功插入:"+l;
    }
}

javaer你還在手寫分表分庫?來看看這個框架怎么做的 干貨滿滿

javaer你還在手寫分表分庫?來看看這個框架怎么做的 干貨滿滿

查詢單條

按分片鍵查詢

可以完美的路由到對應(yīng)的數(shù)據(jù)庫表和操作單表擁有一樣的性能

    @GetMapping("/first")
    public Object first(@RequestParam("id") String id) {
        OrderEntity orderEntity = easyQuery.queryable(OrderEntity.class)
                .whereById(id).firstOrNull();
        return orderEntity;
    }
http://localhost:8080/order/first?id=20
{"id":"20","uid":"xiaolan","orderNo":20}


http-nio-8080-exec-1, name:ds0, Preparing: SELECT t.`id`,t.`uid`,t.`order_no` FROM `order_03` t WHERE t.`id` = ? LIMIT 1
==> http-nio-8080-exec-1, name:ds0, Parameters: 20(String)
<== Total: 1

日志稍微解釋一下

  • http-nio-8080-exec-1表示當(dāng)前語句執(zhí)行的線程,默認(rèn)多個分片聚合后需要再線程池中查詢數(shù)據(jù)后聚合返回。
  • name:ds0 表示數(shù)據(jù)源叫做ds0,如果不分庫那么這個數(shù)據(jù)源可以忽略,也可以自己指定配置文件中或者設(shè)置defaultDataSourceName

全程無需您去計算路由到哪里,并且規(guī)則和業(yè)務(wù)代碼已經(jīng)脫離解耦

不按分片鍵查詢

當(dāng)我們的查詢?yōu)榉欠制I查詢那么會導(dǎo)致路由需要進(jìn)行全分片掃描然后來獲取對應(yīng)的數(shù)據(jù)進(jìn)行判斷哪個時我們要的


    @GetMapping("/firstByUid")
    public Object firstByUid(@RequestParam("uid") String uid) {
        OrderEntity orderEntity = easyQuery.queryable(OrderEntity.class)
                .where(o->o.eq(OrderEntity::getUid,uid)).firstOrNull();
        return orderEntity;
    }

http://localhost:8080/order/firstByUid?uid=xiaoming
{"id":"18","uid":"xiaoming","orderNo":18}

//這邊把日志精簡了一下可以看到他是開啟了5個線程進(jìn)行分片查詢
==> SHARDING_EXECUTOR_1, name:ds0, Preparing: SELECT t.`id`,t.`uid`,t.`order_no` FROM `order_00` t WHERE t.`uid` = ? LIMIT 1
==> SHARDING_EXECUTOR_5, name:ds0, Preparing: SELECT t.`id`,t.`uid`,t.`order_no` FROM `order_03` t WHERE t.`uid` = ? LIMIT 1
==> SHARDING_EXECUTOR_4, name:ds0, Preparing: SELECT t.`id`,t.`uid`,t.`order_no` FROM `order_04` t WHERE t.`uid` = ? LIMIT 1
==> SHARDING_EXECUTOR_3, name:ds0, Preparing: SELECT t.`id`,t.`uid`,t.`order_no` FROM `order_02` t WHERE t.`uid` = ? LIMIT 1
==> SHARDING_EXECUTOR_2, name:ds0, Preparing: SELECT t.`id`,t.`uid`,t.`order_no` FROM `order_01` t WHERE t.`uid` = ? LIMIT 1
==> SHARDING_EXECUTOR_3, name:ds0, Parameters: xiaoming(String)
==> SHARDING_EXECUTOR_4, name:ds0, Parameters: xiaoming(String)
==> SHARDING_EXECUTOR_5, name:ds0, Parameters: xiaoming(String)
==> SHARDING_EXECUTOR_1, name:ds0, Parameters: xiaoming(String)
==> SHARDING_EXECUTOR_2, name:ds0, Parameters: xiaoming(String)
<== Total: 1

因為uid不是分片鍵所以在分片查詢的時候需要遍歷所有的表然后返回對應(yīng)的數(shù)據(jù),可能有同學(xué)會問就這?當(dāng)然這只是簡單演示后續(xù)下一篇我會給出具體的優(yōu)化方案來進(jìn)行處理。

分頁查詢

分片后的分頁查詢是分片下的一個難點,這邊框架自帶功能,分片后分頁之所以難是因為如果是自行實現(xiàn)業(yè)務(wù)代碼會變得非常復(fù)雜,有一種非常簡易的方式就是把分頁重寫pageIndex永遠(yuǎn)為1,然后全部取到內(nèi)存后在進(jìn)行stream過濾,但是帶來的另一個問題就是pageIndex不能便宜過大不然內(nèi)存會完全存不下導(dǎo)致內(nèi)存爆炸,并且如果翻頁到最后幾頁那將是災(zāi)難性的,給程序帶來極其不穩(wěn)定,但是easy-query提供了和sharding-sphere一樣的分片聚合方式并且因為靠近業(yè)務(wù)的關(guān)系所以可以有效的優(yōu)化深度分頁pageIndex過大


    @GetMapping("/page")
    public Object page(@RequestParam("pageIndex") Integer pageIndex,@RequestParam("pageSize") Integer pageSize) {
        EasyPageResult<OrderEntity> pageResult = easyQuery.queryable(OrderEntity.class)
                .orderByAsc(o -> o.column(OrderEntity::getOrderNo))
                .toPageResult(pageIndex, pageSize);
        return pageResult;
    }


http://localhost:8080/order/page?pageIndex=1&pageSize=10

{"total":100,"data":[{"id":"0","uid":"xiaoming","orderNo":0},{"id":"1","uid":"xiaohong","orderNo":1},{"id":"2","uid":"xiaolan","orderNo":2},{"id":"3","uid":"xiaoming","orderNo":3},{"id":"4","uid":"xiaohong","orderNo":4},{"id":"5","uid":"xiaolan","orderNo":5},{"id":"6","uid":"xiaoming","orderNo":6},{"id":"7","uid":"xiaohong","orderNo":7},{"id":"8","uid":"xiaolan","orderNo":8},{"id":"9","uid":"xiaoming","orderNo":9}]}
==> SHARDING_EXECUTOR_3, name:ds0, Preparing: SELECT COUNT(1) FROM `order_02` t
==> SHARDING_EXECUTOR_2, name:ds0, Preparing: SELECT COUNT(1) FROM `order_03` t
==> SHARDING_EXECUTOR_5, name:ds0, Preparing: SELECT COUNT(1) FROM `order_04` t
==> SHARDING_EXECUTOR_1, name:ds0, Preparing: SELECT COUNT(1) FROM `order_01` t
==> SHARDING_EXECUTOR_4, name:ds0, Preparing: SELECT COUNT(1) FROM `order_00` t
<== Total: 1
==> SHARDING_EXECUTOR_5, name:ds0, Preparing: SELECT t.`id`,t.`uid`,t.`order_no` FROM `order_04` t ORDER BY t.`order_no` ASC LIMIT 10
==> SHARDING_EXECUTOR_2, name:ds0, Preparing: SELECT t.`id`,t.`uid`,t.`order_no` FROM `order_03` t ORDER BY t.`order_no` ASC LIMIT 10
==> SHARDING_EXECUTOR_4, name:ds0, Preparing: SELECT t.`id`,t.`uid`,t.`order_no` FROM `order_00` t ORDER BY t.`order_no` ASC LIMIT 10
==> SHARDING_EXECUTOR_1, name:ds0, Preparing: SELECT t.`id`,t.`uid`,t.`order_no` FROM `order_01` t ORDER BY t.`order_no` ASC LIMIT 10
==> SHARDING_EXECUTOR_3, name:ds0, Preparing: SELECT t.`id`,t.`uid`,t.`order_no` FROM `order_02` t ORDER BY t.`order_no` ASC LIMIT 10
<== Total: 10

這邊可以看到一行代碼實現(xiàn)分頁,下面是第二頁

http://localhost:8080/order/page?pageIndex=2&pageSize=10
{"total":100,"data":[{"id":"10","uid":"xiaohong","orderNo":10},{"id":"11","uid":"xiaolan","orderNo":11},{"id":"12","uid":"xiaoming","orderNo":12},{"id":"13","uid":"xiaohong","orderNo":13},{"id":"14","uid":"xiaolan","orderNo":14},{"id":"15","uid":"xiaoming","orderNo":15},{"id":"16","uid":"xiaohong","orderNo":16},{"id":"17","uid":"xiaolan","orderNo":17},{"id":"18","uid":"xiaoming","orderNo":18},{"id":"19","uid":"xiaohong","orderNo":19}]}

==> SHARDING_EXECUTOR_9, name:ds0, Preparing: SELECT COUNT(1) FROM `order_02` t
==> SHARDING_EXECUTOR_8, name:ds0, Preparing: SELECT COUNT(1) FROM `order_01` t
==> SHARDING_EXECUTOR_10, name:ds0, Preparing: SELECT COUNT(1) FROM `order_04` t
==> SHARDING_EXECUTOR_7, name:ds0, Preparing: SELECT COUNT(1) FROM `order_03` t
==> SHARDING_EXECUTOR_6, name:ds0, Preparing: SELECT COUNT(1) FROM `order_00` t
<== Total: 1
==> SHARDING_EXECUTOR_9, name:ds0, Preparing: SELECT t.`id`,t.`uid`,t.`order_no` FROM `order_01` t ORDER BY t.`order_no` ASC LIMIT 20
==> SHARDING_EXECUTOR_8, name:ds0, Preparing: SELECT t.`id`,t.`uid`,t.`order_no` FROM `order_03` t ORDER BY t.`order_no` ASC LIMIT 20
==> SHARDING_EXECUTOR_10, name:ds0, Preparing: SELECT t.`id`,t.`uid`,t.`order_no` FROM `order_04` t ORDER BY t.`order_no` ASC LIMIT 20
==> SHARDING_EXECUTOR_6, name:ds0, Preparing: SELECT t.`id`,t.`uid`,t.`order_no` FROM `order_02` t ORDER BY t.`order_no` ASC LIMIT 20
==> SHARDING_EXECUTOR_7, name:ds0, Preparing: SELECT t.`id`,t.`uid`,t.`order_no` FROM `order_00` t ORDER BY t.`order_no` ASC LIMIT 20
<== Total: 10

按時間分表

這邊我們簡單還是以order訂單為例,按月進(jìn)行分片假設(shè)我們從2022年1月到2023年5月一共17個月表名為t_order_202201、t_order_202202t_order_202203...t_order_202304、t_order_202305

數(shù)據(jù)庫腳本

create table t_order_202201
(
    id varchar(32) not null comment '主鍵ID'primary key,
    uid varchar(50) not null comment '用戶id',
    order_no int not null comment '訂單號',
    create_time datetime not null comment '創(chuàng)建時間'
)comment '訂單表';
create table t_order_202202
(
    id varchar(32) not null comment '主鍵ID'primary key,
    uid varchar(50) not null comment '用戶id',
    order_no int not null comment '訂單號',
    create_time datetime not null comment '創(chuàng)建時間'
)comment '訂單表';
....
create table t_order_202304
(
    id varchar(32) not null comment '主鍵ID'primary key,
    uid varchar(50) not null comment '用戶id',
    order_no int not null comment '訂單號',
    create_time datetime not null comment '創(chuàng)建時間'
)comment '訂單表';
create table t_order_202305
(
    id varchar(32) not null comment '主鍵ID'primary key,
    uid varchar(50) not null comment '用戶id',
    order_no int not null comment '訂單號',
    create_time datetime not null comment '創(chuàng)建時間'
)comment '訂單表';

@Data
@Table(value = "t_order",shardingInitializer = OrderByMonthShardingInitializer.class)
public class OrderByMonthEntity {

    @Column(primaryKey = true)
    private String id;
    private String uid;
    private Integer orderNo;
    /**
     * 分片鍵改為時間
     */
    @ShardingTableKey
    private LocalDateTime createTime;
}

//路由規(guī)則可以直接繼承AbstractShardingMonthInitializer也可以自己實現(xiàn)
@Component
public class OrderByMonthShardingInitializer extends AbstractShardingMonthInitializer<OrderByMonthEntity> {
   /**
     * 開始時間不可以使用LocalDateTime.now()因為會導(dǎo)致每次啟動開始時間都不一樣
     * @return
     */
    @Override
    protected LocalDateTime getBeginTime() {
        return LocalDateTime.of(2022,1,1,0,0);
    }

    /**
     * 如果不設(shè)置那么就是當(dāng)前時間,用于程序啟動后自動計算應(yīng)該有的表包括最后時間
     * @return
     */
    @Override
    protected LocalDateTime getEndTime() {
        return LocalDateTime.of(2023,5,31,0,0);
    }

    @Override
    public void configure0(ShardingEntityBuilder<OrderByMonthEntity> builder) {
        //后續(xù)用來實現(xiàn)優(yōu)化分表
    }
}
//按月分片路由規(guī)則也可以自己實現(xiàn)因為框架已經(jīng)封裝好了所以可以用框架自帶的
@Component
public class OrderByMonthTableRouteRule extends AbstractMonthTableRule<OrderByMonthEntity> {
    @Override
    protected LocalDateTime convertLocalDateTime(Object shardingValue) {
        return (LocalDateTime)shardingValue;
    }
}

初始化


@RestController
@RequestMapping("/orderMonth")
@RequiredArgsConstructor(onConstructor_ = @Autowired)
public class OrderMonthController {

    private final EasyQuery easyQuery;

    @GetMapping("/init")
    public Object init() {
        ArrayList<OrderByMonthEntity> orderEntities = new ArrayList<>(100);
        List<String> users = Arrays.asList("xiaoming", "xiaohong", "xiaolan");
        LocalDateTime beginTime=LocalDateTime.of(2022,1,1,0,0);
        LocalDateTime endTime=LocalDateTime.of(2023,5,31,0,0);
        int i=0;
        while(!beginTime.isAfter(endTime)){

            OrderByMonthEntity orderEntity = new OrderByMonthEntity();
            orderEntity.setId(String.valueOf(i));
            int i1 = i % 3;
            String uid = users.get(i1);
            orderEntity.setUid(uid);
            orderEntity.setOrderNo(i);
            orderEntity.setCreateTime(beginTime);
            orderEntities.add(orderEntity);
            beginTime=beginTime.plusDays(1);
            i++;
        }
        long l = easyQuery.insertable(orderEntities).executeRows();
        return "成功插入:"+l;
    }
}

http://localhost:8080/orderMonth/init
成功插入:516

獲取第一條數(shù)據(jù)

    @GetMapping("/first")
    public Object first(@RequestParam("id") String id) {
        OrderEntity orderEntity = easyQuery.queryable(OrderEntity.class)
                .whereById(id).firstOrNull();
        return orderEntity;
    }

http://localhost:8080/orderMonth/first?id=11
{"id":"11","uid":"xiaolan","orderNo":11,"createTime":"2022-01-12T00:00:00"}
//以每5組一個次并發(fā)執(zhí)行聚合

==> SHARDING_EXECUTOR_1, name:ds0, Preparing: SELECT t.`id`,t.`uid`,t.`order_no`,t.`create_time` FROM `t_order_202205` t WHERE t.`id` = ? LIMIT 1
==> SHARDING_EXECUTOR_1, name:ds0, Parameters: 11(String)
==> SHARDING_EXECUTOR_2, name:ds0, Preparing: SELECT t.`id`,t.`uid`,t.`order_no`,t.`create_time` FROM `t_order_202207` t WHERE t.`id` = ? LIMIT 1
==> SHARDING_EXECUTOR_2, name:ds0, Parameters: 11(String)
==> SHARDING_EXECUTOR_3, name:ds0, Preparing: SELECT t.`id`,t.`uid`,t.`order_no`,t.`create_time` FROM `t_order_202303` t WHERE t.`id` = ? LIMIT 1
==> SHARDING_EXECUTOR_3, name:ds0, Parameters: 11(String)
==> SHARDING_EXECUTOR_4, name:ds0, Preparing: SELECT t.`id`,t.`uid`,t.`order_no`,t.`create_time` FROM `t_order_202212` t WHERE t.`id` = ? LIMIT 1
==> SHARDING_EXECUTOR_4, name:ds0, Parameters: 11(String)
==> SHARDING_EXECUTOR_5, name:ds0, Preparing: SELECT t.`id`,t.`uid`,t.`order_no`,t.`create_time` FROM `t_order_202302` t WHERE t.`id` = ? LIMIT 1
==> SHARDING_EXECUTOR_5, name:ds0, Parameters: 11(String)
==> SHARDING_EXECUTOR_1, name:ds0, Preparing: SELECT t.`id`,t.`uid`,t.`order_no`,t.`create_time` FROM `t_order_202304` t WHERE t.`id` = ? LIMIT 1
==> SHARDING_EXECUTOR_5, name:ds0, Preparing: SELECT t.`id`,t.`uid`,t.`order_no`,t.`create_time` FROM `t_order_202206` t WHERE t.`id` = ? LIMIT 1
==> SHARDING_EXECUTOR_2, name:ds0, Preparing: SELECT t.`id`,t.`uid`,t.`order_no`,t.`create_time` FROM `t_order_202305` t WHERE t.`id` = ? LIMIT 1
==> SHARDING_EXECUTOR_1, name:ds0, Parameters: 11(String)
==> SHARDING_EXECUTOR_2, name:ds0, Parameters: 11(String)
==> SHARDING_EXECUTOR_4, name:ds0, Preparing: SELECT t.`id`,t.`uid`,t.`order_no`,t.`create_time` FROM `t_order_202209` t WHERE t.`id` = ? LIMIT 1
==> SHARDING_EXECUTOR_3, name:ds0, Preparing: SELECT t.`id`,t.`uid`,t.`order_no`,t.`create_time` FROM `t_order_202204` t WHERE t.`id` = ? LIMIT 1
==> SHARDING_EXECUTOR_5, name:ds0, Parameters: 11(String)
==> SHARDING_EXECUTOR_3, name:ds0, Parameters: 11(String)
==> SHARDING_EXECUTOR_4, name:ds0, Parameters: 11(String)
==> SHARDING_EXECUTOR_2, name:ds0, Preparing: SELECT t.`id`,t.`uid`,t.`order_no`,t.`create_time` FROM `t_order_202208` t WHERE t.`id` = ? LIMIT 1
==> SHARDING_EXECUTOR_5, name:ds0, Preparing: SELECT t.`id`,t.`uid`,t.`order_no`,t.`create_time` FROM `t_order_202201` t WHERE t.`id` = ? LIMIT 1
==> SHARDING_EXECUTOR_3, name:ds0, Preparing: SELECT t.`id`,t.`uid`,t.`order_no`,t.`create_time` FROM `t_order_202210` t WHERE t.`id` = ? LIMIT 1
==> SHARDING_EXECUTOR_5, name:ds0, Parameters: 11(String)
==> SHARDING_EXECUTOR_4, name:ds0, Preparing: SELECT t.`id`,t.`uid`,t.`order_no`,t.`create_time` FROM `t_order_202202` t WHERE t.`id` = ? LIMIT 1
==> SHARDING_EXECUTOR_3, name:ds0, Parameters: 11(String)
==> SHARDING_EXECUTOR_2, name:ds0, Parameters: 11(String)
==> SHARDING_EXECUTOR_4, name:ds0, Parameters: 11(String)
==> SHARDING_EXECUTOR_1, name:ds0, Preparing: SELECT t.`id`,t.`uid`,t.`order_no`,t.`create_time` FROM `t_order_202211` t WHERE t.`id` = ? LIMIT 1
==> SHARDING_EXECUTOR_1, name:ds0, Parameters: 11(String)
==> SHARDING_EXECUTOR_2, name:ds0, Preparing: SELECT t.`id`,t.`uid`,t.`order_no`,t.`create_time` FROM `t_order_202203` t WHERE t.`id` = ? LIMIT 1
==> SHARDING_EXECUTOR_5, name:ds0, Preparing: SELECT t.`id`,t.`uid`,t.`order_no`,t.`create_time` FROM `t_order_202301` t WHERE t.`id` = ? LIMIT 1
==> SHARDING_EXECUTOR_2, name:ds0, Parameters: 11(String)
==> SHARDING_EXECUTOR_5, name:ds0, Parameters: 11(String)
<== Total: 1

獲取范圍內(nèi)的數(shù)據(jù)

    @GetMapping("/range")
    public Object first() {
        List<OrderByMonthEntity> list = easyQuery.queryable(OrderByMonthEntity.class)
                .where(o -> o.rangeClosed(OrderByMonthEntity::getCreateTime, LocalDateTime.of(2022, 3, 1, 0, 0), LocalDateTime.of(2022, 9, 1, 0, 0)))
                .toList();
        return list;
    }
http://localhost:8080/orderMonth/range
[{"id":"181","uid":"xiaohong","orderNo":181,"createTime":"2022-07-01T00:00:00"},{"id":"182","uid":"xiaolan","orderNo":182,"createTime":"2022-07-02T00:00:00"},{"id":"183","uid":"xiaoming","orderNo":183,"createTime":"2022-07-03T00:00:00"},...........,{"id":"239","uid":"xiaolan","orderNo":239,"createTime":"2022-08-28T00:00:00"},{"id":"240","uid":"xiaoming","orderNo":240,"createTime":"2022-08-29T00:00:00"},{"id":"241","uid":"xiaohong","orderNo":241,"createTime":"2022-08-30T00:00:00"},{"id":"242","uid":"xiaolan","orderNo":242,"createTime":"2022-08-31T00:00:00"}]

//可以精準(zhǔn)定位到對應(yīng)的分片路由上獲取數(shù)據(jù)
==> SHARDING_EXECUTOR_1, name:ds0, Preparing: SELECT t.`id`,t.`uid`,t.`order_no`,t.`create_time` FROM `t_order_202207` t WHERE t.`create_time` >= ? AND t.`create_time` <= ?
==> SHARDING_EXECUTOR_5, name:ds0, Preparing: SELECT t.`id`,t.`uid`,t.`order_no`,t.`create_time` FROM `t_order_202209` t WHERE t.`create_time` >= ? AND t.`create_time` <= ?
==> SHARDING_EXECUTOR_2, name:ds0, Preparing: SELECT t.`id`,t.`uid`,t.`order_no`,t.`create_time` FROM `t_order_202206` t WHERE t.`create_time` >= ? AND t.`create_time` <= ?
==> SHARDING_EXECUTOR_4, name:ds0, Preparing: SELECT t.`id`,t.`uid`,t.`order_no`,t.`create_time` FROM `t_order_202203` t WHERE t.`create_time` >= ? AND t.`create_time` <= ?
==> SHARDING_EXECUTOR_3, name:ds0, Preparing: SELECT t.`id`,t.`uid`,t.`order_no`,t.`create_time` FROM `t_order_202205` t WHERE t.`create_time` >= ? AND t.`create_time` <= ?
==> SHARDING_EXECUTOR_4, name:ds0, Parameters: 2022-03-01T00:00(LocalDateTime),2022-09-01T00:00(LocalDateTime)
==> SHARDING_EXECUTOR_3, name:ds0, Parameters: 2022-03-01T00:00(LocalDateTime),2022-09-01T00:00(LocalDateTime)
==> SHARDING_EXECUTOR_2, name:ds0, Parameters: 2022-03-01T00:00(LocalDateTime),2022-09-01T00:00(LocalDateTime)
==> SHARDING_EXECUTOR_5, name:ds0, Parameters: 2022-03-01T00:00(LocalDateTime),2022-09-01T00:00(LocalDateTime)
==> SHARDING_EXECUTOR_1, name:ds0, Parameters: 2022-03-01T00:00(LocalDateTime),2022-09-01T00:00(LocalDateTime)
==> SHARDING_EXECUTOR_4, name:ds0, Preparing: SELECT t.`id`,t.`uid`,t.`order_no`,t.`create_time` FROM `t_order_202208` t WHERE t.`create_time` >= ? AND t.`create_time` <= ?
==> SHARDING_EXECUTOR_2, name:ds0, Preparing: SELECT t.`id`,t.`uid`,t.`order_no`,t.`create_time` FROM `t_order_202204` t WHERE t.`create_time` >= ? AND t.`create_time` <= ?
==> SHARDING_EXECUTOR_4, name:ds0, Parameters: 2022-03-01T00:00(LocalDateTime),2022-09-01T00:00(LocalDateTime)
==> SHARDING_EXECUTOR_2, name:ds0, Parameters: 2022-03-01T00:00(LocalDateTime),2022-09-01T00:00(LocalDateTime)
<== Total: 185

最后

目前為止你已經(jīng)看到了easy-query對于分片的便捷性,但是本章只是開胃小菜,相信了解分庫分表的小伙伴肯定會說就這?不是和sharding-jdbc一樣嗎為什么要用你的呢。我想說第一篇只是給大家了解一下如何使用,后續(xù)的文章才是分表分庫的精髓相信我你一定沒看過

demo地址 https://github.com/xuejmnet/easy-sharding-test

  • GITHUB github地址

  • GITEE gitee地址

到了這里,關(guān)于javaer你還在手寫分表分庫?來看看這個框架怎么做的 干貨滿滿的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • ??????C#系列-C#EF框架實現(xiàn)分庫分表(21)

    在 C# 中使用 Entity Framework (EF) 框架實現(xiàn)分庫分表(也稱為數(shù)據(jù)庫分片或水平切分)是一個相對復(fù)雜的過程,因為 EF 本身并不直接支持分庫分表。分庫分表通常是為了解決單一數(shù)據(jù)庫的性能瓶頸、數(shù)據(jù)量過大、高并發(fā)等問題而采取的一種策略。 實現(xiàn)分庫分表通常涉及以下幾個

    2024年02月20日
    瀏覽(20)
  • Java中支持分庫分表的框架/組件/中間件簡介

    Java中支持分庫分表的框架/組件/中間件簡介

    列舉一些比較常見的,簡單介紹一下: sharding-jdbc(當(dāng)當(dāng)) TSharding(蘑菇街) Atlas(奇虎360) Cobar(阿里巴巴) MyCAT(基于Cobar) TDDL(淘寶) Vitess(谷歌) 首先,第一個,可能也是最常見最常用的,Sharding-JDBC,這個是最早的名字,現(xiàn)在已經(jīng)發(fā)展成為ShardingSphere,生態(tài),詳細(xì)

    2024年02月10日
    瀏覽(28)
  • 什么是分庫分表?為什么需要分表?什么時候分庫分表

    什么是分庫分表?為什么需要分表?什么時候分庫分表

    不急于上手實戰(zhàn)? ShardingSphere ?框架,先來復(fù)習(xí)下分庫分表的基礎(chǔ)概念,技術(shù)名詞大多晦澀難懂,不要死記硬背理解最重要,當(dāng)你捅破那層窗戶紙,發(fā)現(xiàn)其實它也就那么回事。 分庫分表是在海量數(shù)據(jù)下,由于單庫、表數(shù)據(jù)量過大,導(dǎo)致數(shù)據(jù)庫性能持續(xù)下降的問題,演變出的技

    2023年04月26日
    瀏覽(53)
  • 分庫分表介紹以及shardingjdbc實現(xiàn)分庫分表

    分庫分表介紹以及shardingjdbc實現(xiàn)分庫分表

    分庫分表概念 一、什么是分庫分表 分庫分表是在海量數(shù)據(jù)下,由于單庫、表數(shù)據(jù)量過大,導(dǎo)致數(shù)據(jù)庫性能持續(xù)下降的問題,演變出的技術(shù)方案。 分庫分表是由分庫和分表這兩個獨立概念組成的,只不過通常分庫與分表的操作會同時進(jìn)行,以至于我們習(xí)慣性的將它們合在一起

    2023年04月13日
    瀏覽(34)
  • 【分庫分表】基于mysql+shardingSphere的分庫分表技術(shù)

    【分庫分表】基于mysql+shardingSphere的分庫分表技術(shù)

    目錄 1.什么是分庫分表 2.分片方法 3.測試數(shù)據(jù) 4.shardingSphere 4.1.介紹 4.2.sharding jdbc 4.3.sharding proxy 4.4.兩者之間的對比 5.留個尾巴 分庫分表是一種場景解決方案,它的出現(xiàn)是為了解決一些場景問題的,哪些場景喃? 單表過大的話,讀請求進(jìn)來,查數(shù)據(jù)需要的時間會過長 讀請求過

    2024年03月12日
    瀏覽(47)
  • 分表?分庫?分庫分表?實踐詳談 ShardingSphere-JDBC

    分表?分庫?分庫分表?實踐詳談 ShardingSphere-JDBC

    如果有不是很了解ShardingSphere的可以先看一下這個文章: 《ShardingSphere JDBC?Sharding JDBC?》基本小白脫坑問題 ? ? ? ? 在很多開發(fā)場景下面,很多的技術(shù)難題都是出自于,大數(shù)據(jù)量級或者并發(fā)的場景下面的。這里就出現(xiàn)了我們要解決的。本文章重點討論一下在java的spirng開發(fā)場

    2024年04月12日
    瀏覽(23)
  • HVV就緒!你還在圍觀考慮嗎?

    “護(hù)網(wǎng)去了坐著就行,一天給1000” “護(hù)網(wǎng)有免費美味的盒飯!” “不僅一天有1000,還包住!” “連路費都可以報銷” 你有沒有在從事網(wǎng)絡(luò)安全行業(yè)的人口中聽到這些內(nèi)容?怎么樣?是不是很誘人?是不是覺得還有這種天上掉餡餅的好事?自己也蠢蠢欲動了? 冷靜!在沖動

    2024年02月15日
    瀏覽(18)
  • 掌握MySQL分庫分表(一)數(shù)據(jù)庫性能優(yōu)化思路、分庫分表優(yōu)缺點

    不能?上來就說分庫分表! 根據(jù)實際情況分析,兩個角度思考:不分庫分表、分庫分表 軟優(yōu)化 數(shù)據(jù)庫參數(shù)調(diào)優(yōu) 分析慢查詢SQL語句,分析執(zhí)行計劃,進(jìn)行sql改寫和程序改寫 優(yōu)化數(shù)據(jù)庫索引結(jié)構(gòu) 優(yōu)化數(shù)據(jù)表結(jié)構(gòu)優(yōu)化 引入NOSQL和程序架構(gòu)調(diào)整 硬優(yōu)化 提升系統(tǒng)硬件(更快的IO、更

    2023年04月19日
    瀏覽(37)
  • 你還在為SFTP連接超時而困惑么?

    在最近的項目聯(lián)調(diào)過程中,發(fā)現(xiàn)在連接上游側(cè)SFTP時總是需要 等待 大約 10s+ 的時間才會出現(xiàn)密碼輸入界面,這種長時間的等待 直接導(dǎo)致 的 調(diào)用文件接口時 連接sftp 超時 問題。于是決定自己針對該問題進(jìn)行一下排查,查詢了相關(guān)資料,并逐個試驗了一下網(wǎng)上提供的解決方案,

    2024年02月05日
    瀏覽(19)
  • 都2023了,你還在這樣發(fā)朋友圈嗎?

    都2023了,你還在這樣發(fā)朋友圈嗎?

    都2023年了,你還在照著時間表發(fā)朋友圈? 又不是每天打卡上班,還要規(guī)定你什么時候發(fā)什么內(nèi)容。 如果我們都這樣發(fā),那客戶看到的都是一模一樣的內(nèi)容,就像流水線上的工人..... 可以試試定時發(fā)圈,提前編輯好朋友圈內(nèi)容,選擇好日期和時間點,到點就會自動發(fā)出。 更絕

    2024年02月08日
    瀏覽(17)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包