zoukankan      html  css  js  c++  java
  • 手撸ORM浅谈ORM框架之基础篇

    好奇害死猫

    一直觉得ORM框架好用、功能强大集众多优点于一身,当然ORM并非完美无缺,任何事物优缺点并存!我曾一度认为以为使用了ORM框架根本不需要关注Sql语句如何执行的,更不用关心优化的问题!!! 随着发际线后移高亮意识到优秀程序员写的优秀的ORM框架会做一些Sql优化,Sql优化不是一成不变的,ORM框架不会根据项目业务场景等主动优化Sql语句。如果ORM真的强大的到开发人员不需要关注Sql,会针对当前项目情况做出相对应很好的优化,必然会增加ORM框架的体积、带来性能等相关问题。知己知彼,百战不殆。一直想探索ORM原理,为什么调用ORM Add或Insert方法都可以把实体写入到数据库???由于好奇之心我准备写一个ORM系列随笔,浅谈对ORM的理解,作者水平有限欢迎园友纠正错误及不恰当之处。

    千里之行始于足下


    ORM对象关系映射(英语:Object Relational Mapping,简称ORM,或O/RM,或O/R mapping),是一种程序设计技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。

    技术栈: .NET Core 3.1 + MySql + Autofac + Swagger

    官方地址传送:

    微软NET Core 3.1: 中文https://docs.microsoft.com/zh-cn/dotnet/   英文https://docs.microsoft.com/en-us/dotnet/

    MySql 8.x 文档: https://dev.mysql.com/doc/

    Autofac文档: 中文https://autofaccn.readthedocs.io/zh/latest/   英文https://autofaccn.readthedocs.io/en/latest/

    Swagger文档: https://swagger.io/docs/

    目前计划

    手撸ORM浅谈ORM框架之基础篇

    手撸ORM浅谈ORM框架之Add篇

    手撸ORM浅谈ORM框架之Update篇

    手撸ORM浅谈ORM框架之Delete篇

    手撸ORM浅谈ORM框架之Query篇

    后续待定。。。。。。

    MySql 8.x 坎(待解决)


     //Grant all privileges on learndb.* to 'learn_user@'@'%'

    //> 1410 - You are not allowed to create a user with GRANT
    //Sql = @"CREATE DATABASE IF NOT EXISTS learndb;"

    因此,权限需要先手动授予: 服务器权限-》Create;(更新2020-10-16)由于使用learn_user用户名是新建的还需要授予增删查改访问权限。注:遇到的项目中一般都是数据库优先或者使用的EntityFramework来创建数据库,MySql8.x命令授权给用户不太熟练。

     新风尚WebApi

    .NET Framework使用静态资源除了保护文件夹可以直接添加需要的静态资源文件夹即可;.NET Core使用静态文件需要在Startup-》Configure 方法中启用静态文件UseStaticFiles并且文件夹的名称:wwwroot,否则禁止访问静态资源。WebApi添加wwwroot文件夹存放静态资源,.Net Core中需要手动添加swagger静态样式资源,下载地址 : swagger-ui ,您也可以使用项目中的wwwroot里面的样式。

    Api神器Swagger

    Startup-》ConfigureServices 方法中添加Swagger 文档doc、xml、security等信息。新版本Swashbuckle.AspNetCore.Swagger有一些改动,例如SwaggerDoc-》OpenApiInfo的属性TermsOfService由String修改为Uri,在对TermsOfService赋值时如果非Uri或String无法转换正确的Uri项目Debug时会抛出下面异常。

    System.UriFormatException
    HResult=0x80131537
    Message=Invalid URI: The format of the URI could not be determined.

     1 private const string ProjectName = "Learn.WebApi";
     2 
     3 // This method gets called by the runtime. Use this method to add services to the container.
     4 public void ConfigureServices(IServiceCollection services)
     5 {
     6     #region Swagger
     7 
     8     services.AddSwaggerGen(c =>
     9     {
    10         c.SwaggerDoc("v1", new OpenApiInfo
    11         {
    12             Title = ProjectName,
    13             Version = "v1",
    14             Description = $"{ProjectName} HTTP API ",
    15             TermsOfService = new Uri("https://github.com/dingshuanglei"),
    16             Contact = new OpenApiContact { Name = "丁双磊", Email = "shuangleiding@163.com", Url = new Uri("https://github.com/dingshuanglei") }
    17         });
    18 
    19         var basePath = Path.GetDirectoryName(typeof(Program).Assembly.Location);
    20         var xmlPath = Path.Combine(basePath, $"{ProjectName}.xml");
    21         c.IncludeXmlComments(xmlPath, true);
    22         var modelXmlPath = Path.Combine(basePath, "Learn.Model.xml");
    23         c.IncludeXmlComments(modelXmlPath, true);
    24 
    25         // Add security definitions
    26         c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme()
    27         {
    28             Description = "Please enter into field the word 'Bearer' followed by a space and the JWT value",
    29             Name = "token",
    30             In = ParameterLocation.Header,
    31             Type = SecuritySchemeType.ApiKey,
    32         });
    33         c.AddSecurityRequirement(new OpenApiSecurityRequirement
    34         {
    35             {
    36                 new OpenApiSecurityScheme
    37                 {
    38                     Reference = new OpenApiReference()
    39                     {
    40                         Id = "Bearer",
    41                         Type = ReferenceType.SecurityScheme
    42                     }
    43                 }, Array.Empty<string>()
    44             }
    45         });
    46     });
    47 
    48     #endregion
    49 
    50     #region db init
    51 
    52     InitDbTable.InitTable();
    53 
    54     #endregion
    55 
    56     services.AddControllers();
    57 }

    (更新2020-10-16)WebApi项目右键属性设置,下图2处适合强迫症开发者取消summary注释,1处是WebApi使用swagger必须的用来显示接口信息;

     Startup-》Configure 方法中启用Swagger和静态文件UseStaticFiles。

     1 // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
     2 public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
     3 {
     4     if (env.IsDevelopment())
     5     {
     6         app.UseDeveloperExceptionPage();
     7     }
     8 
     9     app.UseRouting();
    10 
    11     #region Swagger
    12     app.UseSwagger();
    13     app.UseSwaggerUI(c =>
    14     {
    15         c.SwaggerEndpoint("/swagger/v1/swagger.json", $"v1");
    16         c.RoutePrefix = string.Empty;
    17     });
    18     #endregion
    19 
    20     app.UseAuthorization();
    21 
    22     //使用静态文件
    23     app.UseStaticFiles();
    24 
    25     app.UseEndpoints(endpoints =>
    26     {
    27         endpoints.MapControllers();
    28     });
    29 }

    Program-》CreateHostBuilder 方法中将默认ServiceProviderFactory指定为AutofacServiceProviderFactory。

    1 public static IHostBuilder CreateHostBuilder(string[] args) =>
    2    Host.CreateDefaultBuilder(args)
    3        //将默认ServiceProviderFactory指定为AutofacServiceProviderFactory
    4        .UseServiceProviderFactory(new AutofacServiceProviderFactory())
    5        .ConfigureWebHostDefaults(webBuilder =>
    6        {
    7            webBuilder.UseStartup<Startup>();
    8        });

    Autofac Ioc

    Startup-》添加ConfigureContainer方法注入需要Ioc管理的类及类库,当前项目中使用的注入没有特殊的需求,普通的注入业务层和数据访问层类库,也可以根据您自身项目的需要指定注入的生命周期、单接口多实现等等。

     1 /// <summary>
     2 /// autofac ioc
     3 /// </summary>
     4 /// <param name="builder"></param>
     5 public void ConfigureContainer(ContainerBuilder builder)
     6 {
     7     //使用单例模式
     8     //builder.RegisterType<Test>().As<ITest>().SingleInstance().PropertiesAutowired();
     9 
    10     //单接口多实现
    11     //builder.RegisterType<TestOne>().Named<ITest>(nameof(TestOne));
    12     //builder.RegisterType<TestTwo>().Named<ITest>(nameof(TestTwo));
    13 
    14     Assembly[] assembliesService = new Assembly[] { Assembly.Load("Learn.Service") };
    15     builder.RegisterAssemblyTypes(assembliesService).Where(type => !type.IsAbstract && typeof(IocService).IsAssignableFrom(type)).AsImplementedInterfaces().PropertiesAutowired();
    16 
    17     Assembly[] assembliesRepository = new Assembly[] { Assembly.Load("Learn.Repository") };
    18     builder.RegisterAssemblyTypes(assembliesRepository).Where(type => !type.IsAbstract).AsImplementedInterfaces().PropertiesAutowired();
    19 }

    代码下载地址: SourceCode  作者水平有限欢迎园友纠正错误及不恰当之处,予以及时修正以免误导他人!

     
  • 相关阅读:
    原!!如何将多个复杂查询整合成一个查询,并作为一个对象的各个字段输出
    转!!mysql order by 中文排序
    mybatis 模糊查询 like
    转!!log4j基础
    CI框架下的PHP增删改查总结
    tp5中url使用js变量传参方法
    一个用户管理的ci框架的小demo--转载
    CI框架入门教程
    PHP的CI框架流程基本熟悉
    CI
  • 原文地址:https://www.cnblogs.com/dingshuanglei/p/13804106.html
Copyright © 2011-2022 走看看