• ORM框架对分表分库之分库和分表指定不同的字段


    ORM框架分库分表已实现了

    1. 只分表(根据指定字段)
      点我查看demo
    2. 只分库(根据指定字段)
      点我查看demo
    3. 既分库又分表(根据相同的字段)
      点我查看demo

    上面几点之前我在博客中已经写了使用介绍,点我查看

    最近我完善了分库分表功能:

    分库和分表可以指定不同的字段

    首先看下配置上是如何配置的

    image

    在配置上相比于上面提到的第3点,配置文件新增了

    • dbcolumn 代表db是根据哪个字段分
    • column 代表的table是根据哪个字段分
     {
          "Provider": "mysql",
          "Name": "testshardingdbandtableMany",
          "ShardingStrategy": "class=AntData.DbEngine.Sharding.ModShardingStrategy;dbcolumn=CityId;column=ID;mod=3;shardByDB=true;shardByTable=true",
          "ConnectionItemList": [
            {
              "Name": "testorm_mysql0",
              "Sharding": "0",
              "ConnectionString": "Server=127.0.0.1;Port=3306;Database=testorm1;Uid=root;Pwd=123456;charset=utf8;SslMode=none",
              "DatabaseType": "Master"
            },
            {
              "Name": "testorm_mysql1",
              "Sharding": "1",
              "ConnectionString": "Server=127.0.0.1;Port=3306;Database=testorm2;Uid=root;Pwd=123456;charset=utf8;SslMode=none",
              "DatabaseType": "Master"
            }
          ]
    
        }
    
    

    根据上面的配置的意思就是:

    1. class=AntData.DbEngine.Sharding.ModShardingStrategy代表的是按照取模策略来分表分库
    2. shardByDB=true;shardByTable=true 开启了分库分表的开关
    3. dbcolumn=CityId 代表的是分库是按照CityId的来分
    4. column=ID;代表的是分表是按照ID的值字段来分
    5. mod=3;代表的分表是按照3来取模
    6. db的取模是看ConnectionItemList有配置几个,上面的例子是配置2个,所以分库是按照2来取模

    对应我的库和表如下

    image

    image

    根据codegen来生成代码

    注意一点:
    代码生成器生成的表需要自己加一个_{0}
    例如:[Table(Comment = "订单表", Name = "order_{0}")]

        /// <summary>
        /// Database       : testorm1
        /// Data Source    : localhost
        /// Server Version : 5.6.26-log
        /// </summary>
        public partial class Entitys : IEntity
        {
            /// <summary>
            /// 订单表
            /// </summary>
            public IQueryable<Order> Orders { get { return this.Get<Order>(); } }
    
            private readonly IDataContext con;
    
            public IQueryable<T> Get<T>()
                where T : class
            {
                return this.con.GetTable<T>();
            }
    
            public Entitys(IDataContext con)
            {
                this.con = con;
            }
        }
    
        /// <summary>
        /// 订单表
        /// </summary>
        [Table(Comment = "订单表", Name = "order_{0}")]
        public partial class Order : BaseEntity
        {
            #region Column
    
            /// <summary>
            /// 订单号
            /// </summary>
            [Column("ID", DataType = DataType.Int64, Comment = "订单号"), Nullable]
            public long? ID { get; set; } // bigint(20)
    
            /// <summary>
            /// 名称
            /// </summary>
            [Column("Name", DataType = DataType.VarChar, Length = 50, Comment = "名称"), Nullable]
            public string Name { get; set; } // varchar(50)
    
    
            /// <summary>
            /// CityId
            /// </summary>
            [Column("CityId", DataType = DataType.Int64, Comment = "CityId"), Nullable]
            public long CityId { get; set; } 
    
            #endregion
        }
    
    

    下面来写测试代码验证

    
    
            /// <summary>
            /// 测试mod分库插入到testorm2数据库的order_1表
            /// </summary>
            [TestMethod]
            public void TestMethod6_01()
            {
                var id = 1;
                //查testorm2 的 order_1 表
                var odIsExist = DB.Tables.Orders.Any(r => r.ID.Equals(1) && r.CityId == 1);
                if (odIsExist)
                {
                    return;
                }
                var order = new Order
                {
                    ID = 1,//按照id分表
                    Name = "上海大学",
                    CityId = 1//按照cityid分库
                };
    
                var result = DB.Insert(order);
                Assert.AreEqual(result, 1);
    
            }
    
            /// <summary>
            /// 测试mod分库插入到testorm1数据库
            /// </summary>
            [TestMethod]
            public void TestMethod6_02()
            {
    
                var id = 2;
                //查testorm1 的 order_2 表
                var odIsExist = DB.Tables.Orders.Any(r => r.ID.Equals(2) && r.CityId == 2);
                if (odIsExist)
                {
                    return;
                }
                var order = new Order
                {
                    ID = 2,
                    Name = "北京大学",
                    CityId = 2
                };
    
                var result = DB.Insert(order);
                Assert.AreEqual(result, 1);
            }
    
            [TestMethod]
            public void TestMethod6_022()
            {
    
                var id = 2;
                //3%2=1 查testorm1 的3%3=0 order_0 表
                var odIsExist = DB.Tables.Orders.Any(r => r.ID.Equals(3) && r.CityId == 3);
                if (odIsExist)
                {
                    return;
                }
                var order = new Order
                {
                    ID = 3,
                    Name = "厦门大学",
                    CityId =3
                };
    
                var result = DB.Insert(order);
                Assert.AreEqual(result, 1);
            }
    
            /// <summary>
            /// 测试mod分库 查询testorm2数据库
            /// </summary>
            [TestMethod]
            public void TestMethod6_03()
            {
                var id = 1;
                // 1%2=1 testorm2的 1%3=1 order_1
                var tb1 = DB.Tables.Orders.FirstOrDefault(r => r.ID.Equals(1)&&r.CityId ==1);
                Assert.IsNotNull(tb1);
            }
    
            /// <summary>
            /// 测试mod分库 查询testorm1数据库
            /// </summary>
            [TestMethod]
            public void TestMethod6_04()
            {
                var id = 2;
                // 2%2=0 testorm1的 2%3=2 order_2
                var tb1 = DB.Tables.Orders.FirstOrDefault(r => r.ID.Equals(2)&&r.CityId ==2);
                Assert.IsNotNull(tb1);
            }
    
            /// <summary>
            /// 测试mod分库 不指定sharing column 查询叠加
            /// </summary>
            [TestMethod]
            public void TestMethod6_05()
            {
                //没有指定CityID也没有指定ID 会查询2个db的各3张表 6次的叠加
                var tb1 = DB.Tables.Orders.ToList();
                Assert.IsNotNull(tb1);
                Assert.AreEqual(tb1.Count, 3);
                //没有指定CityID 那么会查询2个db 。由于指定了ID 那么只会查询 1%3=1 order_1 2%3=2 order_2
                var odIsExist = DB.Tables.Orders.Where(r => r.ID.Equals(1) || r.ID.Equals(2)).ToList();
                Assert.AreEqual(odIsExist.Count, 2);
            }
    
            /// <summary>
            /// 测试mod分库修改到testorm2数据库
            /// </summary>
            [TestMethod]
            public void TestMethod6_06()
            {
                var id = 1;
                //没有指定CityID 那么会查询2个db 。由于指定了ID 那么只会查询 1%3=1 order_1 
                var result = DB.Tables.Orders.Where(r => r.ID.Equals(1)).Set(r => r.Name, y => y.Name + "1").Update();
                Assert.AreEqual(result, 1);
            }
    
            /// <summary>
            /// 测试mod分库修改到testorm1数据库
            /// </summary>
            [TestMethod]
            public void TestMethod6_07()
            {
                var id = 2;
                //没有指定CityID 那么会查询2个db 。由于指定了ID 那么只会查询 2%3=2 order_2 
                var result = DB.Tables.Orders.Where(r => r.ID.Equals(2)).Set(r => r.Name, y => y.Name + "1").Update();
                Assert.AreEqual(result, 1);
            }
    
            /// <summary>
            /// 测试mod分库删除到testorm2数据库
            /// </summary>
            [TestMethod]
            public void TestMethod6_08()
            {
                var id = 1;
                //没有指定CityID 那么会查询2个db 。由于指定了ID 那么只会查询 1%3=1 order_1 
                var result = DB.Tables.Orders.Where(r => r.ID.Equals(1)).Delete();
                Assert.AreEqual(result, 1);
            }
    
            /// <summary>
            /// 测试mod分库删除到testorm1数据库
            /// </summary>
            [TestMethod]
            public void TestMethod6_09()
            {
                var id = 2;
                //没有指定CityID 那么会查询2个db 。由于指定了ID 那么只会查询 2%3=2 order_2
                var result = DB.Tables.Orders.Where(r => r.ID.Equals(2)).Delete();
                Assert.AreEqual(result, 1);
            }
    
            /// <summary>
            /// 测试mod分库批量分别插入到testorm1 和 testorm2数据库
            /// </summary>
            [TestMethod]
            public void TestMethod7_02()
            {
                var orderList = new List<Order>();
                //会分到3%2=1 testorm2 的 order_0
                orderList.Add(new Order
                {
                    ID = 3,
                    Name = "上海大学",
                    CityId = 3
                });
                //会分到4%2=0 testorm1 的 order_1
                orderList.Add(new Order
                {
                    ID = 4,
                    Name = "上海大学",
                    CityId = 4
                });
    
                //没有指定 shading column的话是默认分到第一个分片
                orderList.Add(new Order
                {
                    ID = null,
                    Name = "上海大学",
                    //CityId = 0
                });
                 var rows = DB.BulkCopy(orderList);
                Assert.AreEqual(rows.RowsCopied, 3);
            }
    
            [TestMethod]
            public void TestMethod7_03()
            {
                var odIsExist = DB.Tables.Orders.Delete();
    
            }
    
            /// <summary>
            /// 指定了shadingtable的分库 自动会走到1对应的db
            /// </summary>
            [TestMethod]
            public void TestMethod7_04()
            {
                DB.UseShardingDbAndTable("1","1", con =>
                {
                    //1%2 = 1 1%3 = 1 testorm2 的 order_1
                    var first = con.Tables.Orders.FirstOrDefault();
                    Assert.IsNotNull(first);
                    Assert.AreEqual(1, first.ID);
                });
    
            }
    
            /// <summary>
            /// 指定了shadingtable的分库 自动会走到0对应的db
            /// </summary>
            [TestMethod]
            public void TestMethod7_05()
            {
                DB.UseShardingDbAndTable("0","0", con =>
                {
                    //0%2 = 0 0%3 = 0 testorm1 的 order_0
                    var first = con.Tables.Orders.FirstOrDefault();
                    Assert.IsNotNull(first);
                    Assert.AreEqual(2, first.ID);
                });
    
            }
    
    
    

    总结

    目前在AntData orm中使用分库分表在使用上是不是很爽:

    1. 决定好用哪种策略 是取模 还是区间分片
    2. 支持只分表,只分库,或者既分表又分库
    3. 如果既分表又分库还可以指定分库和分表的字段不同
    4. 只需要在配置文件上配置好即可
    5. 在写代码和平常一样

    如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!欢迎各位转载,转载文章之后须在文章页面明显位置给出作者和原文连接,谢谢。
  • 相关阅读:
    Spring 实例化bean的三种方式
    Mybatis和Hibernate比较
    MyBatis学习总结(一)——MyBatis快速入门
    Java EE的十三个规范
    Python 测试代码覆盖率统计工具 coverage.py
    mysql explain执行计划详解
    Django模型的Field Types
    使程序在Linux下后台运行,程序运行前后台切换
    ubuntu中将本地文件上传到服务器
    Python-内置函数小结
  • 原文地址:https://www.cnblogs.com/yudongdong/p/14409367.html
Copyright © 2020-2023  润新知