[MAUI 项目实战] 笔记App(二):数据库设计

devtools/2024/9/19 0:42:26/ 标签: 数据库, maui, xamarin, .netcore

文章目录

    • Sqlite配置
    • 创建实体
      • 笔记实体类
      • 笔记分组实体
      • 笔记片段实体
      • 笔记片段负载实体
      • 笔记片段仓库实体
      • 笔记模板(场景)实体
      • 笔记片段模板实体
      • 笔记片段模板负载实体
    • 配置EF
    • 创建映射
    • 迁移和种子数据
    • 项目地址

Sqlite配置

应用程序里使用Sqlite作为数据库,使用EntityFramworkCore作为ORM,使用CodeFirst方式用EFCore初始化Sqlite数据库文件:mato.db

在MatoProductivity.Core项目的appsettings.json中添加本地sqlite连接字符串

  "ConnectionStrings": {"Default": "Data Source=file:{0};"},...

这里文件是一个占位符,通过代码hardcode到配置文件

在MatoProductivityCoreModule.cs中,重写PreInitialize并设置Configuration.DefaultNameOrConnectionString:

public override void PreInitialize()
{LocalizationConfigurer.Configure(Configuration.Localization);Configuration.Settings.Providers.Add<CommonSettingProvider>();string documentsPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), MatoProductivityConsts.LocalizationSourceName);var configuration = AppConfigurations.Get(documentsPath, development);var connectionString = configuration.GetConnectionString(MatoProductivityConsts.ConnectionStringName);var dbName = "mato.db";string dbPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), MatoProductivityConsts.LocalizationSourceName, dbName);Configuration.DefaultNameOrConnectionString = String.Format(connectionString, dbPath);base.PreInitialize();
}

创建实体

接下来定义实体类

笔记实体类

笔记用于存储实体,在笔记列表中,每个笔记都有标题和内容,创建时间等内容。

定义于\MatoProductivity.Core\Models\Entities\Note.cs


public class Note : FullAuditedEntity<long>
{public Note(){}public Note(string name, bool isHidden, bool isRemovable){Title = name;IsHidden = isHidden;IsRemovable = isRemovable;}[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]public override long Id { get; set; }public ICollection<NoteSegment> NoteSegments { get; set; }public string Title { get; set; }public string Type { get; set; }public string Status { get; set; }public string Desc { get; set; }public string Icon { get; set; }public string Color { get; set; }public string BackgroundColor { get; set; }public string BackgroundImage { get; set; }public string PreViewContent { get; set; }public bool IsEditable { get; set; }public bool IsHidden { get; set; }public bool IsRemovable { get; set; }public bool CanSimplified { get; set; }}

笔记分组实体

定义于\MatoProductivity.Core\Models\Entities\NoteGroup.cs

public class NoteGroup : FullAuditedEntity<long>
{public NoteGroup(){}public NoteGroup(string name, bool isHidden, bool isRemovable){Title = name;IsHidden = isHidden;IsRemovable = isRemovable;}[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]public override long Id { get; set; }public string Title { get; set; }public bool IsHidden { get; set; }public bool IsRemovable { get; set; }public ICollection<Note> Notes { get; set; }
}

笔记片段实体

定义于\MatoProductivity.Core\Models\Entities\NoteSegment.cs

public class NoteSegment : FullAuditedEntity<long>, INoteSegment
{public NoteSegment(){}[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]public override long Id { get; set; }[ForeignKey(nameof(NoteId))]public Note Note { get; set; }public ICollection<NoteSegmentPayload> NoteSegmentPayloads { get; set; }public long NoteId { get; set; }public string Title { get; set; }public string Type { get; set; }public string Status { get; set; }public string Desc { get; set; }public string Icon { get; set; }public string Color { get; set; }public int Rank { get; set; }public bool IsHidden { get; set; }public bool IsRemovable { get; set; }public INoteSegmentPayload GetNoteSegmentPayload(string key){if (NoteSegmentPayloads != null){return NoteSegmentPayloads.FirstOrDefault(c => c.Key == key);}return default;}public void SetNoteSegmentPayload(INoteSegmentPayload noteSegmentPayload){if (NoteSegmentPayloads != null){var currentPayload = NoteSegmentPayloads.FirstOrDefault(c => c.Key == noteSegmentPayload.Key);if (currentPayload != null){NoteSegmentPayloads.Remove(currentPayload);}if (!this.IsTransient()){(noteSegmentPayload as NoteSegmentPayload).NoteSegmentId = this.Id;}NoteSegmentPayloads.Add((noteSegmentPayload as NoteSegmentPayload));}}public INoteSegmentPayload GetOrSetNoteSegmentPayload(string key, INoteSegmentPayload noteSegmentPayload){if (NoteSegmentPayloads != null){var currentPayload = NoteSegmentPayloads.FirstOrDefault(c => c.Key == key);if (currentPayload != null){return currentPayload;}if (noteSegmentPayload != null){if (!this.IsTransient()){(noteSegmentPayload as NoteSegmentPayload).NoteSegmentId = this.Id;}NoteSegmentPayloads.Add((noteSegmentPayload as NoteSegmentPayload));}return noteSegmentPayload;}return noteSegmentPayload;}}

笔记片段负载实体

笔记片段负载与笔记片段实体为一对多的关系,用于存储笔记片段的详细内容。

定义于\MatoProductivity.Core\Models\Entities\NoteSegmentPayload.cs

public class NoteSegmentPayload : FullAuditedEntity<long>, INoteSegmentPayload
{public NoteSegmentPayload(){}public NoteSegmentPayload(string key, object value, string valuetype = null){if (value is string){this.SetStringValue((value as string).ToString());}else if (value is byte[]){this.Value = value as byte[];}else if (value is DateTime){this.SetStringValue(((DateTime)value).ToString("yyyy-MM-dd HH:mm:ss"));}else{this.SetStringValue(value.ToString());}this.Key = key;this.ValueType = valuetype;}[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]public override long Id { get; set; }[ForeignKey(nameof(NoteSegmentId))]public NoteSegment NoteSegment { get; set; }public long NoteSegmentId { get; set; }public string Key { get; set; }public byte[] Value { get; set; }public string ValueType { get; set; }[NotMapped]public string StringValue => GetStringValue();public T GetConcreteValue<T>() where T : struct{var value = Encoding.UTF8.GetString(Value);T result = value.To<T>();return result;}public string GetStringValue(){var value = Encoding.UTF8.GetString(Value);return value;}public void SetStringValue(string value){this.Value = Encoding.UTF8.GetBytes(value);}
}

笔记片段仓库实体

用于在编辑笔记页面的添加片段菜单中,加载所有可用的片段

定义于\MatoProductivity.Core\Models\Entities\NoteSegmentStore.cs

public class NoteSegmentStore : Entity<long>
{[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]public override long Id { get; set; }public string Title { get; set; }public string Type { get; set; }public string Category { get; set; }public string Status { get; set; }public string Desc { get; set; }public string Icon { get; set; }public string Color { get; set; }public bool IsHidden { get; set; }public bool IsRemovable { get; set; }}

笔记模板(场景)实体

定义于\MatoProductivity.Core\Models\Entities\NoteTemplate.cs

public class NoteTemplate : FullAuditedEntity<long>
{public NoteTemplate(){}public NoteTemplate(string name, bool isHidden, bool isRemovable){Title = name;IsHidden = isHidden;IsRemovable = isRemovable;}[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]public override long Id { get; set; }public ICollection<NoteSegmentTemplate> NoteSegmentTemplates { get; set; }public string Title { get; set; }public string Type { get; set; }public string Status { get; set; }public string Desc { get; set; }public string Icon { get; set; }public string Color { get; set; }public string BackgroundColor { get; set; }public string BackgroundImage { get; set; }public string PreViewContent { get; set; }public bool IsEditable { get; set; }public bool IsHidden { get; set; }public bool IsRemovable { get; set; }public bool CanSimplified { get; set; }}

笔记片段模板实体

定义于\MatoProductivity.Core\Models\Entities\NoteSegmentTemplate.cs

public class NoteSegmentTemplate : FullAuditedEntity<long>, INoteSegment
{public NoteSegmentTemplate(){}[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]public override long Id { get; set; }[ForeignKey(nameof(NoteTemplateId))]public NoteTemplate NoteTemplate { get; set; }public ICollection<NoteSegmentTemplatePayload> NoteSegmentTemplatePayloads { get; set; }public long NoteTemplateId { get; set; }public string Title { get; set; }public string Type { get; set; }public string Status { get; set; }public string Desc { get; set; }public string Icon { get; set; }public string Color { get; set; }public int Rank { get; set; }public bool IsHidden { get; set; }public bool IsRemovable { get; set; }public INoteSegmentPayload GetNoteSegmentPayload(string key){if (NoteSegmentTemplatePayloads != null){return NoteSegmentTemplatePayloads.FirstOrDefault(c => c.Key == key);}return default;}public void SetNoteSegmentPayload(INoteSegmentPayload noteSegmentPayload){if (NoteSegmentTemplatePayloads != null){var currentPayload = NoteSegmentTemplatePayloads.FirstOrDefault(c => c.Key == noteSegmentPayload.Key);if (currentPayload != null){NoteSegmentTemplatePayloads.Remove(currentPayload);}if (!this.IsTransient()){(noteSegmentPayload as NoteSegmentTemplatePayload).NoteSegmentTemplateId = this.Id;}NoteSegmentTemplatePayloads.Add((noteSegmentPayload as NoteSegmentTemplatePayload));}}public INoteSegmentPayload GetOrSetNoteSegmentPayload(string key, INoteSegmentPayload noteSegmentPayload){if (NoteSegmentTemplatePayloads != null){var currentPayload = NoteSegmentTemplatePayloads.FirstOrDefault(c => c.Key == key);if (currentPayload != null){return currentPayload;}if (noteSegmentPayload != null){if (!this.IsTransient()){(noteSegmentPayload as NoteSegmentTemplatePayload).NoteSegmentTemplateId = this.Id;}NoteSegmentTemplatePayloads.Add((noteSegmentPayload as NoteSegmentTemplatePayload));}return noteSegmentPayload;}return noteSegmentPayload;}}

笔记片段模板负载实体

定义于\MatoProductivity.Core\Models\Entities\NoteSegmentTemplatePayload.cs

public class NoteSegmentTemplatePayload : FullAuditedEntity<long>, INoteSegmentPayload
{public NoteSegmentTemplatePayload(){}public NoteSegmentTemplatePayload(string key, object value, string valuetype = null){if (value is string){this.SetStringValue((value as string).ToString());}else if (value is byte[]){this.Value = value as byte[];}else if (value is DateTime){this.SetStringValue(((DateTime)value).ToString("yyyy-MM-dd HH:mm:ss"));}else{this.SetStringValue(value.ToString());}this.Key = key;this.ValueType = valuetype;}[Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]public override long Id { get; set; }[ForeignKey(nameof(NoteSegmentTemplateId))]public NoteSegmentTemplate NoteSegmentTemplate { get; set; }public long NoteSegmentTemplateId { get; set; }public string Key { get; set; }public byte[] Value { get; set; }public string ValueType { get; set; }[NotMapped]public string StringValue => GetStringValue();public T GetConcreteValue<T>() where T : struct{var value = Encoding.UTF8.GetString(Value);T result = value.To<T>();return result;}public string GetStringValue(){var value = Encoding.UTF8.GetString(Value);return value;}public void SetStringValue(string value){this.Value = Encoding.UTF8.GetBytes(value);}
}

配置EF

数据库上下文对象MatoProductivityDbContext定义如下

    public class MatoProductivityDbContext : AbpDbContext{//Add DbSet properties for your entities...public DbSet<Note> Note { get; set; }public DbSet<NoteGroup> NoteGroup { get; set; }public DbSet<NoteSegment> NoteSegment { get; set; }public DbSet<NoteSegmentStore> NoteSegmentStore { get; set; }public DbSet<NoteSegmentPayload> NoteSegmentPayload { get; set; }public DbSet<NoteTemplate> NoteTemplate { get; set; }public DbSet<NoteSegmentTemplate> NoteSegmentTemplate { get; set; }public DbSet<NoteSegmentTemplatePayload> NoteSegmentTemplatePayload { get; set; }public DbSet<Theme> Theme { get; set; }public DbSet<Setting> Setting { get; set; }public MatoProductivityDbContext(DbContextOptions<MatoProductivityDbContext> options) : base(options){}}

MatoProductivity.EntityFrameworkCore是应用程序数据库的维护和管理项目,依赖于Abp.EntityFrameworkCore。
在MatoProductivity.EntityFrameworkCore项目中csproj文件中,引用下列包

<PackageReference Include="Abp.EntityFrameworkCore" Version="7.4.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="7.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Design" Version="1.1.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.0">

在该项目MatoProductivityEntityFrameworkCoreModule.cs 中,将注册上下文对象,并在程序初始化运行迁移,此时将在设备上生成mato.db文件

public override void PostInitialize()
{Helper.WithDbContextHelper.WithDbContext<MatoProductivityDbContext>(IocManager, RunMigrate);if (!SkipDbSeed){SeedHelper.SeedHostDb(IocManager);}
}public static void RunMigrate(MatoProductivityDbContext dbContext)
{dbContext.Database.Migrate();
}

创建映射

从场景到笔记,或者说从模板到实例,我们需要映射,例如从笔记片段菜单中选择一个片段添加,那么需要从笔记片段仓库实体(NoteSegmentStore)映射到笔记片段实体(NoteSegment)或者,在编辑场景中,映射到笔记片段模板实体(NoteSegmentTemplate)。

[AutoMapTo(typeof(NoteSegment), typeof(NoteSegmentTemplate))]public class NoteSegmentStore : Entity<long>
{...
}

使用时:

var note = ObjectMapper.Map<NoteSegment>(noteSegmentStore);

ABP框架默认使用AutoMapper进行映射,所以需要配置映射关系。

Configuration.Modules.AbpAutoMapper().Configurators.Add(config =>
{IgnoreAbpProperties(config.CreateMap<NoteTemplate, Note>().ForMember(c => c.NoteSegments,options => options.MapFrom(input => input.NoteSegmentTemplates)).ForMember(c => c.Id,options => options.Ignore()));IgnoreAbpProperties(config.CreateMap<Note, NoteTemplate>().ForMember(c => c.NoteSegmentTemplates,options => options.MapFrom(input => input.NoteSegments)).ForMember(c => c.Id,options => options.Ignore()));IgnoreAbpProperties(config.CreateMap<NoteSegmentTemplate, NoteSegment>().ForMember(c => c.Note,options => options.MapFrom(input => input.NoteTemplate)).ForMember(c => c.NoteSegmentPayloads,options => options.MapFrom(input => input.NoteSegmentTemplatePayloads)).ForMember(c => c.NoteId,options => options.Ignore()).ForMember(c => c.Id,options => options.Ignore()));IgnoreAbpProperties(config.CreateMap<NoteSegmentStore, NoteSegment>().ForMember(c => c.Id,options => options.Ignore()));IgnoreAbpProperties(config.CreateMap<NoteSegment, NoteSegmentTemplate>().ForMember(c => c.NoteTemplate,options => options.MapFrom(input => input.Note)).ForMember(c => c.NoteTemplateId,options => options.Ignore()).ForMember(c => c.NoteSegmentTemplatePayloads,options => options.MapFrom(input => input.NoteSegmentPayloads)).ForMember(c => c.Id,options => options.Ignore()));IgnoreAbpProperties(config.CreateMap<NoteSegmentTemplatePayload, NoteSegmentPayload>().ForMember(c => c.NoteSegment,options => options.MapFrom(input => input.NoteSegmentTemplate)).ForMember(c => c.NoteSegmentId,options => options.Ignore()).ForMember(c => c.Id,options => options.Ignore()));IgnoreAbpProperties(config.CreateMap<NoteSegmentPayload, NoteSegmentTemplatePayload>().ForMember(c => c.NoteSegmentTemplate,options => options.MapFrom(input => input.NoteSegment)).ForMember(c => c.NoteSegmentTemplateId,options => options.Ignore()));});

迁移和种子数据

MatoProductivity.EntityFrameworkCore.Seed.SeedHelper可在程序启动时,访问数据库,并初始化种子数据。

public override void PostInitialize()
{Helper.WithDbContextHelper.WithDbContext<MatoProductivityDbContext>(IocManager, RunMigrate);if (!SkipDbSeed){SeedHelper.SeedHostDb(IocManager);}
}

它通过SkipDbSeed来决定是否跳过执行种子数据初始化。我们需要在安装完成App后第一次运行才执行种子数据初始化。

MAUI中提供了VersionTracking.Default.IsFirstLaunchEver方式获取是否是第一次在此设备上启动应用,请查看官方文档

public override async void Initialize()
{IocManager.RegisterAssemblyByConvention(typeof(MatoProductivityModule).GetAssembly());if (VersionTracking.Default.IsFirstLaunchEver){MatoProductivityEntityFrameworkCoreModule.SkipDbSeed = false;}else{MatoProductivityEntityFrameworkCoreModule.SkipDbSeed = true;}
}

在InitialDbBuilder中我们定义了大多数的业务初始数据,具体的实现方式请查阅源码。

internal void Create()
{CreateSetting("Theme", "Light");CreateSetting("DetailPageMode", "PreviewPage");CreateNoteSegmentStore("时间戳", "时间/提醒", "DateTimeSegment", "记录一个瞬时时间", FaIcons.IconClockO, "#D8292B");CreateNoteSegmentStore("计时器", "时间/提醒", "TimerSegment", "创建一个计时器,当它结束时会通知您", FaIcons.IconBell, "#D8292B");CreateNoteSegmentStore("笔记", "文本", "TextSegment", "随时用文本记录您的想法", FaIcons.IconStickyNoteO, "#E1A08B");CreateNoteSegmentStore("Todo", "文本", "TodoSegment", "记录一个Todo项目", FaIcons.IconCheckSquareO, "#E1A08B");CreateNoteSegmentStore("数值", "文本", "KeyValueSegment", "记录数值,以便统计数据", FaIcons.IconLineChart, "#E1A08B");CreateNoteSegmentStore("手绘", "文件", "ScriptSegment", "创建一个手绘", FaIcons.IconPaintBrush, "#AD9CC2");CreateNoteSegmentStore("照片/视频", "文件", "MediaSegment", "拍照或摄像", FaIcons.IconCamera, "#AD9CC2");CreateNoteSegmentStore("文档", "文件", "DocumentSegment", "从您设备中选取一个文档", FaIcons.IconFile, "#AD9CC2");CreateNoteSegmentStore("录音", "文件", "VoiceSegment", "记录一段声音", FaIcons.IconMicrophone, "#AD9CC2");CreateNoteSegmentStore("地点", "其它", "LocationSegment", "获取当前地点,或者从地图上选取一个地点", FaIcons.IconMapMarker, "#6D987C");CreateNoteSegmentStore("天气", "其它", "WeatherSegment", "获取当前天气信息", FaIcons.IconCloud, "#6D987C");CreateNoteSegmentStore("联系人", "其它", "ContactSegment", "从您设备的通讯录中选择一个联系人", FaIcons.IconUser, "#6D987C");
}

项目地址

GitHub:MatoProductivity


http://www.ppmy.cn/devtools/61353.html

相关文章

【Qt】QTcpServer/QTcpSocket通信

这里写目录标题 1.pro文件2.服务器3.客户端 1.pro文件 QT network2.服务器 h文件 #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow> #include <QTcpServer> #include <QTcpSocket>QT_BEGIN_NAMESPACE namespace Ui { class MainW…

PostgreSQL 中如何处理数据的并发读写和死锁检测与解决?

&#x1f345;关注博主&#x1f397;️ 带你畅游技术世界&#xff0c;不错过每一次成长机会&#xff01;&#x1f4da;领书&#xff1a;PostgreSQL 入门到精通.pdf 文章目录 PostgreSQL 中如何处理数据的并发读写和死锁检测与解决一、并发读写的基本概念&#xff08;一&#xf…

c++人脸识别项目,满足工业界对于人脸识别系统的高标准需求!(二)

在第一个章节时&#xff0c;我们完成了基本功能的实现&#xff0c;同时也带来了问题就是添加的人脸没有永久保存的问题。今天我们讲解决这些问题。 思路分析 要完成这些功能我们首先要知道&#xff0c;我们要保存的是什么&#xff0c;是人脸特征 关于特征值的保存&#xff0…

python运维实战-ssh工具

1. 功能描述 1.1 系统具有的功能描述 &#xff08;1&#xff09;连接服务器&#xff1a;用户可以通过系统连接到远程服务器&#xff0c;系统支持多个服务器配置&#xff0c;并且可以方便地管理这些配置。 &#xff08;2&#xff09;执行命令&#xff1a;用户可以在连接成功后…

MySQL:基础操作(增删查改)

目录 一、库的操作 创建数据库 查看数据库 显示创建语句 修改数据库 删除数据库 备份和恢复 二、表的操作 创建表 查看表结构 修改表 删除表 三、表的增删查改 新增数据 插入否则更新 插入查询的结果 查找数据 为查询结果指定别名 结果去重 where 条件 结…

3、宠物商店智能合约实战(truffle智能合约项目实战)

3、宠物商店智能合约实战&#xff08;truffle智能合约项目实战&#xff09; 1-宠物商店环境搭建、运行2-webjs与宠物逻辑实现3-领养智能合约初始化4-宠物领养实现5-更新宠物领养状态 1-宠物商店环境搭建、运行 https://www.trufflesuite.com/boxes/pet-shop 这个还是不行 或者…

layui 监听弹窗关闭并刷新父级table

记录&#xff1a;easyadmin 监听弹窗关闭并刷新父级table 场景一&#xff1a;在二级页面的table中点击编辑&#xff0c;保存后刷新二级页面的table edit: function () {ea.listen(function (data) {return data;}, function (res) {ea.msg.success(res.msg, function () {var …

PostgreSQL 中如何实现数据的批量插入和更新?

&#x1f345;关注博主&#x1f397;️ 带你畅游技术世界&#xff0c;不错过每一次成长机会&#xff01;&#x1f4da;领书&#xff1a;PostgreSQL 入门到精通.pdf 文章目录 PostgreSQL 中如何实现数据的批量插入和更新&#xff1f;一、批量插入数据1. 使用 INSERT INTO 语句结…

electron 主进程和渲染进程通信

在Electron中,主进程(main process)和渲染进程(renderer process)之间的通信是非常重要的,因为Electron应用通常会将用户界面(由Web技术如HTML, CSS, 和JavaScript构建)和原生功能(如系统对话框、文件I/O等)分开处理。主进程管理应用的生命周期和创建渲染进程,而渲染…

在 PostgreSQL 里如何处理数据的归档和清理过程中的数据完整性验证?

&#x1f345;关注博主&#x1f397;️ 带你畅游技术世界&#xff0c;不错过每一次成长机会&#xff01;&#x1f4da;领书&#xff1a;PostgreSQL 入门到精通.pdf 文章目录 在 PostgreSQL 里如何处理数据的归档和清理过程中的数据完整性验证 在 PostgreSQL 里如何处理数据的归…

Unity XR Interaction Toolkit的安装(二)

提示&#xff1a;文章有错误的地方&#xff0c;还望诸位大神不吝指教&#xff01; 文章目录 前言一、安装1.打开unity项目2.打开包管理器&#xff08;PackageManage&#xff09;3.导入Input System依赖包4.Interaction Layers unity设置总结 前言 安装前请注意&#xff1a;需要…

Kotlin泛型实化

内联函数 reified实现 1. 内联函数 内联函数中的代码会在编译的时候自动被替换到调用它的地方&#xff0c;这样的话也就不存在什么泛型擦除的问题了&#xff0c;因为代码在编译之后会直接使用实际的类型来替代内联函数中的泛型声明。 2. reified关键字 在Kotlin中&#xff0…

CentOS8无论安装更新什么都出现错误: Failed to download metadata for repo ‘AppStream‘

CentOS 已经停止维护&#xff0c;需要将镜像从 mirror.centos.org 更改为 vault.centos.org&#xff0c;依次执行以下命令即可: 1、cd /etc/yum.repos.d/ 2、sed -i s/mirrorlist/#mirrorlist/g /etc/yum.repos.d/CentOS-* 3、sed -i s|#baseurlhttp://mirror.centos.org|baseu…

视觉巡线小车——STM32+OpenMV

系列文章目录 第一章&#xff1a;视觉巡线小车——STM32OpenMV&#xff08;一&#xff09; 第二章&#xff1a;视觉巡线小车——STM32OpenMV&#xff08;二&#xff09; 第三章&#xff1a;视觉巡线小车——STM32OpenMV&#xff08;三&#xff09; 第四章&#xff1a;视觉巡…

vue 字符串格式“[a,b]“转数组

背景&#xff1a;后端返回格式为字符串格式的数组数据&#xff0c;需要转化为数组格式 let arrString "[1,2,3,4]" let arr JSON.parse(arrString) console.log(arr) //[1,2,3,4]

祈愿更多的人都有底气和勇气

今天&#xff0c;本“人民体验官”推广人民日报官方微博文化产品《你不慌&#xff0c;世界便不慌》。 截图&#xff1a;来源“人民体验官”推广平台 是呀&#xff0c;在生命的长河里&#xff0c;有惊涛拍岸&#xff0c;亦有柔风甘雨&#xff0c;你不慌&#xff0c;世界便不慌。…

Linux grep技巧 提取log中的json数据

目录 一. 前提1.1 数据准备1.2 需求1.3 分析 二. 数据提取2.1 提取所有的json数据2.2 提取子项目的全部json数据2.3 提取指定项目的json数据 一. 前提 1.1 数据准备 545-1 2024/07/20 18:20:21 [ERROR] MPX001 eventControlleraupay transactionIdA545 {"event":&q…

Langchain 对pdf,word,txt等不同文件的加载解析

项目中遇到各种数据资源想要加载近langchain构建本地知识ai系统&#xff0c;怎么加载对应的文件格式呢&#xff0c;一起研究下 引入Langchain from langchain.document_loaders import UnstructuredWordDocumentLoader,PyPDFium2Loader,DirectoryLoader,PyPDFLoader,TextLoad…

Nginx的HA高可用的搭建

1. 什么是高可用 高可用&#xff08;High Availability, HA&#xff09;是一种系统设计策略&#xff0c;旨在确保服务或应用在面对硬件故障、软件缺陷或任何其他异常情况时&#xff0c;仍能持续稳定地运行。它通过实现冗余性、故障转移、负载均衡、数据一致性、监控自动化、预防…

问题记录-Spring Security- bean httpSecurity not found

问题描述 最近使用Security的时候报了下面的错误&#xff1a; 配置如下&#xff1a; EnableWebSecurity Slf4j public class SecurityConfig {Resourceprivate CustUserService custUserService;Beanpublic AuthenticationProvider authenticationProvider() {return new A…