【后端】.NET Core API框架搭建(6) --配置使用MongoDB

        

目录

1.添加包

2. 连接配置

        2.1.链接字符串

        2.2.连接类

3.仓储配置

        3.1.仓储实现

         3.2.仓储接口

4.获取配置和注册

4.1.添加配置获取方法

        4.2.注册 

5.常规使用案例

        5.1实体

        5.2.实现

        5.3.接口

        5.4.控制器


        NET Core 应用程序中使用 MongoDB 有许多好处,尤其是在处理大规模数据、需要高灵活性和扩展性的场景下。

1.添加包

        添加 MongoDB.Driver 包。

2. 连接配置

        2.1.连接字符串

        dbsettings.json文件添加 MongoDB连接配置

//MongoDB配置
"MongoDBSettings": {"MongoConnStr": "mongodb://root:密码@iP地址:Mongo端口","DatabaseName": "数据库名称"
},

        2.2.连接类

namespace Frame3_DataRepository.MongoRepository
{/// <summary>/// Mongo配置获取/// </summary>public class MongoOptions{/// <summary>/// 连接地址/// </summary>public string MongoConnStr { get; set; }/// <summary>/// 连接数据库/// </summary>public string DatabaseName { get; set; }}
}

        案例如下

3.仓储配置

        3.1.仓储实现

        为MongoDB添加仓储方便使用。

using MongoDB.Bson;
using MongoDB.Driver;
using System.Linq.Expressions;namespace Frame3_DataRepository.MongoRepository
{/// <summary>/// 泛型MongoDB仓储实现类,实现IMongoRepository<T>接口,约束T必须是class类型/// </summary>/// <typeparam name="T"></typeparam>public class MongoRepository<T> : IMongoRepository<T> where T : class{// 私有字段,存储MongoDB集合对象private readonly IMongoCollection<T> _collection;/// <summary>/// 构造函数,通过依赖注入初始化/// </summary>/// <param name="database">Mongo数据库实例</param>/// <param name="collectionName">集合名称(可选,默认为类型名称)</param>public MongoRepository(IMongoDatabase database, string collectionName = null){// 获取或创建集合:如果collectionName为null则使用类型名称作为集合名_collection = database.GetCollection<T>(collectionName ?? typeof(T).Name);}#region 基本CRUD操作/// <summary>/// 插入单个文档/// </summary>/// <param name="document">要插入的文档</param>/// <returns>受影响的行数(1表示成功,0表示失败)</returns>public async Task<int> InsertAsync(T document){try{// 异步插入单个文档await _collection.InsertOneAsync(document);return 1; // 插入单个文档总是返回1表示成功}catch{return 0; // 插入失败返回0}}/// <summary>/// 批量插入文档/// </summary>/// <param name="documents">要插入的文档集合</param>/// <returns>实际插入的文档数量</returns>public async Task<int> InsertAsync(IEnumerable<T> documents){try{// 转换为列表以避免多次枚举var docsList = documents.ToList();// 如果集合为空则直接返回0if (!docsList.Any()){return 0;}// 异步批量插入文档await _collection.InsertManyAsync(docsList);// 返回实际插入的文档数量return docsList.Count;}catch{return 0; // 插入失败返回0}}/// <summary>/// 根据ID获取文档/// </summary>/// <param name="id">文档ID字符串</param>/// <returns>找到的文档或默认值</returns>public async Task<T> GetByIdAsync(string id){try{// 构建ID过滤器(MongoDB默认使用"_id"字段)var filter = Builders<T>.Filter.Eq("_id", ObjectId.Parse(id));// 异步查找并返回第一个匹配的文档return await _collection.Find(filter).FirstOrDefaultAsync();}catch{return default; // 出错返回默认值}}/// <summary>/// 获取所有文档/// </summary>/// <returns>所有文档列表或默认值</returns>public async Task<List<T>> GetAllAsync(){try{// 使用空过滤器获取所有文档return await _collection.Find(_ => true).ToListAsync();}catch{return default; // 出错返回默认值}}/// <summary>/// 条件查询/// </summary>/// <param name="filter">LINQ表达式过滤器</param>/// <returns>匹配条件的文档集合</returns>public async Task<IEnumerable<T>> FindByConditionAsync(Expression<Func<T, bool>> filter){try{// 使用表达式过滤器查询文档return await _collection.Find(filter).ToListAsync();}catch{return default; // 出错返回默认值}}/// <summary>/// 更新单个文档/// </summary>/// <param name="filter">查询过滤器</param>/// <param name="update">更新定义</param>/// <returns>实际修改的文档数量</returns>public async Task<int> UpdateAsync(Expression<Func<T, bool>> filter, UpdateDefinition<T> update){try{// 异步更新单个文档var result = await _collection.UpdateOneAsync(filter, update);// 返回实际修改的文档数量return (int)result.ModifiedCount;}catch{return 0; // 出错返回0}}/// <summary>/// 替换整个文档/// </summary>/// <param name="filter">查询过滤器</param>/// <param name="replacement">替换文档</param>/// <returns>实际修改的文档数量</returns>public async Task<int> UpdateAsync(Expression<Func<T, bool>> filter, T replacement){try{// 异步替换整个文档var result = await _collection.ReplaceOneAsync(filter, replacement);// 返回实际修改的文档数量return (int)result.ModifiedCount;}catch{return 0; // 出错返回0}}/// <summary>/// 删除单个文档/// </summary>/// <param name="filter">查询过滤器</param>/// <returns>实际删除的文档数量</returns>public async Task<int> DeleteAsync(Expression<Func<T, bool>> filter){try{// 异步删除单个文档var result = await _collection.DeleteOneAsync(filter);// 返回实际删除的文档数量return (int)result.DeletedCount;}catch{return 0; // 出错返回0}}/// <summary>/// 根据ID删除文档/// </summary>/// <param name="id">文档ID</param>/// <returns>实际删除的文档数量</returns>public async Task<int> DeleteByIdAsync(string id){try{// 构建ID过滤器var filter = Builders<T>.Filter.Eq("_id", ObjectId.Parse(id));// 异步删除匹配的文档var result = await _collection.DeleteOneAsync(filter);// 返回实际删除的文档数量return (int)result.DeletedCount;}catch{return 0; // 出错返回0}}/// <summary>/// 批量删除文档/// </summary>/// <param name="filter">查询过滤器</param>/// <returns>实际删除的文档数量</returns>public async Task<int> DeleteManyAsync(Expression<Func<T, bool>> filter){try{// 异步删除多个文档var result = await _collection.DeleteManyAsync(filter);// 返回实际删除的文档数量return (int)result.DeletedCount;}catch{return 0; // 出错返回0}}#endregion#region 高级操作/// <summary>/// 分页查询/// </summary>/// <param name="filter">查询过滤器</param>/// <param name="pageNumber">页码</param>/// <param name="pageSize">每页大小</param>/// <param name="sort">排序定义(可选)</param>/// <returns>包含数据和总数的元组</returns>public async Task<(List<T> Data, int Total)> PaginateAsync(Expression<Func<T, bool>> filter, int pageNumber, int pageSize, SortDefinition<T> sort = null){try{// 获取匹配条件的文档总数var count = (int)await _collection.CountDocumentsAsync(filter);// 构建基础查询var query = _collection.Find(filter);// 如果提供了排序条件,则应用排序if (sort != null){query = query.Sort(sort);}// 执行分页查询:跳过前面的记录,限制返回数量var data = await query.Skip((pageNumber - 1) * pageSize).Limit(pageSize).ToListAsync();// 返回数据和总数return (data, count);}catch{return (null, 0); // 出错返回空数据和0总数}}/// <summary>/// 聚合查询/// </summary>/// <typeparam name="TResult">结果类型</typeparam>/// <param name="pipeline">聚合管道定义</param>/// <returns>聚合结果集合</returns>public async Task<IEnumerable<TResult>> AggregateAsync<TResult>(PipelineDefinition<T, TResult> pipeline){// 异步执行聚合管道并返回结果列表return await _collection.Aggregate(pipeline).ToListAsync();}/// <summary>/// 创建索引/// </summary>/// <param name="keys">索引键定义</param>/// <param name="options">索引选项(可选)</param>/// <returns>创建的索引名称</returns>public async Task<string> CreateIndexAsync(IndexKeysDefinition<T> keys, CreateIndexOptions options = null){// 异步创建索引并返回索引名称return await _collection.Indexes.CreateOneAsync(new CreateIndexModel<T>(keys, options));}/// <summary>/// 批量操作/// </summary>/// <param name="requests">批量写操作模型集合</param>/// <returns>批量操作结果</returns>public async Task<BulkWriteResult<T>> BulkWriteAsync(IEnumerable<WriteModel<T>> requests){// 异步执行批量写操作return await _collection.BulkWriteAsync(requests);}/// <summary>/// 文档计数/// </summary>/// <param name="filter">查询过滤器(可选)</param>/// <returns>匹配条件的文档数量</returns>public async Task<long> CountAsync(Expression<Func<T, bool>> filter = null){// 根据是否提供过滤器返回相应计数return filter == null? await _collection.CountDocumentsAsync(_ => true)  // 无过滤器时计算所有文档: await _collection.CountDocumentsAsync(filter);   // 有过滤器时计算匹配文档}#endregion#region 事务支持/// <summary>/// 执行事务操作/// </summary>/// <param name="actions">要在事务中执行的操作</param>public async Task ExecuteInTransactionAsync(Func<IClientSessionHandle, IMongoCollection<T>, Task> actions){// 创建会话using var session = await _collection.Database.Client.StartSessionAsync();// 开始事务session.StartTransaction();try{// 执行用户定义的操作await actions(session, _collection);// 提交事务await session.CommitTransactionAsync();}catch{// 出错时中止事务await session.AbortTransactionAsync();throw; // 重新抛出异常}}#endregion}
}

        案例如下 

         3.2.仓储接口

        方便使用仓储给所有实现加接口

using MongoDB.Driver;
using System.Linq.Expressions;namespace Frame3_DataRepository.MongoRepository
{public interface IMongoRepository<T> where T : class{/// <summary>/// 插入文档/// </summary>/// <param name="document"></param>/// <returns></returns>Task<int> InsertAsync(T document);/// <summary>/// 批量插入文档/// </summary>Task<int> InsertAsync(IEnumerable<T> documents);/// <summary>/// 根据ID获取文档/// </summary>Task<T> GetByIdAsync(string id);/// <summary>/// 获取所有文档/// </summary>Task<List<T>> GetAllAsync();/// <summary>/// 条件查询/// </summary>Task<IEnumerable<T>> FindByConditionAsync(Expression<Func<T, bool>> filter);/// <summary>/// 更新单个文档/// </summary>Task<int> UpdateAsync(Expression<Func<T, bool>> filter, UpdateDefinition<T> update);/// <summary>/// 替换整个文档/// </summary>Task<int> UpdateAsync(Expression<Func<T, bool>> filter, T replacement);/// <summary>/// 删除单个文档/// </summary>Task<int> DeleteAsync(Expression<Func<T, bool>> filter);/// <summary>/// 根据ID删除文档/// </summary>Task<int> DeleteByIdAsync(string id);/// <summary>/// 批量删除文档/// </summary>Task<int> DeleteManyAsync(Expression<Func<T, bool>> filter);/// <summary>/// 分页查询/// </summary>Task<(List<T> Data, int Total)> PaginateAsync(Expression<Func<T, bool>> filter, int pageNumber, int pageSize, SortDefinition<T> sort = null);/// <summary>/// 聚合查询/// </summary>Task<IEnumerable<TResult>> AggregateAsync<TResult>(PipelineDefinition<T, TResult> pipeline);/// <summary>/// 创建索引/// </summary>Task<string> CreateIndexAsync(IndexKeysDefinition<T> keys, CreateIndexOptions options = null);/// <summary>/// 批量操作/// </summary>Task<BulkWriteResult<T>> BulkWriteAsync(IEnumerable<WriteModel<T>> requests);/// <summary>/// 文档计数/// </summary>Task<long> CountAsync(Expression<Func<T, bool>> filter = null);/// <summary>/// 执行事务操作/// </summary>Task ExecuteInTransactionAsync(Func<IClientSessionHandle, IMongoCollection<T>, Task> actions);}
}

        案例如下

4.获取配置和注册

        获取连接字符串、注册Mongo实例和仓储

4.1.添加配置获取方法

using Microsoft.Extensions.Configuration;namespace Frame4_LibraryCore.BaseConfig
{/// <summary>/// 全局配置/// </summary>public static class Config{/// <summary>/// 从指定的 JSON 配置文件中读取配置,并反序列化为指定类型/// </summary>/// <typeparam name="T">目标配置类型(如 RedisSettings、DatabaseSettings 等)</typeparam>/// <param name="fileName">JSON 配置文件名(如 "appsettings.json")</param>/// <param name="sessions">配置节点名称(如 "RedisSettings")</param>/// <returns>返回绑定后的强类型配置对象</returns>public static T GetSetting<T>(string fileName, string sessions){//创建 ConfigurationBuilder 实例,用于构建配置var builder = new ConfigurationBuilder()//设置配置文件的基础路径为当前程序运行目录.SetBasePath(Directory.GetCurrentDirectory())//添加 JSON 文件作为配置源://- fileName: 指定要加载的 JSON 文件//- optional: false 表示文件必须存在,否则抛出异常//- reloadOnChange: true 表示文件修改时自动重新加载.AddJsonFile(fileName, optional: false, reloadOnChange: true);//构建配置对象(IConfigurationRoot)IConfigurationRoot config = builder.Build();//获取指定配置节点(sessions),并将其反序列化为类型 Tvar conn = config.GetSection(sessions).Get<T>();//返回反序列化后的配置对象return conn;}}
}

        案例如下 

 

        4.2.注册 

        添加注册方法方便程序注册

using Frame4_LibraryCore.BaseConfig;
using Microsoft.Extensions.DependencyInjection;
using MongoDB.Driver;namespace Frame3_DataRepository.MongoRepository
{/// <summary>/// MongoDB仓储相关服务/// </summary>public static class MongoExtension{/// <summary>/// 扩展方法:向IServiceCollection添加MongoDB仓储相关服务/// </summary>/// <param name="services">服务集合</param>/// <returns>配置后的服务集合</returns>public static IServiceCollection AddMongoRepository(this IServiceCollection services){// 从配置文件"dbsettings.json"的"MongoDBSettings"节点获取MongoDB配置选项var mongoOptions = Config.GetSetting<MongoOptions>("dbsettings.json", "MongoDBSettings");// 注册IMongoClient为单例服务(因为MongoClient是线程安全的,适合单例)services.AddSingleton<IMongoClient>(sp => new MongoClient(mongoOptions.MongoConnStr));// 注册IMongoDatabase为作用域服务(每个请求一个实例)services.AddScoped(sp =>{// 从服务容器获取已注册的IMongoClient实例var client = sp.GetRequiredService<IMongoClient>();// 使用配置中的数据库名称获取数据库实例return client.GetDatabase(mongoOptions.DatabaseName);});// 注册泛型仓储接口和实现(IMongoRepository<>和MongoRepository<>)services.AddScoped(typeof(IMongoRepository<>), typeof(MongoRepository<>));// 返回配置好的服务集合以支持链式调用return services;}}
}

         案例如下

        新增好注册方法后即可在  Program 或 Startup 中注册。

//注册MongoDB服务
builder.Services.AddMongoRepository();

        案例如下 

5.常规使用案例

        下面是 实体、实现、接口和控制器的使用案例

        5.1实体

using MongoDB.Bson;
using MongoDB.Bson.Serialization.Attributes;namespace Frame2_DataModel.MongoEntity.Product
{/// <summary>/// 产品表-Mongo/// </summary>public class ProductEntity{[BsonId] // 标记这是 MongoDB 的 _id 字段[BsonRepresentation(BsonType.ObjectId)] // 表示该字段使用 ObjectId 类型public string Id { get; set; }/// <summary>/// 产品名称/// </summary>public string ProductName { get; set; }/// <summary>/// 价格/// </summary>public decimal Price { get; set; }/// <summary>/// 库存/// </summary>public int Stock { get; set; }}
}

        案例如下

 

        5.2.实现

using Frame_Service.IService.Product;
using Frame1_Service.IService.Product;
using Frame2_DataModel.MongoEntity.Product;
using Frame3_DataRepository.MongoRepository;
using Frame6_LibraryUtility;namespace Frame1_Service.Service.Product
{/// <summary>/// MongoDB测试实现/// </summary>public class ProductSvr : BaseService, IProductSvr{/// <summary>/// 产品-Mongo/// </summary>private readonly IMongoRepository<ProductEntity> _productSvr;/// <summary>/// 构造函数/// </summary>public ProductSvr(IMongoRepository<ProductEntity> productSvr){_productSvr = productSvr;}#region 查询数据/// <summary>/// 获取所有产品/// </summary>/// <returns></returns>public async Task<ResultModel<List<ProductEntity>>> GetProductAll(){var result = new ResultModel<List<ProductEntity>>() { Data = null };var list = await _productSvr.GetAllAsync();result.Code = ResultCodeEnum.Success;result.Msg = "获取成功";result.Data = list;return result;}/// <summary>/// 根据Id获取产品/// </summary>/// <param name="id"></param>/// <returns></returns>public async Task<ResultModel<ProductEntity>> GetByIdProduct(string id){var result = new ResultModel<ProductEntity>() { Data = null };var list = await _productSvr.GetByIdAsync(id);result.Msg = "获取成功";result.Data = list;return result;}/// <summary>/// 获取所有产品-分页/// </summary>/// <param name="model"></param>/// <returns></returns>public async Task<ResultPageModel<List<ProductEntity>>> GetProductPageList(PageList model){var result = new ResultPageModel<List<ProductEntity>>() { Data = null };var (products, total) = await _productSvr.PaginateAsync(filter: p => true, pageNumber: model.PageIndex, pageSize: model.PageSize);result.TotalCount = total;result.PageIndex = model.PageIndex;result.PageSize = model.PageSize;result.Data = products;result.Msg = "获取成功";return result;}#endregion#region 修改数据/// <summary>/// 保存产品/// </summary>/// <param name="model"></param>/// <returns></returns>public async Task<ResultModel<int>> SaveProduct(ProductEntity model){var result = new ResultModel<int>() { Data = 0 };#region 数据校验if (model.IsEmpty()){result.Code = ResultCodeEnum.Error;result.Msg = "传参错误";return result;}#endregionint row = 0;if (model.Id.IsEmpty()){row = await _productSvr.InsertAsync(model);}else{row = await _productSvr.UpdateAsync(a => a.Id.Equals(model.Id), model);}if (row > 0){result.Code = ResultCodeEnum.Success;result.Msg = "操作成功";result.Data = row;}return result;}/// <summary>/// 根据Id删除产品/// </summary>/// <param name="id"></param>/// <returns></returns>public async Task<ResultModel<int>> RemoveProduct(string id){var result = new ResultModel<int>() { Data = 0 };int row = await _productSvr.DeleteByIdAsync(id);if (row > 0){result.Code = ResultCodeEnum.Success;result.Msg = "操作成功";result.Data = row;}return result;}#endregion}
}

        案例如下

        5.3.接口

using Frame2_DataModel.MongoEntity.Product;
using Frame6_LibraryUtility;namespace Frame1_Service.IService.Product
{/// <summary>/// MongoDB测试接口/// </summary>public interface IProductSvr{/// <summary>/// 获取所有产品/// </summary>/// <returns></returns>Task<ResultModel<List<ProductEntity>>> GetProductAll();/// <summary>/// 根据Id获取产品/// </summary>/// <param name="id"></param>/// <returns></returns>Task<ResultModel<ProductEntity>> GetByIdProduct(string id);/// <summary>/// 获取所有产品-分页/// </summary>/// <param name="model"></param>/// <returns></returns>Task<ResultPageModel<List<ProductEntity>>> GetProductPageList(PageList model);/// <summary>/// 保存产品/// </summary>/// <param name="model"></param>/// <returns></returns>Task<ResultModel<int>> SaveProduct(ProductEntity model);/// <summary>/// 根据Id删除产品/// </summary>/// <param name="id"></param>/// <returns></returns>Task<ResultModel<int>> RemoveProduct(string id);}
}

        案例如下

        5.4.控制器

using Frame1_Service.IService.Product;
using Frame2_DataModel.MongoEntity.Product;
using Frame4_LibraryCore.BaseConfig;
using Frame6_LibraryUtility;
using Microsoft.AspNetCore.Mvc;namespace DemoAPI.Controllers
{/// <summary>/// MongoDB测试控制器/// </summary>//[Authorize]// 保护整个控制器[Route("api/[controller]/[action]")]//标记路由地址规格[ApiController] // 标记该类为 API 控制器,启用一些默认的行为,如模型绑定、输入验证等[ApiExplorerSettings(GroupName = nameof(ApiVersionInfo.V1))]//设置控制器的API版本public class ProductController : BaseController{/// <summary>/// 产品/// </summary>private readonly IProductSvr _IProductSvr;/// <summary>/// 构造/// </summary>/// <param name="productSvr"></param>public ProductController(IProductSvr productSvr){_IProductSvr = productSvr;}/// <summary>/// 获取所有产品/// </summary>/// <returns></returns>[HttpGet]public async Task<ResultModel<List<ProductEntity>>> GetProductAll() => await _IProductSvr.GetProductAll();/// <summary>/// 根据Id获取产品/// </summary>/// <param name="id"></param>/// <returns></returns>[HttpGet]public async Task<ResultModel<ProductEntity>> GetByIdProduct(string id) => await _IProductSvr.GetByIdProduct(id);/// <summary>/// 获取所有产品-分页/// </summary>/// <param name="model"></param>/// <returns></returns>[HttpPost]public async Task<ResultPageModel<List<ProductEntity>>> GetProductPageList(PageList model) => await _IProductSvr.GetProductPageList(model);/// <summary>/// 保存产品/// </summary>/// <param name="model"></param>/// <returns></returns>[HttpPost]public async Task<ResultModel<int>> SaveProduct(ProductEntity model) => await _IProductSvr.SaveProduct(model);/// <summary>/// 根据Id删除产品/// </summary>/// <param name="id"></param>/// <returns></returns>[HttpGet]public async Task<ResultModel<int>> RemoveProduct(string id) => await _IProductSvr.RemoveProduct(id);}
}

        案例如下

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/89150.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/89150.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring AI快速入门

文章目录1 介绍1_大模型对比2_开发框架对比2 快速入门1_引入依赖2 配置模型3 配置客户端4 测试3 会话日志1_Advisor2 添加日志Advisor4 会话记忆1_定义会话存储方式2 配置会话记忆Advisor5 会话历史1_管理会话历史2 保存会话id3 查询会话历史6 后续1 介绍 SpringAI整合了全球&…

Windows下编译pthreads

本文记录在Windows下编译pthreads的流程。 零、环境 操作系统Windows 11VS Code1.92.1Git2.34.1MSYS2msys2-x86_64-20240507Visual StudioVisual Studio Community 2022CMake3.22.1 一、编译安装 1.1 下载 git clone https://git.code.sf.net/p/pthreads4w/code 1.2 构建…

WP Force SSL Pro – HTTPS SSL Redirect Boost Your Website‘s Trust in Minutes!

In the vast digital landscape where security and user trust are paramount, ensuring your WordPress site uses HTTPS is not just a recommendation—it’s a necessity. That’s where WP Force SSL Pro – HTTPS SSL Redirect steps in as your silent guardian, makin…

jvm--java代码对照字节码图解

java代码&#xff1a;无静态方法&#xff1b;&#xff08;对应字节码没有方法&#xff09; 任何一个类&#xff0c;至少有一个构造器&#xff0c;默认是无参构造java代码包含&#xff1a;静态方法java代码包含&#xff1a;静态方法、显示构造方法public class ClassInitTest {p…

动态规划题解_打家劫舍【LeetCode】

198. 打家劫舍 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋。每间房内都藏有一定的现金&#xff0c;影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统&#xff0c;如果两间相邻的房屋在同一晚上被小偷闯入&#xff0c;系统会自动报警。 给定一个代表每个…

电脑安装 Win10 提示无法在当前分区上安装Windows的解决办法

原因&#xff1a; win10系统均添加快速启动功能&#xff0c;预装的win10电脑默认都是UEFI引导和GPT硬盘&#xff0c;传统的引导方式为Legacy引导和MBR硬盘&#xff0c;UEFI必须跟GPT对应&#xff0c;同理Legacy必须跟MBR对应。如果BIOS开启UEFI&#xff0c;而硬盘分区表格式为M…

大端序与小端序

理解大端序&#xff08;Big-Endian&#xff09;和小端序&#xff08;Little-Endian&#xff09;的关键在于数据在内存中存储时字节的排列顺序&#xff0c;特别是在存储多字节数据类型&#xff08;如整数、浮点数&#xff09;时。以下是清晰易懂的解释&#xff1a;核心概念 假设…

PyTorch笔记5----------Autograd、nn库

1.Autograd grad和grad_fn grad&#xff1a;该tensor的梯度值&#xff0c;每次在计算backward时都需要将前一时刻的梯度归零&#xff0c;否则梯度值会一直累加grad_fn&#xff1a;叶子结点通常为None&#xff0c;只有结果节点的grad_fn才有效&#xff0c;用于只是梯度函数时哪…

Perl 格式化输出

Perl 格式化输出 引言 Perl 是一种通用、解释型、动态编程语言&#xff0c;广泛应用于文本处理、系统管理、网络编程等领域。在Perl编程中&#xff0c;格式化输出是一种常见的需求&#xff0c;它可以帮助开发者更好地展示和打印信息。本文将详细讲解Perl中格式化输出的方法&…

Python爬虫实战:研究markdown2库相关技术

一、引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上的信息量呈指数级增长。如何高效地获取和整理这些信息成为了一个重要的研究课题。网络爬虫作为一种自动获取网页内容的技术,能够按照一定的规则,自动地抓取万维网信息,为信息的收集提供了有力手段。 Markdown …

【Linux】基本指令详解(二) 输入\输出重定向、一切皆文件、认识管道、man、cp、mv、echo、cat

文章目录一、man指令二、输入/输出重定向(echo、一切皆文件&#xff09;三、cp指令四、mv指令五、cat指令六、more/less指令七、head/tail指令八、管道初见一、man指令 Linux的指令有很多参数&#xff0c;我们不可能全记住&#xff0c;可以通过查看联机手册获取帮助。 man 指令…

MVC HTML 帮助器

MVC HTML 帮助器 引言 MVC&#xff08;模型-视图-控制器&#xff09;是一种流行的软件架构模式&#xff0c;它将应用程序的逻辑分解为三个主要组件&#xff1a;模型&#xff08;Model&#xff09;、视图&#xff08;View&#xff09;和控制器&#xff08;Controller&#xff09…

linux下手工安装ollama0.9.6

1、去下载ollama的linux版的压缩包&#xff1a; 地址&#xff1a;https://github.com/ollama/ollama/releases2、上传到linux中。3、解压&#xff1a; tar zxvf ollama-linux-amd64-0.9.6.tgz -C /usr/local/4、如果仅仅是要手工执行&#xff0c;已经可以了&#xff1a; ollama…

kotlin布局交互

将 wrapContentSize() 方法链接到 Modifier 对象&#xff0c;然后传递 Alignment.Center 作为实参以将组件居中。Alignment.Center 会指定组件同时在水平和垂直方向上居中。 DiceWithButtonAndImage(modifier Modifier.fillMaxSize().wrapContentSize(Alignment.Center) )创建…

50天50个小项目 (Vue3 + Tailwindcss V4) ✨ | ToastNotification(推送通知)

&#x1f4c5; 我们继续 50 个小项目挑战&#xff01;—— ToastNotification组件 仓库地址&#xff1a;https://github.com/SunACong/50-vue-projects 项目预览地址&#xff1a;https://50-vue-projects.vercel.app/ 使用 Vue 3 的 Composition API&#xff08;<script s…

学习笔记(34):matplotlib绘制图表-房价数据分析与可视化

学习笔记(34):matplotlib绘制图表-房价数据分析与可视化分析房价分布情况&#xff0c;通过直方图、核密度估计和正态分布拟合来直观展示房价的分布特征&#xff0c;并进行统计检验。一、房价数据分析与可视化&#xff0c;代码分析1.1、导入必要的库import pandas as pd import …

前端三剑客之CSS

1. CSS 简介1) CSS 简述CSS&#xff0c;即层叠样式表&#xff08;英文全称&#xff1a;Cascading Style Sheets&#xff09;&#xff0c;是一种专门用于修饰 HTML 文档呈现样式的计算机语言。它的功能不仅限于静态美化网页&#xff0c;还能与各类脚本语言配合&#xff0c;实现对…

力扣25.7.11每日一题——无需开会的工作日

Description 这题类似合并区间&#xff0c;题意你们都能看懂吧…… Solution 这道题就需要用到合并区间的方法。 答案等于 daysdaysdays 减「有会议安排的天数」。 对左端点进行排序&#xff0c;计算有会议安排的天数&#xff0c;累加每个区间的长度&#xff0c;即为有会议…

每日一SQL 【销售分析 III】

文章目录问题案例执行顺序使用分组解决问题 案例 执行顺序 SQL 语句的执行顺序&#xff08;核心步骤&#xff09; 同一层级的select查询内部, 别名在整个 SELECT 计算完成前不生效 使用分组解决 select distinct s.product_id, Product.product_name from Sales sleft join …

轻轻松松带你进行-负载均衡LVS实战

8. LVS部署命令介绍 8.1 LVS软件相关信息 1.程序包&#xff1a;ipvsadm 2.Unit File: ipvsadm.service 3.主程序&#xff1a;/usr/sbin/ipvsadm 4.规则保存工具&#xff1a;/usr/sbin/ipvsadm-save 5.规则重载工具&#xff1a;/usr/sbin/ipvsadm-restore 6.配置文件&#xff1a…