一个简易的ORM框架的实现(二)

这篇具有很好参考价值的文章主要介绍了一个简易的ORM框架的实现(二)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

框架目标

什么是框架,框架能做到什么?

把一个方向的技术研发做封装,具备通用性,让使用框架的开发者用起来很轻松。

属性:

  1. 通用性
  2. 健壮性
  3. 稳定性
  4. 扩展性
  5. 高性能
  6. 组件化
  7. 跨平台

从零开始-搭建框架

  1. 建立项目
  2. 主键查询功能开发
  3. 绑定实体

一步一步的给大家推导:
一边写一边测试

从零开始--搭建框架

1. 创建项目

首先,创建两个类库一个名为Models保存我们的模型,一个名为DbProxy的类库保存我们对数据库的核心操作。

先进行我们查询功能的编写,暂时不考虑通用性。

public class DbProxyCore
{
    public Commodity GetCommodity(int id)
    {
        string connectionString = "Data Source=10.10.32.242;Initial Catalog=AdvancedCustomerDB;Persist Security Info=True;User ID=sa;Password=*******";
        Commodity commodity = new Commodity();
        using (var connection = new SqlConnection(connectionString))
        {
            connection.Open();

            string sql = @"SELECT [Id]
                            ,[ProductId]
                            ,[CategoryId]
                            ,[Title]
                            ,[Price]
                            ,[Url]
                            ,[ImageUrl]
                            FROM [dbo].[Commodity] where Id="+id;

            SqlCommand sqlCommand= connection.CreateCommand();
            sqlCommand.CommandText = sql;
            SqlDataReader reader= sqlCommand.ExecuteReader();//数据集的读取器
           
             if (reader.Read())
            {
                commodity.Id = Convert.ToInt32(reader["Id"]);
                commodity.ProductId = Convert.ToInt64(reader["ProductId"]);
                commodity.CategoryId = Convert.ToInt32(reader["CategoryId"]);
                commodity.Title = reader["Title"].ToString();   
                commodity.Price = Convert.ToDecimal(reader["Price"]);
                commodity.Url = reader["Url"].ToString();
                commodity.ImageUrl = reader["ImageUrl"].ToString();                    
            }
            
        }
        return commodity;
    }
}

当我们又创建一个其他的model对象的时候,就遇到一个问题,难道我们需要每次都进行不同对象的独有的方法的创建吗?
并不是,这里就可以通过泛型来完成它们独有的方法
暂时的改造

  public T Find<T>(int id) where T : new()
  {
      string connectionString = """
          Data Source=10.10.32.242;Initial Catalog=AdvancedCustomerDB;Persist Security Info=True;User ID=sa;Password=*********;
          """;
      T obj = new T();
      using (var connection = new SqlConnection(connectionString))
      {
          connection.Open();

          string sql = @"SELECT [Id]
                          ,[ProductId]
                          ,[CategoryId]
                          ,[Title]
                          ,[Price]
                          ,[Url]
                          ,[ImageUrl]
                          FROM [dbo].[Commodity] where Id=" + id;

          SqlCommand sqlCommand = connection.CreateCommand();
          sqlCommand.CommandText = sql;
          SqlDataReader reader = sqlCommand.ExecuteReader();//数据集的读取器

          if (reader.Read())
          {
              //commodity.Id = Convert.ToInt32(reader["Id"]);
              //commodity.ProductId = Convert.ToInt64(reader["ProductId"]);
              //commodity.CategoryId = Convert.ToInt32(reader["CategoryId"]);
              //commodity.Title = reader["Title"].ToString();
              //commodity.Price = Convert.ToDecimal(reader["Price"]);
              //commodity.Url = reader["Url"].ToString();
              //commodity.ImageUrl = reader["ImageUrl"].ToString();
          }

      }
      return obj;
  }
       

尝试运行,可以正确的运行,并不报错。

我们要给对象的属性赋值,不能通过new一个对象,直接调用对象的属性赋值;
这里就可以使用到我们的反射技术。

  public T Find<T>(int id) where T : new()
  {
      string connectionString = """
          Data Source=10.10.32.242;Initial Catalog=AdvancedCustomerDB;Persist Security Info=True;User ID=sa;Password=7ujm&UJM;
          """;
      //T obj = new T();
      Type type = typeof(T);
      object? oResult = Activator.CreateInstance(type);

      using (var connection = new SqlConnection(connectionString))
      {
          connection.Open();

          string sql = @"SELECT [Id]
                          ,[ProductId]
                          ,[CategoryId]
                          ,[Title]
                          ,[Price]
                          ,[Url]
                          ,[ImageUrl]
                          FROM [dbo].[Commodity] where Id=" + id;

          SqlCommand sqlCommand = connection.CreateCommand();
          sqlCommand.CommandText = sql;
          SqlDataReader reader = sqlCommand.ExecuteReader();//数据集的读取器

          if (reader.Read())
          {
              //commodity.Id = Convert.ToInt32(reader["Id"]);
              //commodity.ProductId = Convert.ToInt64(reader["ProductId"]);
              //commodity.CategoryId = Convert.ToInt32(reader["CategoryId"]);
              //commodity.Title = reader["Title"].ToString();
              //commodity.Price = Convert.ToDecimal(reader["Price"]);
              //commodity.Url = reader["Url"].ToString();
              //commodity.ImageUrl = reader["ImageUrl"].ToString();
              foreach (var prop in type.GetProperties())
              {                        
                prop.SetValue(oResult, reader[prop.Name]);
                                                        
              }
          }

      }
      return (T)oResult;
  }

还有就是sql语句的问题,如何通过T来生成不同的sql语句。
sql语句应该依赖于我们的泛型T,也通过T来动态生成不同的SQl的语句。

 public T Find<T>(int id) where T : new()
 {
     string connectionString = """
         Data Source=10.10.32.242;Initial Catalog=AdvancedCustomerDB;Persist Security Info=True;User ID=sa;Password=********;
         """;
     //T obj = new T();
     Type type = typeof(T);
     object? oResult = Activator.CreateInstance(type);

     using (var connection = new SqlConnection(connectionString))
     {
         connection.Open();

         List<string> propNameList = type.GetProperties().Select(c => c.Name).ToList();
         string strProps = string.Join(",", propNameList);

         string sql = $"SELECT {strProps} FROM {type.Name} where Id=" + id;
         //以逗号分割的数据库表的字段名称。
       

         SqlCommand sqlCommand = connection.CreateCommand();
         sqlCommand.CommandText = sql;
         SqlDataReader reader = sqlCommand.ExecuteReader();//数据集的读取器

         if (reader.Read())
         {
             foreach (var prop in type.GetProperties())
             {                        
               prop.SetValue(oResult, reader[prop.Name]);
                                                       
             }
         }

     }
     return (T)oResult;
 }

处理DBNULL的问题

prop.SetValue(oResult, reader[prop.Name] is DBNull ? null : reader[prop.Name]) ;

这里还需要考虑如何避免传入如何的实体,导致报错的问题。
使用基类约束就能避免这个问题了。文章来源地址https://www.toymoban.com/news/detail-712126.html

到了这里,关于一个简易的ORM框架的实现(二)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 如何创建一个简易的HTML网页框架

    在我们初步学习了web前端开发的一些知识时,我们可能会考虑构建一个简单的html网站,但是,如何着手去开始我们的网站,对于新手来说可能是个问题。 在这篇文章中,我将介绍我在构建一个简易的网页时,首先去做的事情。 当然,我本身也并非专业的前端设计师,写此文

    2024年02月06日
    浏览(40)
  • 从零用python flask框架写一个简易的网站

    要用Python写一个网站,你可以使用Python的Web框架来开发。常见的Python Web框架包括Django、Flask、Bottle等。以下是一个简单的使用Flask框架开发的示例。 在开始开发之前,你需要安装Flask框架。你可以使用以下命令来安装: 在安装完Flask之后,你可以创建一个Flask应用。以下是一个

    2024年02月12日
    浏览(41)
  • OpenCV单目标跟踪:实现目标追踪的简易指南

    了解如何使用OpenCV库实现单目标跟踪。本指南介绍了OpenCV中主要的目标跟踪算法,包括CSRT、KCF、MIL、GOTURN和DaSiamRPN。通过选择初始目标区域并使用适当的跟踪器,在视频中准确地追踪目标位置。快速掌握单目标跟踪技术,适用于视频监控、自动驾驶和行人跟踪等应用场景。

    2024年02月04日
    浏览(40)
  • 探索BasicCoin:一个简易的区块链实现

    项目地址:https://gitcode.com/zack-bitcoin/basiccoin 在数字货币和分布式账本技术的世界中,Bitcoin是毫无疑问的领头羊。而BasicCoin,作为开源项目,是一个为初学者设计的简单版Bitcoin实现,帮助我们理解区块链的工作原理。本文将深入探讨BasicCoin的技术特性,其用途,并解释为何它对

    2024年04月27日
    浏览(36)
  • 微信原生实现一个简易的图片上传功能

    wx.showActionSheet():显示操作菜单,选择是从相册选择还是相机拍摄照片 wx.chooseImage():从本地相册选择图片或使用相机拍照。 wx.uploadFile():将本地资源上传到服务器。客户端发起一个 HTTPS POST 请求,其中 content-type 为 multipart/form-data。 wx.previewMedia(): 预览图片和视频。 upload.wx

    2024年02月16日
    浏览(36)
  • 【Qt 一个简易画板的实现(Graphics View)】

    Qt专栏 Qt 学习之路(32): 一个简易画板的实现(Graphics View) 这一次将介绍如何使用 Graphics View 来实现前面所说的画板。前面说了很多有关 Graphics View的好话,但是没有具体的实例很难说究竟好在哪里。现在我们就把前面的内容使用 Graphics View 重新实现一下,大家可以对比一下看有

    2024年02月16日
    浏览(45)
  • 认识环境变量和进程替换,实现一个简易的shell

    首先,在百度百科中,环境变量的解释是这样的: 环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数,如:临时文件夹位置和系统文件夹位置等。环境变量是在操作系统中一个具有特定名字的对象,它包含了一个或者多个应用程序所将

    2024年02月08日
    浏览(52)
  • 如何用Java实现一个简易的图书管理系统

    目录 确立对象 确立这些对象的基本信息和功能 书 书架 管理员和普通用户 各对象之间进行交互 既然是Java实现,那么就应该从面向对象的思想入手。首先需要确立有哪些对象,这些对象的功能又是什么,然后通过这些对象的交互实现这样一个建议的图书管理系统。 要实现图

    2024年02月04日
    浏览(90)
  • ORM框架概述

      现在各大公司比较流行的ORM框架有MyBatis,Hibernate,Spring Data JPA等,甚至一些公司会进行封装后成为自己公司专用的框架。相信后端方向的各位小伙伴都知道, ORM框架就是连接数据库的桥梁 ,比较官方的说法叫“ 对象关系映射 ”。单单这六个字并不能很好地理解ORM框架。ORM 英

    2024年02月11日
    浏览(40)
  • 【Servlet学习三】实现一个内存版本的简易计算器~

    目录 一、方式1:使用form表单的形式(不推荐) 🌈1、前端代码:HTML文件 🌈2、后端代码:Calculator_form.java文件 🌈3、最终效果 二、方式2:使用ajax形式(最常用重点!!!) 🌈1、前端代码:HTML文件 🌈2、后端代码:Calculator_ajax.java文件 🌈3、最终效果  注意: (1)前端

    2024年02月12日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包