Furion分表分库我也要happy coding
Furion分表分库集成ShardingCore
ShardingCore
ShardingCore 易用、简单、高性能、普适性,是一款扩展针对efcore生态下的分表分库的扩展解决方案,支持efcore2+的所有版本,支持efcore2+的所有数据库、支持自定义路由、动态路由、高性能分页、读写分离的一款组件,如果你喜欢这组件或者这个组件对你有帮助请点击下发star让更多的.neter可以看到使用
Github Star 助力dotnet 生态 Gitee Star
背景
随着.net6的发布,陆陆续续的框架都已经开始支持了,ShardingCore也不例外,为了推动.net生态,也为了让更多的的人了解.net下其实也有分表分库的解决方案,所以打算写一篇关于ShardingCore集成到其他框架的思路。
Fourin框架大家应该也是比较清楚的,作者也是一个乐于开源有着开源精神的人,秉着大家都是热爱开源的所以决定助Fourin一臂之力(蹭一下热度)。随着上次的AbpVNext的"完美"集成ShardingCore后,这次带来的就是Furion下的efcore集成。
efcore下完美的分表分库解决方案,支持任意efcore的集成框架,完美支持或者需要稍作修改即可完美支持,并不需要让你有任何使用的学习成本,几乎做到不修改现有efcore代码的前提下让你的程序完美支持分表分库。真正做到“零”代码修改。
新建Furion项目
首先我们已目前Furion最新版本为例v3.0.5,新建一个空的aspnetcore web api的net6项目,当然也支持efcore2+的所有aspnetcore版本。
然后我们添加ShardingCore和efcore.SqlServer包

新建dbcontext
这边看了Furion的使用方法和Abp一样需要继承一个他自己的DbContext叫做AppDbContext,但是没有关西。因为ShardingCore是基于接口来实现的,所以不存在多继承问题,只是我们需要自行实现Furion的ShardingDbContext的抽象版本源码地址 AppShardingDbContext

简单的说下就是如果你是需要继承某个dbcontext的那么就需要自己实现三个接口IShardingDbContext, ISupportShardingTransaction, ISupportShardingReadWrite分别是分表分库的核心接口,支持事务,支持读写分离。
具体已经帮你们抽象好了只需要复制代码就可以了。
做好了准备工作我们开始新建dbcontext
[AppDbContext("SqlServerConnectionString", DbProvider.SqlServer)]
public class DefaultDbContext : AppShardingDbContext<DefaultDbContext>,IShardingTableDbContext
{
public DefaultDbContext(DbContextOptions<DefaultDbContext> options) : base(options)
{
}
public IRouteTail RouteTail { get; set; }
}
创建todoitem对象
public class TodoItem:IPrivateEntity
{
public string Id { get; set; }
public string Name { get; set; }
}
这边我们将TodoItem的Id做成取模分表
配置dbcontext
[AppDbContext("SqlServerConnectionString", DbProvider.SqlServer)]
public class DefaultDbContext : AppShardingDbContext<DefaultDbContext>,IShardingTableDbContext
{
public DefaultDbContext(DbContextOptions<DefaultDbContext> options) : base(options)
{
}
public IRouteTail RouteTail { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<TodoItem>(entity =>
{
entity.HasKey(o => o.Id);
entity.Property(o => o.Id).IsRequired().IsUnicode(false).HasMaxLength(50).HasComment("Id");
entity.Property(o => o.Name).IsRequired().HasMaxLength(50).HasComment("名称");
entity.ToTable(nameof(TodoItem));
});
}
}
配置了todoitem的简单配置,注意这边不一定要这么配置,也可以用Attribute+DbSet,也可以用FluentApi
创建TodoItem的分表路由
public class TodoItemVirtualTableRoute : AbstractSimpleShardingModKeyStringVirtualTableRoute<TodoItem>
{
public TodoItemVirtualTableRoute() : base(2, 8)
{
}
public override void Configure(EntityMetadataTableBuilder<TodoItem> builder)
{
builder.ShardingProperty(x => x.Id);
}
}
这边采用的是简单取模通过构造函数传入,具体可以参考文档就是分表后缀为2位数,模8也就是00,01.....07,一共8张表,ShardingProperty(x => x.Id)表示TodoItem的分表字段为Id。
注意: 这边只是为了简单演示,你如果需要外部传入可以自行通过实现AbstractShardingOperatorVirtualTableRoute来实现,并且路由构造函数支持单例的依赖注入
初始化Furion配置
AppStartup
[AppStartup(600)]
public sealed class SqlServerEntityFrameworkCoreStartup : AppStartup
{
public static readonly ILoggerFactory efLogger = LoggerFactory.Create(builder =>
{
builder.AddFilter((category, level) => category == DbLoggerCategory.Database.Command.Name && level == LogLevel.Information).AddConsole();
});
public void ConfigureServices(IServiceCollection services)
{
var connStr = DbProvider.GetConnectionString<DefaultDbContext>(/*这里可写可不写*/);
// 配置数据库上下文,支持N个数据库
services.AddDatabaseAccessor(options =>
{
// 配置默认数据库
options.AddDb<DefaultDbContext>(o =>
{
o.UseSqlServer(connStr).UseSharding<DefaultDbContext>().UseLoggerFactory(efLogger);
});
});
services.AddShardingConfigure<DefaultDbContext>((s, builder) =>
{
builder.UseSqlServer(s).UseLoggerFactory(efLogger);
}).Begin(o =>
{
o.CreateShardingTableOnStart = true;
o.EnsureCreatedWithOutShardingTable = true;
o.AutoTrackEntity = true;
})
.AddShardingTransaction((connection, builder) =>
builder.UseSqlServer(connection).UseLoggerFactory(efLogger))
.AddDefaultDataSource("ds0", connStr)
.AddShardingTableRoute(o =>
{
o.AddShardingTableRoute<TodoItemVirtualTableRoute>();
}).End();
}
}
通过官网我们可以知道如何针对Furion进行efcore的配置,这边目前sharding-core不支持efcore的单例dbcontext,所以不建议使用单例。
额外配置:.UseSharding<DefaultDbContext>()仅需要配置dbcontext使用sharding原先的所有dbcontext的注入都可以不去管他
sharding-core的配置:AddShardingConfigure是sharding-core在efcore的基础上额外进行配置就可以支持分表分库的扩展更多配置可以参考文档
Program
using ShardingCore.Bootstrapers;
var builder = WebApplication.CreateBuilder(args).Inject();
// Add services to the container.
builder.Services.AddControllers().AddInject();
var app = builder.Build();
// Configure the HTTP request pipeline.
app.UseAuthorization();
app.UseInject();
app.Services.GetRequiredService().Start();
app.MapControllers();
app.Run();
注意:很多同学老是忘记启动导致sharding-core没法使用app.Services.GetRequiredService<IShardingBootstrapper>().Start();
编写控制器
首先我们通过注入构造函数IRepository<TodoItem> todoItemRepository这是Furion提供的
其次我们编写增删改查接口
[HttpGet]
public async Task<IActionResult> Add()
{
await _todoItemRepository.InsertAsync(new TodoItem() { Id = Guid.NewGuid().ToString("n"), Name = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss") });
await _todoItemRepository.SaveNowAsync();
return Ok();
}
[HttpGet]
public async Task<IActionResult> List()
{
var list = await _todoItemRepository.AsQueryable().ToListAsync();
return Ok(list);
}
[HttpGet]
public async Task<IActionResult> First([FromQuery]string id)
{
var todoItem = await _todoItemRepository.FirstOrDefaultAsync(o => o.Id == id);
return Ok(todoItem);
}
[HttpGet]
public async Task<IActionResult> Update([FromQuery]string id)
{
var todoItem = await _todoItemRepository.FirstOrDefaultAsync(o => o.Id == id);
todoItem.Name = "123";
await _todoItemRepository.SaveNowAsync();
return Ok(todoItem);
}
启动项目
因为默认为了测试ShardingCore配置了
o.CreateShardingTableOnStart = true;
o.EnsureCreatedWithOutShardingTable = true;
所以启动会帮我们建表并且建库
新增

符合预期插入到了具体的hash%8的表
查询所有

因为是获取所有所以这边会查询所有的分表符合预期
获取单条

获取单条符合预期用的id取模所以用id去查询会到指定的表里面
更新

符合预期代码先查询05表在更新05表并且使用的是追踪更新
我们接着再来查询一次看看是否真的修改了

到此为止我们的Furion的ShardingCore集成就完成了,当然这只是ShardingCore的冰山一角,最最最简单的分表,如果你喜欢或者你认为ShardingCore有用那么可以给个赞或者star吗?开原作者希望自己开源的项目被更多人高人指点并且进步。也希望为.net下的分表分库进行一份微薄之力。在efcore下我相信ShardingCore是在官方不支持efcore下最最最完美的解决方案。全程的使用代码体验是0感知,只要你配置好了完全不需要考虑,当然也有同学要杠,如果某些情况下我就是要指定某几张表呢,ShardingCore也是支持的所以在自动情况下是“零”入侵业务代码的最优分表分库方案,更多使用方式请查询
github ShardingCore文档
gitee ShardingCore文档
最后项目源码
dotnet 天下第一 (大吼)
分表分库组件求赞求star
- Github ShardingCore
- Gitee ShardingCore
QQ群:771630778
个人QQ:326308290(欢迎技术支持提供您宝贵的意见)
个人邮箱:326308290@qq.com
Furion分表分库我也要happy coding的更多相关文章
- NetCore框架WTM的分表分库实现
介绍 本期主角: ShardingCore 一款ef-core下高性能.轻量级针对分表分库读写分离的解决方案,具有零依赖.零学习成本.零业务代码入侵 WTM WalkingTec.Mvvm框架(简称W ...
- .Net下极限生产力之efcore分表分库全自动化迁移CodeFirst
.Net下极限生产力之分表分库全自动化Migrations Code-First ## 介绍 本文ShardinfCore版本x.6.x.x+ 本期主角: - [`ShardingCore`](htt ...
- 学会数据库读写分离、分表分库——用Mycat,这一篇就够了!
系统开发中,数据库是非常重要的一个点.除了程序的本身的优化,如:SQL语句优化.代码优化,数据库的处理本身优化也是非常重要的.主从.热备.分表分库等都是系统发展迟早会遇到的技术问题问题.Mycat是一 ...
- .NETCore 下支持分表分库、读写分离的通用 Repository
首先声明这篇文章不是标题党,我说的这个类库是 FreeSql.Repository,它作为扩展库现实了通用仓储层功能,接口规范参考 abp vnext 定义,实现了基础的仓储层(CURD). 安装 d ...
- sharding sphere 分表分库 读写分离
sharding jdbc: sharding sphere 的 一部分,可以做到 分表分库,读写分离. 和 mycat 不同的 是 sharding jdbc 是 一个 jdbc 驱动 在 驱动这个 ...
- 总结下Mysql分表分库的策略及应用
上月前面试某公司,对于mysql分表的思路,当时简要的说了下hash算法分表,以及discuz分表的思路,但是对于新增数据自增id存放的设计思想回答的不是很好(笔试+面试整个过程算是OK过了,因与个人 ...
- 学会数据库读写分离、分表分库——用Mycat
系统开发中,数据库是非常重要的一个点.除了程序的本身的优化,如:SQL语句优化.代码优化,数据库的处理本身优化也是非常重要的.主从.热备.分表分库等都是系统发展迟早会遇到的技术问题问题.Mycat是一 ...
- (转)学会数据库读写分离、分表分库——用Mycat,这一篇就够了!
原文:https://www.cnblogs.com/joylee/p/7513038.html 系统开发中,数据库是非常重要的一个点.除了程序的本身的优化,如:SQL语句优化.代码优化,数据库的处理 ...
- Sharding-Jdbc实现分表分库
Sharding-Jdbc分表分库LogicTable数据分片的逻辑表,对于水平拆分的数据库(表),同一类表的总称.订单信息表拆分为2张表,分别是t_order_0.t_order_1,他们的逻辑表名 ...
随机推荐
- 从零入门 Serverless | 函数计算的可观测性
作者 | 夏莞 阿里巴巴函数计算团队 本文整理自<Serverless 技术公开课>,关注"Serverless"公众号,回复"入门",即可获取 S ...
- 洛谷4631 [APIO2018] Circle selection 选圆圈 (KD树)
qwq纪念AC450 一开始想这个题想复杂了. 首先,正解的做法是比较麻烦的. qwqq 那么就不如来一点暴力的东西,看到平面上点的距离的题,不难想到\(KD-Tree\) 我们用类似平面最近点对那个 ...
- Java:异常小记
Java:异常小记 对 Java 中的 异常 ,做一个微不足道的小小小小记 Error 和 Exception 相同点: Exception 和Error 都是继承了 Throwable 类,在 Ja ...
- 看动画学算法之:队列queue
目录 简介 队列的实现 队列的数组实现 队列的动态数组实现 队列的链表实现 队列的时间复杂度 简介 队列Queue是一个非常常见的数据结构,所谓队列就是先进先出的序列结构. 想象一下我们日常的排队买票 ...
- BUAA-OO-UML
BUAA-OO-UML 作业架构设计分析 第一次作业 类图如下: 这个架构十分简明,就是在底层数据和调用者之间建立起一层隔离层.但其实可以将转换过程延迟到调用阶段. 第二次作业 类图如下: 架构基本同 ...
- 北航OO第四单元总结
OO最后一次博客作业--好聚好散 一.单元总结 作业一: 第一次是对类图进行解析,没有太大难度,只要根据讨论区提供的建议,新建两个类来存储相关数据即可实现. 作业二: 第二次作业的难度只有量的提升,然 ...
- Vue报错 type check failed for prop “xxx“. Expected String with value “xx“,got Number with value ‘xx‘
vue报错 [Vue warn]: Invalid prop: type check failed for prop "name". Expected String with ...
- NKOJ-2936 城市建设
问题描述: PS国是一个拥有诸多城市的大国,国王Louis为城市的交通建设可谓绞尽脑汁.Louis可以在某些城市之间修建道路,在不同的城市之间修建道路需要不同的花费.Louis希望建造最少的道路使得国 ...
- EasyX安装教程
Easyx是什么 就是一款可以在Windows里让你的C++程序里显示图片等的工具. 注意:EasyX不支持Linux.MacOS.不过还有Qt等可以选择. 安装VC/VS Easyx只支持Visua ...
- 《手把手教你》系列技巧篇(三十六)-java+ selenium自动化测试-单选和多选按钮操作-番外篇(详解教程)
1.简介 前边几篇文章是宏哥自己在本地弄了一个单选和多选的demo,然后又找了网上相关联的例子给小伙伴或童鞋们演示了一下如何自动化测试,这一篇宏哥在网上找了一个问卷调查,给小伙伴或童鞋们来演示一下.上 ...