当前位置: 首页 > news >正文

从CRUD到高级功能:EF Core在.NET Core中全面应用(三)

目录

IQueryable使用

原生SQL使用

实体状态跟踪

全局查询筛选器

并发控制使用


IQueryable使用

        在EFCore中IQueryable是一个接口用于表示可查询的集合,它继承自IEnumerable但具有一些关键的区别,使得它在处理数据库查询时非常有用,普通集合的版本(IEnumerable)是在内存中过滤(客户端评估),而IQueryable版本则是把查询操作翻译成SQL语句(服务器端评估):

接下来我们开始讲解其简单的应用,如下所示是两种使用的代码,基本上都一样,唯一区别在于两种在执行查询时的行为有所不同,如下所示:

IQueryable:查询会被延迟执行并且它能将LINQ查询转换为SQL以便在数据库中执行,适合处理大规模数据。
IEnumerable:查询会立即执行适合用于内存中的数据集合但无法进行数据库优化,因此性能较差。

class Program
{static void Main(string[] args){using (MyDbContext ctx = new MyDbContext()){IEnumerable<Class> classes1 = ctx.Classes.Include(t => t.Students);IQueryable<Class> classes2 = ctx.Classes.Include(t => t.Students);foreach (var c in classes1){Console.WriteLine($"Class Name: {c.Name}");foreach (var s in c.Students){Console.WriteLine($"\tStudent Name: {s.Name}, Age: {s.Age}");}}foreach (var c in classes2){Console.WriteLine($"Class Name: {c.Name}");foreach (var s in c.Students){Console.WriteLine($"\tStudent Name: {s.Name}, Age: {s.Age}");}}}}
}

两者的区别如下所示:

特性IQueryableIEnumerable
执行时机延迟执行,查询会转化为 SQL 并在数据库中执行即时执行,查询在内存中执行
数据来源通常用于数据库查询,支持远程数据源通常用于内存中的集合
性能优化利用数据库的索引和优化进行查询数据已经在内存中,无法优化
常见用途用于数据库查询(如 Entity Framework)用于内存中的集合,如 List、Array 等

延迟执行:IQueryable支持延迟加载,执行查询的集合时只有在查询被执行时才会真正访问数据库或数据源,查询会在执行时转化为相应的SQL语句或者其他数据源的查询语言,只有在需要数据时查询才会被执行,如下所示:

// 假设 context 是一个 DbContext 对象
IQueryable<User> query = context.Users.Where(u => u.Age > 18);
// 这个查询还没有执行,只有调用 ToList() 或其他方法时,查询才会发送到数据库执行
var result = query.ToList(); // 执行查询,返回结果

IQueryable只是代表一个“可以放到数据库服务器去执行的查询”,它没有立刻执行只是可以被执行而已,对于IQueryable接口调用非终结方法的时候不会执行查询,而调用终结方法的时候则会立刻执行查询。

一个方法的返回值类型如果是IQueryable类型,那么这个方法一般就是非终结方法,否则就是终结方法:

// 终结方法:
ToArrar()、ToList()、Min()、Max()、Count()等// 非终结方法:
GroupBy()、OrderBy()、Include()、Skip()、Take()等

IQueryable代表一个对数据库中数据进行查询的一个逻辑,这个查询是一个延迟查询,我们可以调用非终结方法向IQueryable中添加查询逻辑,当执行终结方法的时候才真正生成SQL语句来执行查询,可以实现以前要靠SQL拼接实现的动态查询逻辑。

分页查询:IQueryable是用于支持延迟执行的LINQ查询的一种接口,在分页查询的实现中我们通常结合Skip()和Take()方法来控制结果集的起始位置和返回的数量,分页查询通过限制数据的加载量来提高查询效率,尤其在处理大数据集时,如下所示:

// Skip() 方法: 用于跳过前N条记录,通常用来跳过前几页的数据。
// Take() 方法: 用于返回指定数量的记录。
public IQueryable<T> GetPagedResults<T>(IQueryable<T> query, int pageNumber, int pageSize)
{return query.Skip((pageNumber - 1) * pageSize)  // 跳过前几页的记录.Take(pageSize);                  // 获取当前页的记录
}

这里我们通过分页去查询我们数据库当中的学生表,以每页2条数据为准,如下所示:

获取数据: 从数据库获取数据主要分为以下两种:

1)DataReader:分批从数据库服务器读取数据,内存占用小、DB连接占用时间长。

2)DataTable:把所有数据都一次性从数据库服务器都加载到客户端内存中,内存占用大节省DB连接。

我们可以通过insert into select多插入一些数据,然后加上Delay/Sleep的遍历IQueryable,在遍历执行的过程中停止MySQL服务器,可以验证IQueryable内部就是在调用DataReader,其优点是节省客户端内存,缺点是如果处理的慢就会长时间占用连接。

如果想IQueryable一次性加载数据到内存中,可以用IQueryable的ToArrary()、ToArrayAsync()、ToList()、ToListAsync()等方法,等ToArray()执行完毕再断服务器试一下。

原生SQL使用

尽管EF Core已经非常强大,但是仍然存在着无法被写成标准EF Core调用方法的SQL语句,少数情况下仍然需要写原生的SQL,这里有三种情况:非查询语句、实体查询、任意SQL查询,如下:

非查询语句:这里我们可以通过ExecuteSqlInterpolatedAsync进行字符串插值拼接,其会自动处理SQL参数,如下所示:

namespace Program
{class Program{static async Task Main(string[] args){string description = "test";using (MyDbContext ctx = new MyDbContext()){await ctx.Database.ExecuteSqlInterpolatedAsync($"INSERT INTO T_Class (Name, Description) SELECT Name, {description} FROM T_Students WHERE Id > 2");}}}
}

得到的结果如下所示:

字符串内插如果赋值给string变量,就是字符串拼接,字符串内插如果赋值FormattableString变量,编译器就会构造FormattableString对象,该对象会进行参数化SQL处理,一定程度上防止了SQL注入攻击,如下所示:

实体查询:如果要执行的原生SQL是一个查询语句并且查询的结果也能对应一个实体,就可以调用对应实体的DbSet的FromSqlInterpolated()方法来执行一个查询的SQL语句,同样使用字符串内插来传递参数,如下所示:

namespace Program
{class Program{static async Task Main(string[] args){string description = "%test%";using (MyDbContext ctx = new MyDbContext()){var queryable = ctx.Classes.FromSqlInterpolated(@$"select * from T_Class where Description like {description}");foreach (var item in queryable){Console.WriteLine(item.Id+" "+item.Name+" "+item.Description);}}}}
}

查询的结果如下所示:

        FromSqlInterpolated()方法的返回值是IQueryable类型的,因此我们可以在执行IQueryable之前对IQueryable进行进一步的处理,把只能用原生SQL语句写的逻辑用FromSqlInterpolated()去执行,然后把分页、分组、二次过滤、排序、Include等其他逻辑尽可能仍然使用EF Core的标准去操作实现。

局限性:SQL查询必须返回实体类型对应数据库表的所有列,结果集中的列必须与属性映射到的列名称匹配,只能单表查询而不能使用join语句进行关联查询,但是可在查询后面使用Include来进行关联数据的获取。

任意SQL查询:这里使用DbConnection来获取数据库的连接对象,而不借用EF Core生成的SQL进行查询,如下所示:

namespace Program
{class Program{static async Task Main(string[] args){using (MyDbContext ctx = new MyDbContext()){DbConnection conn = ctx.Database.GetDbConnection(); // 获取数据库连接if (conn.State != System.Data.ConnectionState.Open){await conn.OpenAsync(); // 打开数据库连接}using (DbCommand cmd = conn.CreateCommand()){cmd.CommandText = "select * from T_Class where Description like '%test%'";using (DbDataReader reader = await cmd.ExecuteReaderAsync()){while (await reader.ReadAsync()){Console.WriteLine(reader["Id"] + " " + reader["Name"] + " " + reader["Description"]);}}}}}}
}

最终得到的结果如下所示:

总结:一般Ling操作就够了尽量不用写原生SQL,非查询SQL用ExecuteSqllnterpolated(),针对实体的SQL查询用FromSqllnterpolated(),复杂SQL查询用ado.net的方式或者Dapper等

实体状态跟踪

实体状态跟踪:是指框架如何追踪实体对象在其生命周期中的状态变化,这些状态帮助EFCore确定如何与数据库进行交互,以便在保存更改时正确生成SQL查询。

EFCore使用一个叫做Change Tracker的机制来跟踪实体的状态,确保数据库中的数据与应用程序中的实体对象保持一致,其实体对象主要有以下五种状态:

已添加(Added):实体是新创建的尚未保存到数据库中,EFCore将会把这些实体作为新的记录插入到数据库中,如下:

var newStudent = new Student { Name = "John" };
dbContext.Students.Add(newStudent);  // 设置状态为 Added

未改变(Unchanged):实体的状态没有发生变化,EFCore不会对其生成任何SQL语句,实体的属性值与数据库中的数据一致,如下:

var student = dbContext.Students.Find(1);  // 假设没有更改属性
// 没有显式的修改,实体状态保持 Unchanged

已修改(Modified):实体已存在并且它的属性值发生了变化,EFCore会在保存更改时生成一个 update sql语句将这些更改同步到数据库中,如下:

var student = dbContext.Students.Find(1);
student.Name = "Jane";  // 设置状态为 Modified
dbContext.Students.Update(student);

已删除(Deleted):实体被标记为删除并且当保存更改时,EFCore会生成deleted sql语句,需要显式调用删除操作来设置实体为删除状态,如下:

var student = dbContext.Students.Find(1);
dbContext.Students.Remove(student);  // 设置状态为 Deleted

已分离(Detached):实体不再被EFCore上下文跟踪,通常是因为实体从上下文中移除或在数据库之外创建,如果试图对这些实体做更改EFCore不会追踪它们,因此不会执行任何操作,如下:

var student = dbContext.Students.Find(1);
dbContext.Entry(student).State = EntityState.Detached;  // 设置状态为 Detached

如果想查看实体状态,这里我们可以使用DbContext的Entry()方法来获得实体在EF Core中的跟踪信息对象EntityEntry,EntityEntry类的State属性代表实体的状态,通过DebugView.LongView属性可以看到实体的变化信息,如下所示:

var student = dbContext.Students.Find(1);
var entry = dbContext.Entry(student);
Console.WriteLine(entry.State);  // 输出实体的当前状态(例如 Added, Modified, Unchanged, 等)

DbContext会根据跟踪的实体的状态,在SaveChanges()的时候,根据实体状态的不同生成update、delete、insert等sql语句来把内存中实体的变化更新到数据库中。

默认情况下EFCore会追踪所有实体的状态,如果不想追踪某些实体的状态可以使用AsNoTracking方法禁用状态跟踪,这通常用于查询操作以提高性能:

var students = dbContext.Students.AsNoTracking().ToList();

如果我们确认我们的操作只会查询不会被修改、删除等,那么这里我们就可以使用AsNoTracking()方法来提升性能,降低内存占用,如下所示:

全局查询筛选器

EFCore中的全局查询筛选器是一种用于在整个应用程序中自动应用的查询条件,它允许在查询时自动对数据进行过滤,确保数据的一致性和安全性而无需在每个查询中显式添加筛选条件,常用的场景如下所示:

软删除:通过全局查询筛选器确保删除的记录在查询中不被返回,而无需显式地为每个查询添加where子句。

假设我们有一个Product实体,其中包含一个IsDeleted属性用来标记某个产品是否被删除,我们可以在OnModelCreating方法中为Product实体配置全局查询筛选器确保查询时自动排除已删除的产品,如下所示:

public class ApplicationDbContext : DbContext
{public DbSet<Product> Products { get; set; }protected override void OnModelCreating(ModelBuilder modelBuilder){// 为 Product 实体添加全局查询筛选器modelBuilder.Entity<Product>().HasQueryFilter(p => !p.IsDeleted);}
}

如果想查询已经删除的数据,并且我们也已经配置了全局忽略删掉数据的过滤器,这里我们可以在要查询删除数据的地方添加上忽略全局过滤器的函数,如下所示:

多租户:为每个租户添加自动的筛选条件,确保每个租户只访问自己的数据。

这里可以使用多个条件创建复杂的筛选器,例如如果有一个TenantId字段来支持多租户功能,可以根据租户ID创建全局筛选器,这种方式确保了在每次查询Product实体时都会自动根据当前租户的ID过滤数据,如下所示:

modelBuilder.Entity<Product>().HasQueryFilter(p => p.TenantId == currentTenantId);

并发控制使用

并发控制用于确保多个用户或多个进程对数据库进行并发访问时,不会产生数据冲突或不一致的问题,避免多个用户同时操作资源造成的并发冲突问题,例如:统计点击量。最好的解决方案就是:非数据库解决方案。如果从数据库层面来处理的话,EFCore支持如下两种主要的并发控制机制:

悲观并发控制:假设并发冲突的可能性较大,因此会通过锁定数据来防止其他用户修改正在处理的数据。在悲观并发控制中EFCore支持使用数据库的锁机制(如行级锁)来实现并发控制。

悲观并发控制一般采用行锁、表锁等排他锁对资源进行锁定,确保同时只有一个使用者操作被锁定的资源,EF Core没有封装悲观并发控制的使用,需要开发人员编写原生SQL语句来使用悲观并发控制,不同数据库的语法不一样。

这里我们通过一个占据房子书写房名的案例进行讲解,这里通过MySQL方案来实现,如下:

class House {public long Id {get; set;}public string Name {get; set;}public string Owner {get; set;}
}
// MySQL方案
select * from T_Houses Where Id = 1 for update

如果有其他的查询操作也使用for update来查询id=1的这条数据的话,那么查询就会被挂起直到针对这条数据的更新操作完成从而释放这个行锁,代码才会继续执行,如下所示:

namespace Program
{class Program{static async Task Main(string[] args){Console.WriteLine("请输出您的名字");string name = Console.ReadLine();using (MyDbContext ctx = new MyDbContext()){var houses = ctx.Houses.Single(h => h.Id == 1);if (!string.IsNullOrEmpty(houses.Owner)){if (houses.Owner == name){Console.WriteLine("恭喜你,你已经买过了");} else{Console.WriteLine($"房子已经被{houses.Owner}买走了");}return;}houses.Owner = name;Thread.Sleep(10000);Console.WriteLine("恭喜你,你已经买到了房子");ctx.SaveChanges();Console.ReadKey();}}}
}

上面代码,如果我们不进行并发控制的话,下面如果我们同时执行两个人抢房子,两者都会出现买到了房子,但是实际上房子最后还是被Hack买到了,如下

接下来我们在程序中添加事务操作,如下所示:

namespace Program
{class Program{static async Task Main(string[] args){Console.WriteLine("请输出您的名字");string name = Console.ReadLine();using (MyDbContext ctx = new MyDbContext())using (var tx = ctx.Database.BeginTransaction()) // 开启事务{Console.WriteLine(DateTime.Now+"正在为您查询房源信息");var houses = ctx.Houses.FromSqlInterpolated($"select * from T_House where Id = 1 for update").Single();Console.WriteLine(DateTime.Now+"房源信息完毕");if (!string.IsNullOrEmpty(houses.Owner)){if (houses.Owner == name){Console.WriteLine("恭喜你,你已经买过了");} else{Console.WriteLine($"房子已经被{houses.Owner}买走了");}Console.ReadKey();return;}houses.Owner = name;Thread.Sleep(10000);Console.WriteLine("恭喜你,你已经买到了房子");ctx.SaveChanges();Console.WriteLine("正在为您保存房源信息");tx.Commit(); // 提交事务Console.ReadKey();}}}
}

得到的结果如下所示,可以看到我们的并发操作以及处理好了:

总结: 悲观并发控制的使用比较简单,锁是独占排他的,如果系统并发量很大的话会严重影响性能,如果使用不当的话甚至会导致死锁,这点尤为重要,所以要根据实际情况进行选择使用。

乐观并发控制:假设并发冲突较少,因此允许多个操作同时对数据进行修改,在提交更改时EFCore会检查数据是否被其他操作修改过,如果数据已被修改当前操作会被拒绝并抛出 DbUpdateConcurrencyException异常。

举例:当update的时候如果数据库中的Owner值已经被其他操作者更新为其他值了,那么where语句的值就会被设为false,因此这个update语句影响的行数就是0,EFCore就知道发生并发冲突了,因此SaveChanges()方法就会抛出DbUpdateConcurrencyException异常,如下所示:

1)标记并发字段:在实体类或配置类中标记一个字段作为并发标记,通常是一个时间戳字段或者是一个列,EFCore使用该字段来检测数据是否在并发操作期间被修改过,如下所示:

namespace test
{internal class HouseConfig : IEntityTypeConfiguration<House>{public void Configure(EntityTypeBuilder<House> builder){builder.ToTable("T_House");builder.Property(x => x.Name).IsRequired();builder.Property(x => x.Owner).IsConcurrencyToken(); // 并发标记}}
}

2)处理并发冲突:当发生并发冲突时,EFCore会抛出DbUpdateConcurrencyException异常,可以捕获此异常并根据需求进行处理,比如:

namespace Program
{class Program{static async Task Main(string[] args){Console.WriteLine("请输出您的名字");string name = Console.ReadLine();using (MyDbContext ctx = new MyDbContext()){Console.WriteLine(DateTime.Now + "正在为您查询房源信息");var houses = ctx.Houses.Single(h => h.Id == 1);Console.WriteLine(DateTime.Now + "房源信息完毕");if (!string.IsNullOrEmpty(houses.Owner)){if (houses.Owner == name){Console.WriteLine("恭喜你,你已经买过了");}else{Console.WriteLine($"房子已经被{houses.Owner}买走了");}Console.ReadKey();return;}houses.Owner = name;Console.WriteLine("恭喜你,你已经买到了房子");try{ctx.SaveChanges();}catch (DbUpdateConcurrencyException ex){Console.WriteLine("并发访问冲突");var entry = ex.Entries.Single();string newValue = entry.GetDatabaseValues().GetValue<string>("Owner");Console.WriteLine($"房子已经被{newValue}买走了");}Console.ReadKey();}}}
}

最终呈现的效果如下所示:

相关文章:

从CRUD到高级功能:EF Core在.NET Core中全面应用(三)

目录 IQueryable使用 原生SQL使用 实体状态跟踪 全局查询筛选器 并发控制使用 IQueryable使用 在EFCore中IQueryable是一个接口用于表示可查询的集合&#xff0c;它继承自IEnumerable但具有一些关键的区别&#xff0c;使得它在处理数据库查询时非常有用&#xff0c;普通集…...

浅谈云计算22 | Kubernetes容器编排引擎

Kubernetes容器编排引擎 一、Kubernetes管理对象1.1 Kubernetes组件和架构1.2 主要管理对象类型 二、Kubernetes 服务2.1 服务的作用与原理2.2 服务类型 三、Kubernetes网络管理3.1 网络模型与目标3.2 网络组件3.2.1 kube-proxy3.2.2 网络插件 3.3 网络通信流程 四、Kubernetes…...

C 语言的void*到底是什么?

一、void* 的类型任意性 void* 是一种通用指针类型。它可以指向任意类型的数据。例如&#xff0c;它可以指向一个整数&#xff08;int&#xff09;、一个浮点数&#xff08;float&#xff09;、一个字符&#xff08;char&#xff09;或者一个结构体等。在C语言中&#xff0c;当…...

前端【3】--CSS布局,CSS实现横向布局,盒子模型

盒子分类 1、块级盒子 2、内联级盒子 3、内联块级盒子 4、弹性盒子 5、盒子内部分区 方法一&#xff1a;使用 float 普通盒子实现横向布局 方法二&#xff1a;使用 display: inline-block 内联块级元素实现横向布局 方法三&#xff1a;使用弹性盒子 flexbox&#xff0…...

JavaEE

一.web开发概述 1.服务器 解释1&#xff1a;服务器是一款软件&#xff0c;可以向其他发送请求&#xff0c;服务器会做出一个响应。可以在服务器中部署文件&#xff0c;让其他人访问。 解释2&#xff1a;也可以把运行服务器软件的计算机称为服务器 2.安装服务器 Tomcat官方…...

C语言之文本加密程序设计

&#x1f31f; 嗨&#xff0c;我是LucianaiB&#xff01; &#x1f30d; 总有人间一两风&#xff0c;填我十万八千梦。 &#x1f680; 路漫漫其修远兮&#xff0c;吾将上下而求索。 文本加密程序设计 摘要&#xff1a;本文设计了一种文本加密程序&#xff0c;旨在提高信息安…...

Spring-Data-Redis连接模式

Redis可以在各种设置中操作。每个操作模式都需要特定的配置&#xff0c;这些配置将在以下部分中进行解释。 一、Redis 单机模式 最简单的入门方法是将Redis Standalone与单个Redis服务器一起使用&#xff0c; 配置LettuceConnectionFactory或JedisConnectionFactor&#xff0…...

详细介绍下linux内核的高端地址

在32位系统中&#xff0c;内核空间通常占据1GB&#xff0c;用户空间占3GB&#xff0c;这主要是基于历史原因、内存管理需求和系统安全性考虑。 历史原因&#xff1a;早期的UNIX系统就采用了将内核空间和用户空间分离的设计&#xff0c;在32位系统设计时&#xff0c;延续了这种…...

ThinkPhp项目解决静态资源请求的跨域问题的解决思路

背景&#xff1a;我在前端使用vue语言开发的&#xff0c;请求的后端是用ThinkPhp项目开发的。我vue项目里的请求php接口&#xff0c;自带header参数的跨域问题通过网上查询到的server端配置方法已经解决了。我使用的 是中间件的配置方法&#xff1a; <?php//admin 项目 配…...

通过图形界面展现基于本地知识库构建RAG应用

1. 客户需求 快速完成概念验证(PoC)通过图形界面快速完成演示本地私有数据对比不同模型和成本&#xff0c;决定如何部署 2. 阿里云基于本地知识库构建RAG应用 参考方案&#xff1a; 百炼本地知识库方案 解决方案&#xff1a; FastAPI Gradio Llamaindex qwen-plus 主要三大…...

GCPAAS/DashBoard:完全免费的仪表盘设计,基于Vue+ElementUI+G2Plot+Echarts,开源代码,简单易用!还在等什么呢

嗨&#xff0c;大家好&#xff0c;我是小华同学&#xff0c;关注我们获得“最新、最全、最优质”开源项目和高效工作学习方法 GCPAAS/DashBoard&#xff0c;一款基于SpringBoot、MyBatisPlus、ElementUI、G2Plot、Echarts等技术栈的仪表盘设计器&#xff0c;具备仪表盘目录管理…...

深度学习笔记——循环神经网络RNN

大家好&#xff0c;这里是好评笔记&#xff0c;公主号&#xff1a;Goodnote&#xff0c;专栏文章私信限时Free。本文详细介绍面试过程中可能遇到的循环神经网络RNN知识点。 文章目录 文本特征提取的方法1. 基础方法1.1 词袋模型&#xff08;Bag of Words, BOW&#xff09;工作原…...

【Linux系统编程】—— 深度解析进程等待与终止:系统高效运行的关键

文章目录 进程创建再次认识fork()函数fork()函数返回值 写时拷贝fork常规⽤法以及调用失败的原因 进程终⽌进程终止对应的三种情况进程常⻅退出⽅法_exit函数exit函数return退出 进程等待进程等待的必要性进程等待的⽅法 进程创建 再次认识fork()函数 fork函数初识&#xff1…...

EPSANet2021笔记

来源&#xff1a; EPSANet: An Efficient Pyramid Squeeze Attention Block on Convolutional Neural Network 相关工作&#xff1a; #注意力机制 #多尺度特征表示 创新点&#xff1a; 贡献&#xff1a; 建立了长距离通道依赖关系有效获取利用不同尺度特征图的空间信息 问…...

CTTSHOW-WEB入门-信息搜集11-20

web11 1. 题目&#xff1a; 2. 解题步骤及思路&#xff1a;本题的flag已经给出&#xff0c;主要考点是考察域名的查询&#xff0c;通过查询有时候也可以得到一些有用的信息。 3. 相关知识点&#xff1a;查询域名可以使用nslookup命令使用方法如下&#xff1a;&#xff08;windo…...

2025年1月19日(理论力学动静法)

动静法&#xff08;Dynamic-Static Method&#xff09;是理论力学中常用的一种分析方法&#xff0c;用来求解多自由度系统的平衡问题&#xff0c;尤其适用于静力学分析和动力学分析之间的转化。动静法通过引入虚拟的动力学效应&#xff0c;将静力学问题转化为一个动力学问题&am…...

iOS 性能优化:实战案例分享

摘要&#xff1a; 本文将深入探讨 iOS 性能优化的重要性&#xff0c;并通过一系列实际开发案例&#xff0c;展示如何解决常见的性能问题&#xff0c;包括内存管理、CPU 性能、网络性能、UI 性能和启动性能等方面的优化&#xff0c;帮助 iOS 开发者打造更流畅、高效的应用程序。…...

基于本地消息表实现分布式事务

假设我们有一个电商系统,包含订单服务和库存服务。当用户下单时,需要在订单服务中创建订单,同时在库存服务中扣减库存。这是一个典型的分布式事务场景,我们需要保证这两个操作要么都成功,要么都失败,以保证数据的最终一致性。 项目结构: 订单服务(Order Service)库存服务(Inv…...

select函数

系统调用 select()可用于执行 I/O 多路复用操作&#xff0c;调用 select()会一直阻塞&#xff0c;直到某一个或多个文件描述符成为就绪态&#xff08;可以读或写&#xff09;。其函数原型如下所示&#xff1a; #include <sys/select.h> int select(int nfds, fd_set *re…...

自然语言处理——自注意力机制

一、文字表示方法 在自然语言处理中&#xff0c;如何用数据表示文字是基础问题。独热编码&#xff08;One-hot Encoding &#xff09;是一种简单的方法&#xff0c;例如对于 “我”“你”“他”“猫”“狗” 等字&#xff0c;会将其编码为如 “我 [1 0 0 0 0 ……]”“你 [0 …...

C语言初阶--函数

目录 1. 函数是什么&#xff1f; 2. C语言中函数的分类 2.1 库函数 2.2 自定义函数 3. 函数的参数 3.1 实际参数&#xff08;实参&#xff09; 3.2 形式参数&#xff08;形参&#xff09; 4. 函数调用 4.1 传值调用 4.2 传址调用 练习&#xff1a;写一个函数判断一个…...

探索基于机器学习的信用评分:从数据到洞察

友友们好! 我的新专栏《Python进阶》正式启动啦!这是一个专为那些渴望提升Python技能的朋友们量身打造的专栏,无论你是已经有一定基础的开发者,还是希望深入挖掘Python潜力的爱好者,这里都将是你不可错过的宝藏。 在这个专栏中,你将会找到: ● 深入解析:每一篇文章都将…...

Ubuntu 24.04 LTS 通过 docker desktop 安装 seafile 搭建个人网盘

准备 Ubuntu 24.04 LTSUbuntu 空闲硬盘挂载Ubuntu 安装 Docker Desktop [我的Ubuntu服务器折腾集](https://blog.csdn.net/jh1513/article/details/145222679。 安装 seafile 参考资料 Docker安装 Seafile OnlyOffice 并配置OnlyOffice到Seafile&#xff0c;实现在线编辑…...

【Golang 面试题】每日 3 题(三十六)

✍个人博客&#xff1a;Pandaconda-CSDN博客 &#x1f4e3;专栏地址&#xff1a;http://t.csdnimg.cn/UWz06 &#x1f4da;专栏简介&#xff1a;在这个专栏中&#xff0c;我将会分享 Golang 面试中常见的面试题给大家~ ❤️如果有收获的话&#xff0c;欢迎点赞&#x1f44d;收藏…...

Linux虚拟机安装与FinalShell使用:探索Linux世界的便捷之旅

文章目录 软件准备安装 VMware 虚拟机下载CentOS 光盘镜像文件选择适合的 CentOS 版本选择合适的镜像文件 本教程工具版本 第一部分&#xff1a;安装 Linux 虚拟机1. 启动 VMware 并创建新虚拟机2. 默认硬件兼容性设置3. 安装操作系统的设置4. 选择操作系统类型与版本5. 为虚拟…...

leetcode19-删除链表的第n结点

leetcode 19 思路 要删除倒数第n个元素&#xff0c;那么就要找到倒数第n1个元素&#xff0c;那么我们需要两个指针来记录&#xff0c;首先快指针需要先走n1步&#xff0c;然后快慢指针一起进行移动&#xff0c;直到快指针为null的时候&#xff0c;此时慢指针恰好走到倒数第n…...

多学科视角下探索开源Github、Git初步学习

​ Think 1.Github 作为现今最主流的代码托管平台、协作平台甚至是“社交平台”&#xff0c;本身是闭源的。一方面&#xff0c;它是和大多数开发者连接最紧密的开源阵地&#xff0c;另一方面&#xff0c;拥有传统“黑客精神”的人认为将用户身份绑定这样一个闭源平台上恰恰与…...

新星杯-ESP32智能硬件开发--ESP32的I/O组成-系统中断矩阵

本博文内容导读&#x1f4d5;&#x1f389;&#x1f525; ESP32开发板的中断矩阵、功能描述与实现、相关API和示例程序进行介绍 ESP32中断矩阵将任一外部中断源单独分配到每个CPU的任一外部中断上&#xff0c;提供了强大的灵活性&#xff0c;能适应不同的应用需求。 ESP32中断主…...

Android 右键后无Java class创建

Android studio 创建java class &#xff1a; 最近几个月用Android studio 开发&#xff0c;因为电脑设置了一个新的用户使用&#xff0c;原来的android studio,打开之前的正常的项目总是报一些奇奇怪怪的错误&#xff0c;就重新安装了最新的版本 问题描述 但是新的android s…...

leetcode-买卖股票问题

309. 买卖股票的最佳时机含冷冻期 - 力扣&#xff08;LeetCode&#xff09; 动态规划解题思路&#xff1a; 1、暴力递归&#xff08;难点如何定义递归函数&#xff09; 2、记忆化搜索-傻缓存法&#xff08;根据暴力递归可变参数确定缓存数组维度&#xff09; 3、严格表结构依…...

如何通过 Apache Airflow 将数据导入 Elasticsearch

作者&#xff1a;来自 Elastic Andre Luiz 了解如何通过 Apache Airflow 将数据导入 Elasticsearch。 Apache Airflow Apache Airflow 是一个旨在创建、安排&#xff08;schedule&#xff09;和监控工作流的平台。它用于编排 ETL&#xff08;Extract-Transform-Load&#xff0…...

LDPC (Low-Density Parity-Check) 码min_sum、n_0、block_length 和 rate参数

1. min_sum 1; min_sum 是与 最小和解码算法&#xff08;Min-Sum Decoding Algorithm&#xff09;相关的参数。最小和解码算法是 LDPC 码的一种常用解码方法&#xff0c;主要通过传递信号的信息在接收端进行解码。此参数表示最小和算法中的缩放因子。 在 LDPC 解码过程中&am…...

基于javaweb的SpringBoot景区旅游管理系统设计和实现(源码+文档+部署讲解)

个人名片 &#x1f525; 源码获取 | 毕设定制| 商务合作&#xff1a;《个人名片》 ⛺️心若有所向往,何惧道阻且长 文章目录 个人名片运行环境技术栈适用功能说明使用说明 运行环境 Java≥8、MySQL≥5.7 1.运行环境&#xff1a;最好是java jdk 1.8&#xff0c;我们在这个平台…...

(二)afsim第三方库编译(qt编译)

注意&#xff1a;源码编译的路径不能有中文否则报错&#xff0c;压缩包必须用官网下载的xz格式解压的才可以&#xff0c;否则sudo ./configure命令找不到 先编译openssl3.1.1软件包&#xff0c;否则编译的qt库将不支持network&#xff0c;相关库的编译(上文&#xff08;一&…...

重学SpringBoot3-Spring Retry实践

更多SpringBoot3内容请关注我的专栏&#xff1a;《SpringBoot3》 期待您的点赞??收藏评论 重学SpringBoot3-Spring Retry实践 1. 简介2. 环境准备3. 使用方式 3.1 注解方式 基础使用自定义重试策略失败恢复机制重试和失败恢复效果注意事项 3.2 编程式使用3.3 监听重试过程 监…...

极域电子教室破解(JiyuTrainer)

JiyuTrainer下载 byebye极域电脑安装包也可以使用 如果只玩单机游戏最简单的办法就是拔网线 另一种办法安装360卫士通过360卫安全卫士上网设置来进行禁用JiyuTrainer网络跟拔网线一样...

Oracle数据库传统审计怎么用

Oracle数据库传统审计怎么用 审计功能开启与关闭By Session还是By AccessWhenever Successful数据库语句审计数据库对象审计查看审计策略和记录Oracle数据库审计功能分为传统审计(Traditional Auditing)和统一审计(Unified Auditing)。统一审计是从Oracle 12c版本开始引入的…...

windows 搭建flutter环境,开发windows程序

环境安装配置&#xff1a; 下载flutter sdk https://docs.flutter.dev/get-started/install/windows 下载到本地后&#xff0c;随便找个地方解压&#xff0c;然后配置下系统环境变量 编译windows程序本地需要安装vs2019或更新的开发环境 主要就这2步安装后就可以了&#xff0…...

基于SpringBoot的健身房管理系统【源码+文档+部署讲解】

系统介绍 基于SpringBootVue实现的健身房管理系统采用前后端分离架构方式&#xff0c;系统设计了管理员、会员、员工三种角色&#xff0c;系统实现了用户登录与注册、个人中心、会员管理、员工管理、会员卡管理、会员卡类型管理、教练信息管理、解聘管理、健身项目管理、指导项…...

2.slf4j入口

文章目录 一、故事引入二、原理探究三、SLF4JServiceProvider四、总结 一、故事引入 故事要从下面这段代码说起 public class App {private static final Logger logger LoggerFactory.getLogger(App.class);public static void main( String[] args ) throws Exception {lo…...

sql_实用查询语句模版

1. 查询某个字段是否为必填项 SQL 查询模板 SELECT COLUMN_NAME,IS_NULLABLE FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME YourTableNameAND COLUMN_NAME YourColumnName;说明&#xff1a; INFORMATION_SCHEMA.COLUMNS 表包含了所有数据库中表的列信息。IS_NULLABL…...

Nginx反向代理架构介绍

Nginx反向代理架构是一种强大的服务器架构模式&#xff0c;它位于用户和原始服务器之间&#xff0c;接收用户的请求并将其转发到一个或多个后端服务器&#xff0c;然后将从后端服务器获取的响应返回给用户&#xff0c;就好像这些内容都是由代理服务器本身直接提供的一样。以下是…...

Mysql MVCC

MVCC 什么是MVCC MVCC&#xff08;多版本并发控制&#xff0c;Multi-Version Concurrency Control&#xff09; 是一种用于数据库管理系统&#xff08;DBMS&#xff09;中的并发控制机制&#xff0c;它允许多个事务同时执行而不互相阻塞&#xff0c;并通过创建数据的多个版本…...

JavaEE之CAS

上文我们认识了许许多多的锁&#xff0c;此篇我们的CAS就是从上文的锁策略开展的新概念&#xff0c;我们来一探究竟吧 1. 什么是CAS&#xff1f; CAS: 全称Compare and swap&#xff0c;字⾯意思:“比较并交换”&#xff0c;⼀个CAS涉及到以下操作&#xff1a; 我们假设内存中…...

Flink CDC 使用实践以及遇到的问题

背景 最近公司在做一些业务上的架构调整&#xff0c;有一部分是数据从mysql采集到Starrocks&#xff0c;之前的一套方法是走 debezium 到 puslar 到 starrocks,这一套下来比较需要配置很多东西&#xff0c;而且出现问题以后&#xff0c;需要修改很多配置&#xff0c;而且现阶段…...

idea上git log面板的使用

文章目录 各种颜色含义具体的文件的颜色标签颜色&#x1f3f7;️ 节点和路线 各种颜色含义 具体的文件的颜色 红色&#xff1a;表示还没有 git add 提交到暂存区绿色&#xff1a;表示已经 git add 过&#xff0c;但是从来没有 commit 过蓝色&#xff1a;表示文件有过改动 标…...

03.选择排序

一、题目思路 选择排序是一种简单直观的排序算法。它的工作原理是&#xff1a;首先在未排序序列中找到最小&#xff08;或最大&#xff09;元素&#xff0c;存放到排序序列的起始位置&#xff0c;然后&#xff0c;再从剩余未排序元素中继续寻找最小&#xff08;或最大&#xff…...

麒麟V10系统上安装Oracle

以下是在麒麟V10系统上安装Oracle数据库的详细步骤&#xff1a; 安装前准备 检查系统版本&#xff1a;使用uname -a、cat /etc/os-release等命令检查服务器是麒麟V10系统。 配置固定IP和本地yum源&#xff1a; 挂载麒麟V10的iso文件到/mnt目录&#xff0c;如mount -o loop Ky…...

PyTorch 神经协同过滤 (NCF) 推荐系统教程

目录 教程概述1. 神经协同过滤模型概述NCF 模型的主要组成部分&#xff1a; 2. 数据加载与预处理3. 定义神经协同过滤模型4. 训练模型5. 模型评估6. 推荐物品7. 完整示例8. 总结 在本教程中&#xff0c;我们将使用 PyTorch 实现一个神经协同过滤&#xff08;Neural Collaborat…...

日志收集Day001

1.ElasticSearch 作用&#xff1a;日志存储和检索 2.单点部署Elasticsearch与基础配置 rpm -ivh elasticsearch-7.17.5-x86_64.rpm 查看配置文件yy /etc/elasticsearch/elasticsearch.yml&#xff08;这里yy做了别名&#xff0c;过滤掉空行和注释行&#xff09; yy /etc/el…...