一個簡易的ORM框架的實現(一)

一個簡易的ORM框架的實現

ORM

ORM---操作數據庫---對象關係映射
ORM(Object Relational Mapping)框架採用元數據來描述對象與關係映射的細節。只要提供了持久化類與表的映射關係,ORM框架在運行時就能參照映射文件的信息,把對象持久化到數據庫中。

早期數據庫操作---ADO.NET

ADO.NET的名稱起源於ADO(Active Data Objects),是COM組件庫,用於在以往的Mircrosoft技術中訪問數據。之所以使用ADO.NET名稱,是因爲Microsoft希望表明,這是在NET編程環境中優先使用的數據訪問接口。
ADO.NET的操作過程
1 連接數據庫
2 傳遞SQL語句
3 數據庫執行Sql語句
4 返回執行結果

ADO.NET與ORM的比較
ADO:

  1. 大量的sql語句---業務不同,sql語句不同
  2. 需要根據不同的場景編寫不同的代碼--- 靈活去編寫sql語句 --- 提前優化sql語句 --- 提供高性能的sql語句
  3. 不適合快速開發
  4. 可編程性--- 更加靈活(對於高級開發,全方位發展的)
  5. 高性能---原生---接近於底層
    ORM:
  6. 上手快
  7. 不用關注數據庫,不關注sql語句,降低了開發的成本
  8. 關注對象,以對象爲核心
  9. 適合快速開發構建
  10. 性能有爭議
  11. 生成的sql語句---相對僵化---代碼生成器

ORM性能爭議

  1. 二次封裝---業務的執行,步驟多一些
    2。 映射的過程---必然從類到sql語句變化---類---sql語句---必然會有大量的反射
  2. sql語句僵化---數據庫執行有性能損耗

ADO.NET 的增刪改查操作

引入我們所需要的nuget包 System.Data.SqlClient
如果我們記不住我們的鏈接字符串的時候,我們可以通過

連接到我們的數據庫,然後通過數據連接中,找到我們所需要的連接字符串

   const string connectString = "Data Source=10.10.33.197;Persist Security Info=True;User ID=sa;Password=********";
    using (SqlConnection connection = new SqlConnection(connectString))
    {
        Console.WriteLine($"狀態 {connection.State}");
        connection.Open();
        Console.WriteLine($"狀態 {connection.State}");
        connection.Close();
    }

增刪改查我們主要分爲2類
增刪改----受影響行數
查詢 ----結果集

增加

 SqlCommand sqlCommand = connection.CreateCommand();
        string sql = @"INSERT INTO
	beauty(id,NAME,sex,borndate,phone,photo,boyfriend_id)
VALUES(13,'唐藝昕','女','1990-4-23','18988888888',NULL,2);
";
        sqlCommand.CommandText = sql;
        int iret=sqlCommand.ExecuteNonQuery();

查詢

使用SqlDataReader來獲取結果集

SqlCommand sqlCommand = connection.CreateCommand();
        string sql = @" SELECT TOP (1000) [Id]
            ,[ProductId]
            ,[CategoryId]
            ,[Title]
            ,[Price]
            ,[Url]
            ,[ImageUrl]
        FROM [AdvancedCustomerDB].[dbo].[Commodity]";
        sqlCommand.CommandText = sql;
        SqlDataReader sqlDataReader=sqlCommand.ExecuteReader();
        while (sqlDataReader.Read())
        {
            Console.WriteLine(sqlDataReader["Id"]);
            Console.WriteLine(sqlDataReader["ProductId"]);
            Console.WriteLine(sqlDataReader["CategoryId"]);
            Console.WriteLine(sqlDataReader["Title"]);
            Console.WriteLine("=======================================");
        }

使用SqlDataAdapter獲取結果集

       SqlCommand sqlCommand = connection.CreateCommand();
        string sql = @" SELECT TOP (1000) [Id]
            ,[ProductId]
            ,[CategoryId]
            ,[Title]
            ,[Price]
            ,[Url]
            ,[ImageUrl]
        FROM [AdvancedCustomerDB].[dbo].[Commodity]";
        SqlCommand cmd = connection.CreateCommand();
        cmd.CommandText = sql;
        cmd.CommandType = System.Data.CommandType.Text;
        SqlDataAdapter adptr = new SqlDataAdapter(cmd);
        System.Data.DataSet ds = new DataSet();
        adptr.Fill(ds, "myds");

        DataTable dt = new DataTable();
        adptr.Fill(dt);

我們在使用上面的語句的時候就遇到了一個問題,什麼問題?
就是sql注入的問題,我們沒有防備別人使用SQL語句的情況,那我們如何避免這個問題那?
就是SQL語句的參數化。

SqlCommand sqlCommand = connection.CreateCommand();
        string sql = @"INSERT INTO [dbo].[Commodity]
                                                   ([ProductId]
                                                   ,[CategoryId]
                                                   ,[Title]
                                                   ,[Price]
                                                   ,[Url]
                                                   ,[ImageUrl])
                                             VALUES
                                                   (@ProductId
                                                   ,@CategoryId
                                                   ,@Title
                                                   ,@Price
                                                   ,@Url
                                                   ,@ImageUrl)";
        SqlCommand cmd = connection.CreateCommand();
        cmd.CommandText = sql;
        cmd.CommandType = System.Data.CommandType.Text;
        cmd.Parameters.Add(new SqlParameter("@ProductId", "12345798"));
        cmd.Parameters.Add(new SqlParameter("@CategoryId", "234"));
        cmd.Parameters.Add(new SqlParameter("@Title", "高級進階課程高級進階課");
        cmd.Parameters.Add(new SqlParameter("@Price", "4799.00"));
        cmd.Parameters.Add(new SqlParameter("@Url", "zhaoxiedu.net"));
        cmd.Parameters.Add(new SqlParameter("@ImageUrl", "zhaoxiedu.net"));
        object insertResult = cmd.ExecuteNonQuery();

事務的問題

 using (SqlTransaction transaction = connection.BeginTransaction())
            {
                try
                {
                    //對於業務上來說,可能同時去操作多次數據庫表
                    //要成功--必須要都得成功
                    //ACID
                    //原子性
                    //一致性 --- 要麼都成功 只要有一個失敗了,都失敗了
                    //隔離性
                    //持久性 
                    #region 第一個操作
                    { 
                        string sql = @"Delete [AdvancedCustomerDB].[dbo].[Commodity] where id >@id";
                        SqlCommand cmd = connection.CreateCommand();
                        cmd.Transaction = transaction;
                        cmd.CommandText = sql;
                        cmd.CommandType = System.Data.CommandType.Text;
                        cmd.Parameters.Add(new SqlParameter("@id", 31010));
                        object deleteResult = cmd.ExecuteNonQuery();
                    }
                    #endregion 
                    #region 第二個操作
                    {
                        string sql = @"INSERT INTO [dbo].[Commodity]
                                                   ([ProductId]
                                                   ,[CategoryId]
                                                   ,[Title]
                                                   ,[Price]
                                                   ,[Url]
                                                   ,[ImageUrl])
                                             VALUES
                                                   (@ProductId
                                                   ,@CategoryId
                                                   ,@Title
                                                   ,@Price
                                                   ,@Url
                                                   ,@ImageUrl)";
                        SqlCommand cmd = connection.CreateCommand();
                        cmd.Transaction = transaction;
                        cmd.CommandText = sql;
                        cmd.CommandType = System.Data.CommandType.Text;
                        cmd.Parameters.Add(new SqlParameter("@ProductId", "12345798"));
                        cmd.Parameters.Add(new SqlParameter("@CategoryId", "234"));
                        cmd.Parameters.Add(new SqlParameter("@Title", "高級進階課程高級進階課");
                        cmd.Parameters.Add(new SqlParameter("@Price", "4799.00"));
                        cmd.Parameters.Add(new SqlParameter("@Url", "zhaoxiedu.net"));
                        cmd.Parameters.Add(new SqlParameter("@ImageUrl", "zhaoxiedu.net"));
                        object insertResult = cmd.ExecuteNonQuery();
                    }
                    #endregion
                    transaction.Commit();
                }
                catch (Exception ex)
                {
                    transaction.Rollback(); //回滾  可以把之前的操作 全部作廢
                    Console.WriteLine(ex.Message);
                } 
            };
        }


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章