(系列五).net8 中使用Dapper搭建底層倉儲連線資料庫(附原始碼)

陈逸子风發表於2024-10-06

說明

該文章是屬於OverallAuth2.0系列文章,每週更新一篇該系列文章(從0到1完成系統開發)。

該系統文章,我會盡量說的非常詳細,做到不管新手、老手都能看懂。

說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+視覺化流程管理系統。

友情提醒:本篇文章是屬於系列文章,看該文章前,建議先看之前文章,可以更好理解專案結構。

有興趣的朋友,請關注我吧(*^▽^*)。

關注我,學不會你來打我

安裝Dapper

1、在使用的地方,安裝最新版Dapper。

2、在使用的地方,安裝最新版的Microsoft.Extensions.Configuration

3、在使用的地方,安裝最新版的Microsoft.Extensions.Configuration.Json

4、在使用的地方,安裝最新版的System.Data.SqlClient

最終安裝包如下:

建立資料庫連線類

在建立資料庫連線類之前,我們要先在appsettings.json中配置我們的資料庫連線字串。

SqlConnection": "Server=SQLOLEDB;Data Source=你的sqlServer名稱;uid=你的資料庫賬號;pwd=你的資料庫密碼;DataBase=你的資料庫名字

如下圖:

配置好資料庫連線之後,我們需要一個讀取資料庫的類,所以我們需要在基礎設施層(Infrastructure)建立。

建立資料夾DataBaseConnect然後在建立一個類DataBaseConnectConfig.cs。

內容如下:

using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Configuration.Json;
using System.Data;
using System.Data.SqlClient;

namespace Infrastructure.DataBaseConnect
{
    /// <summary>
    /// 資料庫連線類
    /// </summary>
    public static class DataBaseConnectConfig
    {
        /// <summary>
        /// 宣告靜態連線
        /// </summary>
        public static IConfiguration Configuration { get; set; }

        /// <summary>
        /// 靜態建構函式
        /// </summary>
        static DataBaseConnectConfig()
        {
            //ReloadOnChange = true 當appsettings.json被修改時重新載入            
            Configuration = new ConfigurationBuilder()
            .Add(new JsonConfigurationSource { Path = "appsettings.json", ReloadOnChange = true })
            .Build();
        }

        /// <summary>
        /// 連線資料庫
        /// </summary>
        /// <param name="sqlConnectionStr">連線資料庫字串</param>
        /// <returns></returns>
        public static SqlConnection GetSqlConnection(string? sqlConnectionStr = null)
        {

            if (string.IsNullOrWhiteSpace(sqlConnectionStr))
            {
                sqlConnectionStr = Configuration["ConnectionStrings:SqlConnection"];
            }
            var connection = new SqlConnection(sqlConnectionStr);
            if (connection.State != ConnectionState.Open)
            {
                connection.Open();
            }
            return connection;
        }
    }
}
GetSqlConnection方法會讀取appsettings.json中的連線配置,並開啟資料庫。

建立倉儲

有了資料庫連線類後,我們就要開始著手搭建底層倉儲,結構如下:

根據以上結構,我們分別建立IRepository.cs倉儲介面和Repository.cs倉儲介面的實現

IRepository.cs內容如下:

 /// <summary>
 /// 倉儲介面定義
 /// </summary>
 public interface IRepository
 {
 }
 /// <summary>
 /// 定義泛型倉儲介面
 /// </summary>
 /// <typeparam name="T">實體型別</typeparam>
 /// <typeparam name="object">主鍵型別</typeparam>
 public interface IRepository<T> : IRepository where T : class, new()
 {
     /// <summary>
     /// 新增
     /// </summary>
     /// <param name="entity">實體</param>
     /// <param name="innserSql">新增sql</param>
     /// <returns></returns>
     int Insert(T entity, string innserSql);

     /// <summary>
     /// 修改
     /// </summary>
     /// <param name="entity">實體</param>
     /// <param name="updateSql">更新sql</param>
     /// <returns></returns>
     int Update(T entity, string updateSql);

     /// <summary>
     /// 刪除
     /// </summary>
     /// <param name="deleteSql">刪除sql</param>
     /// <returns></returns>
     int Delete(string key, string deleteSql);

     /// <summary>
     /// 根據主鍵獲取模型
     /// </summary>
     /// <param name="key">主鍵</param>
     /// <param name="selectSql">查詢sql</param>
     /// <returns></returns>
     T GetByKey(string key, string selectSql);

     /// <summary>
     /// 獲取所有資料
     /// </summary>
     /// <param name="selectAllSql">查詢sql</param>
     /// <returns></returns>
     List<T> GetAll(string selectAllSql);

     /// <summary>
     /// 根據唯一主鍵驗證資料是否存在
     /// </summary>
     /// <param name="id">主鍵</param>
     /// <param name="selectSql">查詢sql</param>
     /// <returns>返回true存在,false不存在</returns>
     bool IsExist(string id, string selectSql);

說明1:該倉儲介面是我們常用的crud(增刪改查)的介面,它適用於所有的表結構,讓我們不再重複的編寫一樣的sql語句。

說明2:該倉儲介面可以自定義通用的介面,列如分頁查詢、批次新增、批次修改等。

Repository.cs結構如下

 /// <summary>
 /// 倉儲基類
 /// </summary>
 /// <typeparam name="T">實體型別</typeparam>
 /// <typeparam name="TPrimaryKey">主鍵型別</typeparam>
 public abstract class Repository<T> : IRepository<T> where T : class, new()
 {
     /// <summary>
     /// 刪除
     /// </summary>
     /// <param name="deleteSql">刪除sql</param>
     /// <returns></returns>
     public int Delete(string key, string deleteSql)
     {
         using var connection = DataBaseConnectConfig.GetSqlConnection();
         return connection.Execute(deleteSql, new { Key = key });
     }

     /// <summary>
     /// 根據主鍵獲取模型
     /// </summary>
     /// <param name="id">主鍵</param>
     /// <param name="selectSql">查詢sql</param>
     /// <returns></returns>
     public T GetByKey(string id, string selectSql)
     {
         using var connection = DataBaseConnectConfig.GetSqlConnection();
         return connection.QueryFirstOrDefault<T>(selectSql, new { Key = id });
     }

     /// <summary>
     /// 獲取所有資料
     /// </summary>
     /// <param name="selectAllSql">查詢sql</param>
     /// <returns></returns>
     public List<T> GetAll(string selectAllSql)
     {
         using var connection = DataBaseConnectConfig.GetSqlConnection();
         return connection.Query<T>(selectAllSql).ToList();
     }

     /// <summary>
     /// 新增
     /// </summary>
     /// <param name="entity">新增實體</param>
     /// <param name="innserSql">新增sql</param>
     /// <returns></returns>
     public int Insert(T entity, string innserSql)
     {
         using var connection = DataBaseConnectConfig.GetSqlConnection();
         return connection.Execute(innserSql, entity);
     }

     /// <summary>
     /// 根據唯一主鍵驗證資料是否存在
     /// </summary>
     /// <param name="id">主鍵</param>
     /// <param name="selectSql">查詢sql</param>
     /// <returns>返回true存在,false不存在</returns>
     public bool IsExist(string id, string selectSql)
     {
         using var connection = DataBaseConnectConfig.GetSqlConnection();
         var count = connection.QueryFirst<int>(selectSql, new { Key = id });
         if (count > 0)
             return true;
         else
             return false;
     }

     /// <summary>
     /// 更新
     /// </summary>
     /// <param name="entity">更新實體</param>
     /// <param name="updateSql">更新sql</param>
     /// <returns></returns>
     public int Update(T entity, string updateSql)
     {
         using var connection = DataBaseConnectConfig.GetSqlConnection();
         return connection.Execute(updateSql, entity);
     }
 }

該類是IRepository.cs倉儲介面的實現,它繼承於Repository.cs

建立基礎sql倉儲(可省略)

做完以上操作,我們的底層倉儲事實上已經搭建完成,但博主搭建了一個基礎sql的倉儲,以便管理專案中所有基礎的sql語句。

在Infrastructure的根目錄建立一個BaseSqlRepository.cs的類。

編寫sql的基礎語句,現有語句如下。

 /// <summary>
 /// 建立繼承sql倉儲
 /// </summary>
 public class BaseSqlRepository
 {
     #region 表Sys_user

     /// <summary>
     /// sys_user新增
     /// </summary>
     public static string sysUser_insertSql = @"insert into Sys_User (UserName ,Password ,Age,Sex,IsOpen,DepartmentId,CreateTime,CreateUser) values(@UserName ,@Password ,@Age,@Sex,@IsOpen,@DepartmentId,@CreateTime,@CreateUser)";

     /// <summary>
     /// sys_user更新
     /// </summary>
     public static string sysUser_updateSql = @"update Sys_User set UserName=@UserName ,Password=@Password ,Age=@Age,Sex=@Sex,DepartmentId=@DepartmentId,CreateTime=@CreateTime,CreateUser=@CreateUser where UserId = @UserId";

     /// <summary>
     /// sys_user查詢
     /// </summary>
     public static string sysUser_selectByKeySql = @" select * from Sys_User where  UserId=@Key";

     /// <summary>
     /// sys_user表查詢全部語句
     /// </summary>
     public static string sysUser_selectAllSql = @" select * from Sys_User";

     #endregion
 }

建立表Sys_User模型

結構如下:

/// <summary>
/// 使用者表模型
/// </summary>
public class SysUser
{
    /// <summary>
    /// 使用者id
    /// </summary>
    public int UserId { get; set; }

    /// <summary>
    /// 使用者名稱
    /// </summary>
    public string UserName { get; set; }

    /// <summary>
    /// 密碼
    /// </summary>
    public string Password { get; set; }

    /// <summary>
    /// 年齡
    /// </summary>
    public int Age { get; set; }

    /// <summary>
    /// 性別
    /// </summary>
    public int Sex { get; set; }

    /// <summary>
    /// 是否開啟
    /// </summary>
    public bool IsOpen { get; set; }

    /// <summary>
    /// 部門id
    /// </summary>
    public int DepartmentId { get; set; }

    /// <summary>
    /// 建立時間
    /// </summary>
    public DateTime CreateTime { get; set; }

    /// <summary>
    /// 建立人員
    /// </summary>
    public string CreateUser { get; set; }
}

該結構,同資料庫表結構(一會說)

使用倉儲

在之前的ISysUserRepository.cs和SysUserRepository.cs中分別繼承IRepository.cs 和Repository.cs

/// <summary>
/// 使用者服務倉儲介面
/// </summary>
public interface ISysUserRepository : IRepository<SysUser>
{
    /// <summary>
    /// 測試Autofac
    /// </summary>
    /// <returns></returns>
    string TestAutofac();
}
 /// <summary>
 /// 使用者服務倉儲介面實現
 /// </summary>
 public class SysUserRepository : Repository<SysUser>, ISysUserRepository
 {
     /// <summary>
     /// 測試Autofac
     /// </summary>
     /// <returns></returns>
     public string TestAutofac()
     {
         return "Autofac使用成功";
     }
 }

該使用者倉儲繼承IRepository.cs 和Repository.cs之後,它就擁有了該倉儲介面下的所有介面。

測試

做完以上工作,我們開始測試

首先,我們需要建立資料庫(使用sqlServer資料庫)和使用者表

表結構和資料程式碼如下:

USE [OverallAuth]
GO
/****** Object:  Table [dbo].[Sys_User]    Script Date: 2024/10/6 10:38:21 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Sys_User](
    [UserId] [int] IDENTITY(1,1) NOT NULL,
    [UserName] [varchar](50) NOT NULL,
    [Password] [varchar](50) NOT NULL,
    [Age] [int] NULL,
    [Sex] [int] NULL,
    [DepartmentId] [int] NOT NULL,
    [IsOpen] [bit] NULL,
    [CreateTime] [datetime] NULL,
    [CreateUser] [varchar](50) NULL,
 CONSTRAINT [PK_Sys_User] PRIMARY KEY CLUSTERED 
(
    [UserId] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
SET IDENTITY_INSERT [dbo].[Sys_User] ON 

INSERT [dbo].[Sys_User] ([UserId], [UserName], [Password], [Age], [Sex], [DepartmentId], [IsOpen], [CreateTime], [CreateUser]) VALUES (1, N'張三', N'1', 18, 1, 1, 1, CAST(N'2024-10-06T09:14:13.000' AS DateTime), N'1')
INSERT [dbo].[Sys_User] ([UserId], [UserName], [Password], [Age], [Sex], [DepartmentId], [IsOpen], [CreateTime], [CreateUser]) VALUES (2, N'李四', N'1', 19, 1, 1, 1, CAST(N'2024-10-06T09:15:08.000' AS DateTime), N'1')
SET IDENTITY_INSERT [dbo].[Sys_User] OFF
ALTER TABLE [dbo].[Sys_User] ADD  DEFAULT ((0)) FOR [IsOpen]
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'使用者名稱稱' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Sys_User', @level2type=N'COLUMN',@level2name=N'UserName'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'使用者密碼' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Sys_User', @level2type=N'COLUMN',@level2name=N'Password'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'使用者年齡' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Sys_User', @level2type=N'COLUMN',@level2name=N'Age'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'使用者年齡 1:男 2:女' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Sys_User', @level2type=N'COLUMN',@level2name=N'Sex'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'部門id(表Department主鍵)' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Sys_User', @level2type=N'COLUMN',@level2name=N'DepartmentId'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'建立時間' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Sys_User', @level2type=N'COLUMN',@level2name=N'CreateTime'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'建立人員' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Sys_User', @level2type=N'COLUMN',@level2name=N'CreateUser'
GO
EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'人員表' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'Sys_User'
GO

服務層編寫介面呼叫

說明:以下這些類,都在上一期中有說道,這裡不再多說。

 /// <summary>
 /// 使用者服務介面
 /// </summary>
 public interface ISysUserService
 {
     /// <summary>
     /// 測試Autofac
     /// </summary>
     /// <returns></returns>
     string TestAutofac();

     /// <summary>
     /// 查詢所有使用者
     /// </summary>
     /// <returns></returns>
     List<SysUser> GetAllUser();
 }
/// <summary>
/// 使用者服務介面實現
/// </summary>
public class SysUserService : ISysUserService
{
    #region 構造例項化

    private readonly ISysUserRepository _sysUserRepository;

    public SysUserService(ISysUserRepository sysUserRepository)
    {
        _sysUserRepository = sysUserRepository;
    }

    #endregion

    /// <summary>
    /// 測試Autofac
    /// </summary>
    /// <returns></returns>
    public string TestAutofac()
    {
        return _sysUserRepository.TestAutofac();
    }

    /// <summary>
    /// 查詢所有使用者
    /// </summary>
    /// <returns></returns>
    public List<SysUser> GetAllUser() 
    {
        return _sysUserRepository.GetAll(BaseSqlRepository.sysUser_selectAllSql);
    }
}

在控制器(SysUserController)中新增如下介面

   /// <summary>
   /// 查詢所有使用者
   /// </summary>
   /// <returns></returns>
   [HttpGet]
   public List<SysUser> GetAllUser() 
   {
       return _userService.GetAllUser();
   }

好了,啟動專案,進行測試

可以看到,資料獲取成功,到這裡,我們使用Dapper搭建底層倉儲連線資料庫成功。

原始碼地址:https://gitee.com/yangguangchenjie/overall-auth2.0-web-api

預覽地址:http://139.155.137.144:8880/swagger/index.html

幫我Star,謝謝。

有興趣的朋友,請關注我微信公眾號吧(*^▽^*)。

關注我:一個全棧多端的寶藏博主,定時分享技術文章,不定時分享開源專案。關注我,帶你認識不一樣的程式世界

相關文章