深入解析 SqlSugar 与泛型封装:实现通用数据访问层

在现代软件开发中,ORM(对象关系映射)框架的使用已经成为不可或缺的部分,SqlSugar 是一款非常流行且强大的 ORM框架。它不仅提供了简单易用的数据库操作,还具备了高效的性能和灵活的配置方式。为了进一步提升数据库操作的灵活性和复用性,结合 泛型 进行封装是一种非常有效的方式。在本文中,我们将结合 SqlSugar 和泛型,深入探讨如何通过封装来简化数据库操作,并实现一个通用的数据访问层。


1. 安装与配置 SqlSugar

首先,我们需要安装 SqlSugar 库并进行基本配置。SqlSugar 支持多种数据库类型,包括 SQL Server、MySQL、SQLite 等。我们可以通过 NuGet 来安装 SqlSugar。

安装 SqlSugar

Visual Studio 中使用 NuGet 包管理器控制台执行以下命令:

复制代码
Install-Package SqlSugar

或者通过 .NET CLI 安装:

复制代码
dotnet add package SqlSugar

安装完成后,我们需要配置数据库连接和创建 SqlSugarClient 实例:

复制代码
using SqlSugar;

public class SqlSugarHelper
{
    private static SqlSugarClient db;

    static SqlSugarHelper()
    {
        db = new SqlSugarClient(new ConnectionConfig()
        {
            // 数据库连接字符串
            ConnectionString = "Server=localhost;Database=TestDB;User Id=sa;Password=12345;",
            DbType = DbType.SqlServer, // 选择数据库类型
            IsAutoCloseConnection = true, // 自动关闭连接
            InitKeyType = InitKeyType.Attribute // 使用属性标记主键
        });
    }

    public static SqlSugarClient GetInstance()
    {
        return db;
    }
}

此时,我们已完成基础配置,可以开始进行数据库操作。


2. 泛型封装的基本思想

在实际开发中,经常需要对多个数据表进行类似的增、删、改、查操作。为了避免重复代码并提高代码的复用性,我们可以通过 泛型 将这些操作封装成一个通用的类,从而支持对不同实体类的操作。

通过创建一个 Repository(仓储)类来封装所有基本的数据库操作,我们可以在需要时,快速实例化一个泛型仓储类,进行统一的数据操作。


3. 封装数据库操作

3.1 泛型仓储类的实现

我们首先实现一个通用的 Repository 类,利用泛型来处理所有基本的数据库操作,包括查询、插入、更新和删除。这样,无论操作哪个实体类,我们只需要实例化一次仓储类即可。

复制代码
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;

public class Repository<T> where T : class, new()
{
    private readonly SqlSugarClient db;

    public Repository(SqlSugarClient db)
    {
        this.db = db;
    }

    #region 查询操作

    // 根据ID查询单个数据
    public T GetById(int id)
    {
        return db.Queryable<T>().InSingle(id);
    }

    // 根据条件查询数据列表
    public List<T> GetList(Func<T, bool> whereExpression)
    {
        return db.Queryable<T>().Where(whereExpression).ToList();
    }

    // 查询所有数据
    public List<T> GetAll()
    {
        return db.Queryable<T>().ToList();
    }

    #endregion

    #region 插入操作

    // 插入一条数据
    public int Insert(T entity)
    {
        return db.Insertable(entity).ExecuteCommand();
    }

    // 批量插入数据
    public int InsertRange(List<T> entities)
    {
        return db.Insertable(entities).ExecuteCommand();
    }

    #endregion

    #region 更新操作

    // 更新一条数据
    public int Update(T entity)
    {
        return db.Updateable(entity).ExecuteCommand();
    }

    // 根据条件更新数据
    public int Update(Func<T, bool> whereExpression, object updateColumns)
    {
        return db.Updateable<T>().SetColumns(updateColumns).Where(whereExpression).ExecuteCommand();
    }

    #endregion

    #region 删除操作

    // 删除一条数据
    public int Delete(int id)
    {
        return db.Deleteable<T>().In(id).ExecuteCommand();
    }

    // 根据条件删除数据
    public int Delete(Func<T, bool> whereExpression)
    {
        return db.Deleteable<T>().Where(whereExpression).ExecuteCommand();
    }

    // 批量删除数据
    public int DeleteRange(List<int> ids)
    {
        return db.Deleteable<T>().In(ids).ExecuteCommand();
    }

    #endregion
}

3.2 封装分页查询功能

为了进一步提升通用性,我们可以在仓储类中增加 分页查询 功能。SqlSugar 提供了一个方便的分页方法 ToPageList,结合泛型,我们可以封装一个通用的分页查询方法。

复制代码
#region 分页查询

// 分页查询
public List<T> GetPageList(int pageIndex, int pageSize, Func<T, bool> whereExpression, out int totalCount)
{
    return db.Queryable<T>()
             .Where(whereExpression)
             .ToPageList(pageIndex, pageSize, out totalCount);
}

#endregion

4. 使用泛型仓储类

接下来,我们通过实例化 Repository<T> 来对具体的实体类进行操作。例如,我们有一个 User 实体类:

复制代码
public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
}

4.1 在 Service 层使用泛型仓储类

我们可以在业务层 (Service) 中使用 Repository<User> 来封装对 User 表的操作。

复制代码
public class UserService
{
    private readonly Repository<User> userRepository;

    public UserService(SqlSugarClient db)
    {
        // 初始化泛型仓储类
        userRepository = new Repository<User>(db);
    }

    // 获取所有用户
    public List<User> GetAllUsers()
    {
        return userRepository.GetAll();
    }

    // 根据ID获取用户
    public User GetUserById(int id)
    {
        return userRepository.GetById(id);
    }

    // 根据名称查询用户
    public List<User> GetUsersByName(string name)
    {
        return userRepository.GetList(u => u.Name == name);
    }

    // 插入用户
    public int AddUser(User user)
    {
        return userRepository.Insert(user);
    }

    // 更新用户
    public int UpdateUser(User user)
    {
        return userRepository.Update(user);
    }

    // 删除用户
    public int DeleteUser(int id)
    {
        return userRepository.Delete(id);
    }

    // 批量删除用户
    public int DeleteUsers(List<int> ids)
    {
        return userRepository.DeleteRange(ids);
    }
}

4.2 在 Main 方法中调用

复制代码
class Program
{
    static void Main(string[] args)
    {
        // 配置数据库连接
        var db = new SqlSugarClient(new ConnectionConfig()
        {
            ConnectionString = "Server=localhost;Database=TestDB;User Id=sa;Password=12345;",
            DbType = DbType.SqlServer,
            IsAutoCloseConnection = true
        });

        // 使用 UserService 操作 User 表
        var userService = new UserService(db);

        // 添加新用户
        var newUser = new User { Name = "John", Age = 25 };
        userService.AddUser(newUser);

        // 查询所有用户
        var users = userService.GetAllUsers();
        Console.WriteLine($"共查询到 {users.Count} 个用户");

        // 根据 ID 查询用户
        var user = userService.GetUserById(1);
        Console.WriteLine($"用户 {user.Name} 的年龄是 {user.Age}");

        // 删除用户
        userService.DeleteUser(2);
    }
}

5. 总结

通过结合 SqlSugar泛型 ,我们能够实现一个简洁、通用且高效的数据库操作层。在这篇文章中,我们通过封装一个 Repository 类,将常见的数据库操作(增、删、改、查)以及分页查询功能都进行了通用化封装。这样,我们可以轻松地处理不同实体类的数据操作,减少了重复代码,提高了代码的可复用性和可维护性。

泛型的使用不仅让我们能够在不同实体类之间共享同一套操作方法,还使得我们的代码更加简洁、易于扩展。在实际项目中,结合 SqlSugar 和泛型封装,是一种非常有效的解决方案,特别是对于需要操作大量数据表的项目,能够大幅提升开发效率。

希望本文的示例和思路能够帮助你在项目中高效地实现数据库操作和封装。如果你有任何问题或想进一步探讨的内容,欢迎随时提问!

相关推荐
Elastic 中国社区官方博客几秒前
Elasticsearch:Workflows 介绍 - 9.3
大数据·数据库·人工智能·elasticsearch·ai·全文检索
仍然.4 分钟前
MYSQL--- 聚合查询,分组查询和联合查询
数据库
李斯啦果5 分钟前
【PTA】L1-019 谁先倒
数据结构·算法
一 乐9 分钟前
校园二手交易|基于springboot + vue校园二手交易系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端
啦啦啦_999911 分钟前
Redis-0-业务逻辑
数据库·redis·缓存
自不量力的A同学43 分钟前
Redisson 4.2.0 发布,官方推荐的 Redis 客户端
数据库·redis·缓存
Exquisite.1 小时前
Mysql
数据库·mysql
全栈前端老曹1 小时前
【MongoDB】深入研究副本集与高可用性——Replica Set 架构、故障转移、读写分离
前端·javascript·数据库·mongodb·架构·nosql·副本集
R1nG8631 小时前
CANN资源泄漏检测工具源码深度解读 实战设备内存泄漏排查
数据库·算法·cann
阿钱真强道1 小时前
12 JetLinks MQTT直连设备事件上报实战(继电器场景)
linux·服务器·网络·数据库·网络协议