一、环境准备(NuGet 安装)
# SqlSugar 核心
Install-Package SqlSugarCore
# Redis 驱动 (StackExchange.Redis 官方推荐)
Install-Package StackExchange.Redis
# 缓存工具包
Install-Package Microsoft.Extensions.Caching.StackExchangeRedis
二、appsettings.json 配置
{"ConnectionStrings": {// 主库(写入、更新、删除)"MasterDb": "Server=.;Database=TestDb;Uid=root;Pwd=123456;",// 从库(只读,可配置多个)"SlaveDb": "Server=.;Database=TestDb;Uid=root;Pwd=123456;",// Redis"Redis": "127.0.0.1:6379,password=,defaultDatabase=0"}
}
三、SqlSugar 读写分离配置
1. 注册 SqlSugar(Program.cs)
var builder = WebApplication.CreateBuilder(args);// 1. 注册 SqlSugar + 读写分离
builder.Services.AddSingleton<ISqlSugarClient>(provider =>
{var config = new ConnectionConfig(){// 主库ConnectionString = builder.Configuration.GetConnectionString("MasterDb"),DbType = DbType.MySql, // 根据你的数据库改:SqlServer/PostgreSQLIsAutoCloseConnection = true,// ===================== 读写分离配置 =====================SlaveConnectionConfigs = new List<SlaveConnectionConfig>(){new SlaveConnectionConfig(){ConnectionString = builder.Configuration.GetConnectionString("SlaveDb"),HitRate = 100 // 权重(多从库可分配比例)}}};return new SqlSugarClient(config);
});// 2. 注册 Redis
builder.Services.AddStackExchangeRedisCache(options =>
{options.Configuration = builder.Configuration.GetConnectionString("Redis");
});builder.Services.AddControllers();
四、读写分离使用规则(自动切换)
SqlSugar 完全自动切换主从库,你不用手动控制:
自动规则
- 查询(Select) → 自动走 从库
- 增删改(Insert/Update/Delete) → 自动走 主库
- 事务内所有操作 → 强制走 主库
基础使用示例(Service 层)
public class UserService
{private readonly ISqlSugarClient _db;public UserService(ISqlSugarClient db){_db = db;}// ========== 读:自动走从库 ==========public async Task<User> GetUserAsync(int id){return await _db.Queryable<User>().In(id).FirstAsync();}// ========== 写:自动走主库 ==========public async Task<bool> AddUserAsync(User user){return await _db.Insertable(user).ExecuteCommandAsync() > 0;}public async Task<bool> UpdateUserAsync(User user){return await _db.Updateable(user).ExecuteCommandAsync() > 0;}
}
五、Redis 缓存基础使用
结合读写分离,实现 “先查缓存 → 缓存没有再查从库 → 存入缓存”
1. 封装 Redis 帮助类
public class RedisCacheService
{private readonly IDistributedCache _cache;public RedisCacheService(IDistributedCache cache){_cache = cache;}// 获取缓存public async Task<T> GetAsync<T>(string key){var value = await _cache.GetStringAsync(key);return value == null ? default : JsonSerializer.Deserialize<T>(value);}// 设置缓存(带过期时间)public async Task SetAsync<T>(string key, T value, TimeSpan? expiry = null){expiry ??= TimeSpan.FromMinutes(10); // 默认10分钟await _cache.SetStringAsync(key, JsonSerializer.Serialize(value), new DistributedCacheEntryOptions{AbsoluteExpirationRelativeToNow = expiry});}// 删除缓存public async Task RemoveAsync(string key){await _cache.RemoveAsync(key);}
}
2. 注册 Redis 帮助类
builder.Services.AddScoped<RedisCacheService>();
六、最终:读写分离 + Redis 整合(最佳实践)
public class UserService
{private readonly ISqlSugarClient _db;private readonly RedisCacheService _cache;public UserService(ISqlSugarClient db, RedisCacheService cache){_db = db;_cache = cache;}/// <summary>/// 缓存 + 从库查询/// </summary>public async Task<User> GetUserWithCacheAsync(int userId){var cacheKey = $"user:{userId}";// 1. 先查 Redisvar user = await _cache.GetAsync<User>(cacheKey);if (user != null) return user;// 2. Redis 没有 → 查 从库user = await _db.Queryable<User>().In(userId).FirstAsync();if (user == null) return null;// 3. 存入 Redis(10分钟过期)await _cache.SetAsync(cacheKey, user);return user;}/// <summary>/// 更新数据 → 主库 + 删除缓存/// </summary>public async Task<bool> UpdateUserAsync(User user){// 走主库var result = await _db.Updateable(user).ExecuteCommandAsync() > 0;if (result){// 更新成功 → 删除旧缓存await _cache.RemoveAsync($"user:{user.Id}");}return result;}
}
七、强制指定主库 / 从库(特殊场景)
如果你需要手动控制:
// 强制走主库查询
await _db.Queryable<User>().With(SqlWith.Master).ToListAsync();// 强制走从库
await _db.Queryable<User>().With(SqlWith.Slave).ToListAsync();
