高mammalian国观轿子:科艾麻该户、MQ、内存。今天给他们增添的是科艾麻该户的蔬果软件系统,即便你不用我的架构也能由此听到不那样的故事情节计划和同时实现。
这款支持手动该户科艾麻的orm架构easy-query 帮助您解脱跨库增添的复杂销售业务标识符,因此提供多种故事情节计划和自订路由器来同时实现比合作开发工具更高效能的资料库出访。
上首诗单纯的带他们介绍了架构如何采用新溪洲结语将会以理论为主加课堂教学的方式呈现不那样的该户科艾麻。
介绍
科艾麻该户一直是可有可无的难题,市售也有很多人感慨万千,但绝大部分的说词都是那样,甚至给不下两个前述的软件系统,生前经过十多年的耕耘在其他语言里面十多年的保护和课堂教学下来更为适宜happy coding的原则希望更多的人能介绍和认识到该架构因此给他们两个崭新的特别针对科艾麻该户的认识。
他们也经常讥讽项目一开始就用了科艾麻该户结果上架没多少数据,因此整座合作开发新体验来说十分繁杂,对于销售业务而言也是极为不亲善,大幅变长合作开发阶段不说,bug也是更加容易产生,特别针对上述难题该架构得出了两个十分轻松的同时实现来极大程度上的给使用者轻松的新体验新溪洲储存填入预览删掉新溪洲查阅单新溪洲表查阅跨新溪洲表查阅跨新溪洲次序跨新溪洲各组跨新溪洲巨集新溪洲储存
科艾麻该户单纯的同时实现目前绝大部分架构已经都能同时实现了,是静态表名来同时实现该户下的单纯储存,假如是科艾麻下面的那么就采用静态管理工具来转换同时实现,假如是科艾麻加该户就用静态管理工具加静态表名来同时实现,听上去是不是很轻松,但前述情况下你需要表写十分多样的销售业务标识符,因此会让整座合作开发心力全部集中在科艾麻该户下,特别针对后期的保护也是十分麻烦事的两件事。
但科艾麻该户的新溪洲准则又是和具体销售业务谐振的所以合理的解耦新溪洲路由器是两件十分重要的事情。插入
假定他们按订货id进行该户储存
通过上述图片他们能很清晰的介绍到新溪洲填入的执行基本原理,通过拦截执行sql分析对应的值计算出所属表名,然后改写表名进行填入。该同时实现方法有两个弊端是假如填入数据是increment的自增类型,那么这种方法将不适合,因为自增主键只有在填入资料库后才会正真的被确定是什么值,能通过拦截器设置自订自增拨号器来同时实现伪自增,这样也能同时实现“自增”列。
预览删掉)
这边假定他们也是按照订货id进行该户预览
预览新溪洲键
一模那样的处理,将sql进行拦截后导出where和新溪洲字段id然后计算后将结果发送到对应路由器的表中进行执行。
那么假如他们没办法进行路由器确定呢,假如他们采用created字段来预览的那么会发生生呢
预览非新溪洲键
为了得到正确的结果需要将每条sql进行改写分别发送到对应的表中,然后将各自表的执行结果进行聚合返回最终受影响行数
新溪洲查阅
众所周知科艾麻该户的难点并不在如何储存数据到对应的db,也不在于如何预览指定实体数据,因为他们都能通过新溪洲键的计算来重新路由器,能让新溪洲的操作降为单表操作,所以orm只需要支持静态表名那么以上所有功能都是支持的,
但前述情况缺是假如orm或者合作开发工具只支持到了这个级别那么对于稍微复杂一点的销售业务你必须要编写大量的销售业务标识符来同时实现销售业务需要的查阅,因此会浪费大量的重复工作和心力单新溪洲表查阅
加下来我来讲解单新溪洲表查阅,其实基本原理和上面的insert一样
到这里为止其实都是ok的并没有什么难题.但假如他们的本次查阅需要跨新溪洲呢比如跨两个新溪洲那么应该如何处理
跨新溪洲表查阅
果呢
通过上图他们能介绍到在跨新溪洲的聚合下他们能该户通过对a,b两张表进行查阅能并行能串行,最终将结果汇聚到同两个集合那么返回给使用者端是两个完整的数据包,并没有缺少任何数据
跨新溪洲次序
基于上述分他节点新溪洲影响。
那么假如他们对数据进行新溪洲聚合+次序那么又会是什么样的场景呢计划一内存次序
首先他们将执行sql分别路由器到t_order_1和t_order_2两张表,因此执行order by id desc将其数据id大的排在前面这样能保证单个Connection的ResultSet肯定是大的先被返回
所以在单个Connection下结果是正确的但因为多个新溪洲节点间没有交互所以当取到内存中后数据计划二流式次序
绝大部分orm到这边就为止了,毕竟已经同时实现了轻松的节点处理,但他们来看他需要消耗的性能事多少,假定他们新溪洲命中2个节点,每个节点各自返回2条数据,他们对于整座ResultSet的遍历将是每个链接都是2那么是4次,然后在内存中在进行次序假如性能差一点还需要多次所以这个是相对比较浪费性能的,因为假如他们有1000条数据返回那么内存中的次序是很高效的但这个也是他们这次需要讲解的更加高效的次序处理流式次序
相较于内存次序这种方式十分复杂因此繁杂,而且对于使用者也很不
无order字段
到这边不要以为跨新溪洲聚合已经结束了因为当你的sql查阅order b以保证他们数据的正确返回
以下两个难题因为涉及到过多内容结语节无法呈现所以将会在下一章得出具体软件系统
跨新溪洲各组
假如他们程序遇到了这个那么他们该如何处理呢
跨新溪洲巨集
销售业务中常常需要的跨新溪洲巨集他们该如何解决,easy-query又如何处理这种情况,假如跨的新溪洲过多他们又该怎么办,
如何解决深巨集难题如何解决流式瀑布难题接下来将在下首诗中一一解答近
最后
我这边将演示easy-query在本次新溪洲理论中的前述应用
这次采用h2资料库作为演示 CREATE TABLE IF NOT EXISTS `t_order_0` ( `id` INTEGER PRIMARY KEY, `status` Integer, `created` VARCHAR(100) ); CREATE TABLE IF NOT EXISTS `t_order_1` ( `id` INTEGER PRIMARY KEY, `status` Integer, `created` VARCHAR(100) ); CREATE TABLE IF NOT EXISTS `t_order_2` ( `id` INTEGER PRIMARY KEY, `status` Integer, `created` VARCHAR(100) ); CREATE TABLE IF NOT EXISTS `t_order_3` ( `id` INTEGER PRIMARY KEY, `status` Integer, `created` VARCHAR(100) ); CREATE TABLE IF NOT EXISTS `t_order_4` ( `id` INTEGER PRIMARY KEY, `status` Integer, `created` VARCHAR(100) );安装maven依赖
<dependency> <groupId>com.easy-query</groupId> <artifactId>sql-h2</artifactId> <version>0.9.32</version> <scope>compile</scope> </dependency> <dependency> <groupId>com.easy-query</groupId> <artifactId>sql-api4j</artifactId> <version>0.9.32</version> <scope>compile</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.24</version> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <version>1.4.199</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>${spring.version}</version> </dependency>创建实体对象对应资料库
@Data @Table(value = “t_order”,shardingInitializer = H2OrderShardingInitializer.class) public class H2Order { @Column(primaryKey = true) @ShardingTableKey private Integer id; private Integer status; privateString created; }// 新溪洲初始化器 public class H2OrderShardingInitializer extends AbstractShardingTableModInitializer<H2Order> { @Override protected int mod() { return 5;//模5 } @Override protected int tailLength() { return 1;//表后缀长度1位 } } //新溪洲路由器准则 public class H2OrderRule extends AbstractModTableRule<H2Order> { @Override protected int mod() { return 5; } @Override protected int tailLength() { return 1; } }创建datasource和easyquery
orderShardingDataSource=DataSourceFactory.getDataSource(“dsorder”,“h2-dsorder.sql”); EasyQueryClient easyQueryClientOrder = EasyQueryBootstrapper.defaultBuilderConfiguration() .setDefaultDataSource(orderShardingDataSource) .optionConfigure(op -> { op.setMaxShardingQueryLimit(10); op.setDefaultDataSourceName(“ds2020”); op.setDefaultDataSourceMergePoolSize(20); }) .build(); EasyQuery easyQueryOrder =newDefaultEasyQuery(easyQueryClientOrder); QueryRuntimeContext runtimeContext = easyQueryOrder.getRuntimeContext(); QueryConfiguration queryConfiguration = runtimeContext.getQueryConfiguration(); queryConfiguration.applyShardingInitializer(newH2OrderShardingInitializer());//添加新溪洲初始化器TableRouteManager tableRouteManager = runtimeContext.getTableRouteManager(); tableRouteManager.addRouteRule(new H2OrderRule());//添加新溪洲路由器准则填入标识符
ArrayList<H2Order> h2Orders = new ArrayList<>(); for (int i = 0; i < 100; i++) { H2Order h2Order = newH2Order(); h2Order.setId(i); h2Order.setStatus(i%3); h2Order.setCreated(String.valueOf(i)); h2Orders.add(h2Order); } easyQueryOrder.insertable(h2Orders).executeRows();==> main, name:ds2020, Preparing: INSERT INTO t_order_3 (id,status,created) VALUES (?,?,?) ==> main, name:ds2020, Parameters: 0(Integer),0(Integer),0(String) <== main, name:ds2020, Total: 1 ==> main, name:ds2020, Preparing: INSERT INTO t_order_4 (id,status,created) VALUES (?,?,?) ==> main, name:ds2020, Parameters: 1(Integer),1(Integer),1(String) <== main, name:ds2020, Total: 1 ==> main, name:ds2020, Preparing: INSERT INTO t_order_0 (id,status,created) VALUES (?,?,?) ==> main, name:ds2020, Parameters: 2(Integer),2(Integer),2(String) <== main, name:ds2020, Total: 1 ==> main, name:ds2020, Preparing: INSERT INTO t_order_1 (id,status,created) VALUES (?,?,?) ==> main, name:ds2020, Parameters: 3(Integer),0(Integer),3(String) <== main, name:ds2020, Total: 1 ==> main, name:ds2020, Preparing: INSERT INTO t_order_2 (id,status,created) VALUES (?,?,?) ==> main, name:ds2020, Parameters: 4(Integer),1(Integer),4(String) …..省略List<H2Order> list = easyQueryOrder.queryable(H2Order.class) .where(o -> o.in(H2Order::getId, Arrays.asList(1, 2,6, 7))) .toList(); Assert.assertEquals(4,list.size()); ==> SHARDING_EXECUTOR_2, name:ds2020, Preparing: SELECT id,status,created FROM t_order_3 WHERE id IN (?,?,?,?) ==> SHARDING_EXECUTOR_4, name:ds2020, Preparing: SELECT id,status,created FROM t_order_0 WHERE id IN (?,?,?,?) ==> SHARDING_EXECUTOR_3, name:ds2020, Preparing: SELECT id,status,created FROM t_order_4 WHERE id IN (?,?,?,?) ==> SHARDING_EXECUTOR_1, name:ds2020, Preparing: SELECT id,status,created FROM t_order_2 WHERE id IN (?,?,?,?) ==> SHARDING_EXECUTOR_4, name:ds2020, Parameters: 1(Integer),2(Integer),6(Integer),7(Integer) ==> SHARDING_EXECUTOR_5, name:ds2020, Preparing: SELECT id,status,created FROM t_order_1 WHERE id IN (?,?,?,?) ==> SHARDING_EXECUTOR_3, name:ds2020, Parameters: 1(Integer),2(Integer),6(Integer),7(Integer) ==> SHARDING_EXECUTOR_5, name:ds2020, Parameters: 1(Integer),2(Integer),6(Integer),7(Integer) ==> SHARDING_EXECUTOR_1, name:ds2020, Parameters: 1(Integer),2(Integer),6(Integer),7(Integer) ==> SHARDING_EXECUTOR_2, name:ds2020, Parameters: 1(Integer),2(Integer),6(Integer),7(Integer) <== SHARDING_EXECUTOR_2, name:ds2020, Time Elapsed: 0(ms) <== SHARDING_EXECUTOR_5, name:ds2020, Time Elapsed: 0(ms) <== SHARDING_EXECUTOR_1, name:ds2020, Time Elapsed: 1(ms) <== SHARDING_EXECUTOR_4, name:ds2020, Time Elapsed: 1(ms) <== SHARDING_EXECUTOR_3, name:ds2020, Time Elapsed: 1(ms) <== Total: 4 “ 通过上述sql展示他们能清晰的看到哪个线程执行了哪个管理工具(新溪洲下会不那样),执行了什么sql,最终执行消耗多少时间参数是多少,一共返回多少条数据 新溪洲次序 “`java List<H2Order> list = easyQueryOrder.queryable(H2Order.class) .where(o -> o.in(H2Order::getId, Arrays.asList(1, 2, 6, 7))) .orderByDesc(o->o.column(H2Order::getId)) .toList(); Assert.assertEquals(4,list.size()); Assert.assertEquals(7,(int)list.get(0).getId()); Assert.assertEquals(6,(int)list.get(1).getId()); Assert.assertEquals(2,(int)list.get(2).getId()); Assert.assertEquals(1,(int)list.get(3).getId()); ==> SHARDING_EXECUTOR_1, name:ds2020, Preparing: SELECT id,status,created FROM t_order_1 WHERE id IN (?,?,?,?) ORDER BY id DESC ==> SHARDING_EXECUTOR_5, name:ds2020, Preparing: SELECT id,status,created FROM t_order_3 WHERE id IN (?,?,?,?) ORDER BY id DESC ==> SHARDING_EXECUTOR_4, name:ds2020, Preparing: SELECT id,status,created FROM t_order_2 WHERE id IN (?,?,?,?) ORDER BY id DESC ==> SHARDING_EXECUTOR_3, name:ds2020, Preparing: SELECT id,status,created FROM t_order_4 WHERE id IN (?,?,?,?) ORDER BY id DESC ==> SHARDING_EXECUTOR_5, name:ds2020, Parameters: 1(Integer),2(Integer),6(Integer),7(Integer) ==> SHARDING_EXECUTOR_1, name:ds2020, Parameters: 1(Integer),2(Integer),6(Integer),7(Integer) ==> SHARDING_EXECUTOR_4, name:ds2020, Parameters: 1(Integer),2(Integer),6(Integer),7(Integer) ==> SHARDING_EXECUTOR_2, name:ds2020, Preparing: SELECT id,status,created FROM t_order_0 WHERE id IN (?,?,?,?) ORDER BY id DESC ==> SHARDING_EXECUTOR_3, name:ds2020, Parameters: 1(Integer),2(Integer),6(Integer),7(Integer) ==> SHARDING_EXECUTOR_2, name:ds2020, Parameters: 1(Integer),2(Integer),6(Integer),7(Integer) <== SHARDING_EXECUTOR_1, name:ds2020, Time Elapsed: 0(ms) <== SHARDING_EXECUTOR_5, name:ds2020, Time Elapsed: 0(ms) <== SHARDING_EXECUTOR_4, name:ds2020, Time Elapsed: 0(ms) <== SHARDING_EXECUTOR_2, name:ds2020, Time Elapsed: 0(ms) <== SHARDING_EXECUTOR_3, name:ds2020, Time Elapsed: 0(ms) <== Total: 4最后的最后
附上源码地址,源码中有文档,假如觉得有用请点击star谢谢他们了
GITHUB github地址 https://github.com/xuejmnet/easy-queryGITEE gitee地址 https://gitee.com/xuejm/easy-query原文链接:
https://www.cnblogs.com/xuejiaming/p/17433413.html