• DapperPoco


    DapperPoco -- 基于Dapper的、轻量级的、高性能的、简单的、灵活的ORM框架

    为什么要重复造轮子

    因为现有的轮子都在某些方面不太令我满意,下面我来一一点评一下,欢迎拍砖。

    Entity Framework

    我喜欢傻瓜化使用方式的框架,同时又不失灵活性。

    EF虽然使用起来足够简单,但却不够灵活。例如,在EF Core中你无法用原生SQL写一个多表连接查询(返回的结果是多表连接的结果)

    单表简单条件查询还好,多表查询时生成的SQL性能实在不敢恭维,我更喜欢自己写SQL,可控性更高,心里有底

    EF的设计不利于项目的分层;我理想的设计是隔离、低耦合,和数据库打交道的事就交给Db层好了,所有数据库的特性都隔离在Db层内部,对外按业务提供傻瓜化的接口。
    而使用EF你没法做到真正的隔离,因为即使能把SaveChanges封装在Db层,导航属性也会导致再次查询数据库。

    Dapper

    我喜欢它的轻量级,高性能。但它"只支持"原生SQL读写数据库,使用起来还是不太方便。

    很多常用的情景其实可以封装一下不用写SQL的,像EF一样,直接Add一个Entity

    虽然现在Dapper已经有了这样一个封装,但目前来看实在过于粗糙

    PetaPoco

    它可以像EF一样直接Add一个Entity,也可以像Dapper一样自己写原生SQL,按理说这已经很完美了。

    但是,它不支持批量插入、更新啊

    DapperPoco

    在实在找不到满意框架的情况下,于是DapperPoco就诞生了,它是基于Dapper高度封装的,有Dapper的一切优点,同时也弥补了它的不足,它有如下特点:

    1. 高性能(与Dapper一致),以热启动后计算(第一次启动有缓存过程)
    2. 像EF一样使用简单,也可像Dapper一样灵活使用原生SQL
    3. 支持使用Fluent API定义实体映射
    4. 内部模块化灵活、可扩展

    现已将其开源并放到了github上,地址为:https://github.com/md-frank/DapperPoco

    如何使用

    首先定义一个Poco类

    复制代码
    //表示文章表里的一条记录
    public class Article
    {
        public long Id { get; set; }
        public string Title { get; set; }
        public string Content { get; set; }
    }
    复制代码

    创建DbContext

    复制代码
    class MasterDbContext : DbContext
    {
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseConnectionString("连接字符串");
            //使用SQL Server数据库
            optionsBuilder.UseSqlAdapter(new SqlServerAdapter(SqlClientFactory.Instance));
        }
    
        //如果不使用Poco可以不重写此方法
        protected override void OnEntitiesBuilding(EntitiesBuilder entityBuilder)
        {
            //属性名与表列名(列名)不一样,可在此映射别名
            entityBuilder.Entity<Article>()
                .TableName("T_Article")
                .ColumnName(p => p.Id, "article_id");
        }
    }
    复制代码

    插入数据

    复制代码
    var masterDb = new MasterDbContext();
    
    //插入一个Poco对象
    var a = new Article 
    {
        Title = "hello",
        Content = "hello word"
    };
    masterDb.Insert(a);
    
    //插入了2条记录
    masterDb.Insert(new Article[] { a, a });
    
    //也可以显式指定表名
    masterDb.Insert(a, "T_Article");
    
    //原生SQL插入
    this.Execute("insert T_Article(Title, Content) values (@Title, @Content)", a);
    
    //插入了2条记录
    this.Execute("insert T_Article(Title, Content) values (@Title, @Content)", a, a);
    
    //插入了2条记录
    this.Execute("insert T_Article(Title, Content) values (@Title, @Content)", new Article[] { a, a });
    
    //也可以直接写参数值
    this.Execute("insert T_Article(Title, Content) values (@p0, @p1)", "hello", "hello word");
    复制代码

    更新数据

    复制代码
    var masterDb = new MasterDbContext();
    
    //先查出来准备更新
    var article = masterDb.FirstOrDefault<Article>("select * from T_Article where article_id = @p0", 1);
    
    //更新除主键外的所有列
    article.Title = "hello 2";
    article.Content = "content 1";
    masterDb.Update(article);
    
    //仅更新指定列,指定表列名
    article.Title = "hello 2";
    masterDb.Update(article, new [] { "Title" });
    
    //仅更新指定列,指定实体属性名
    article.Title = "hello 3";
    article.Content = "content 1";
    masterDb.Update(article, null, null, p=> p.Title, p=> p.Content);
    复制代码

    保存数据

    复制代码
    var masterDb = new MasterDbContext();
    
    var article = new Article 
    {
        Id = 1,
        Title = "hello",
        Content = "hello word"
    };
    
    //如果记录存在则更新,不存在则插入
    masterDb.Save(article);
    
    //保存并指定列名
    masterDb.Save(article, new [] { "Title" });
    复制代码

    删除数据

    复制代码
    var masterDb = new MasterDbContext();
    
    var article = masterDb.FirstOrDefault<Article>("select * from T_Article where article_id = @p0", 1);
    
    //删除实体记录
    masterDb.Delete(article);
    
    //删除实体记录,显式指定主键名
    masterDb.Delete(article, "article_id");
    复制代码

    查询数据(立即执行)

    复制代码
    var masterDb = new MasterDbContext();
    
    //查询T_Article表所有记录
    var articles = masterDb.FetchAll<Article>();
    
    //指定条件查询,直接写参数值
    var articles = masterDb.Fetch<Article>("select * from T_Article where Title=@p0 and Content=@p1", "hello", "hello word");
    
    //指定条件查询,支持列表(实现了IEnumerable接口的)
    var articles = masterDb.Fetch<Article>("select * from T_Article where article_id in @p0", new [] { 1, 2, 3 });
    
    //查询单条记录
    masterDb.FirstOrDefault<Article>("select * from T_Article where article_id = @p0", 1);
    
    //查询单列
    var count = masterDb.ExecuteScalar<long>("select count(*) from T_Article");
    
    //查询分页的结果(第1页,每页20条)
    Paged<Article> paged = masterDb.Paged<Article>(1, 20, "select * from T_Article where Title=@p0", "hello");
    
    //Paged的定义如下
    public class Paged<T> where T : new()
    {
        //当前页码
        public int CurrentPage { get; set; }
    
        //总页数
        public int TotalPages { get; set; }
    
        ///总记录数
        public long TotalItems { get; set; }
    
        //每页记录数
        public int ItemsPerPage { get; set; }
    
        //当前页记录列表
        public List<T> Items { get; set; }
    }
    复制代码

    查询数据(延迟执行)

    延迟查询使用Query,与Fetch不同的是Query返回的结果只有在使用时才会真正查询数据库

    var masterDb = new MasterDbContext();
    
    //延迟查询
    var articles = masterDb.Query<Article>("select * from T_Article where Title=@p0", "hello");

    动态查询条件

    复制代码
    var title = "此变量来自用户输入";
    
    var sb = new SqlBuilder();
    sb.Append("select * from T_Article");
    if(!string.IsNullOrEmpty(title))
        sb.Append("where Title=@p0", title);
    
    var sql = sb.Build();
    var articles = masterDb.Fetch<Article>(sql.Statement, sql.Parameters);
    复制代码

    事务支持

    复制代码
    using (var trans = this.GetTransaction())
    {
        //这里修改数据库
    
        //提交事务
        trans.Complete();
    }
    复制代码
     
  • 相关阅读:
    Java8 lambda表达式10个示例
    我和阿里云RDS的故事
    Spring Mvc 传递参数要controller出现了400,日期参数全局处理,格式化yyyy-MM-dd 和yyyy-MM-dd HH:mm:ss
    剑指Offer_36_两个链表的第一个公共结点
    剑指Offer_35_数组中的逆序对
    剑指Offer_34_找出字符串中第一个只出现一次的字符
    剑指Offer_33_丑数
    剑指Offer_32_把数组排成最小的数
    剑指Offer_31_整数中1出现的次数(从1到n整数中1出现的次数)
    剑指Offer_30_连续子数组的最大和
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/6582670.html
Copyright © 2020-2023  润新知