基于SqlSugar的开发框架循序渐进介绍(31)-- 在查询接口中实现多表联合和单表对象的统一处理
在一些复杂的业务表中间查询数据,有时候操作会比较复杂一些,不过基于SqlSugar的相关操作,处理的代码会比较简单一些,以前我在随笔《基于SqlSugar的开发框架循序渐进介绍(2)-- 基于中间表的查询处理》介绍过基于主表和中间表的联合查询,而往往实际会比这个会复杂一些。本篇随笔介绍联合多个表进行查询以及树形列表的条件展示的处理实现,系统能够给大家一些参考思路。
1、SqlSugar的开发框架的数据查询处理
在随笔《基于SqlSugar的开发框架循序渐进介绍(2)-- 基于中间表的查询处理》中,介绍过两个表的联合查询,如下所示代码所示。
/// <summary>
/// 根据用户ID获取对应的角色列表
/// </summary>
/// <param name="userID">用户ID</param>
/// <returns></returns>
private async Task<List<RoleInfo>> GetByUser(int userID)
{
var query = this.Client.Queryable<RoleInfo, User_RoleInfo>(
(t, m) => t.Id == m.Role_ID && m.User_ID == userID)
.Select(t => t); //联合条件获取对象 query = query.OrderBy(t => t.CreateTime);//排序
var list = await query.ToListAsync();//获取列表
return list;
} /// <summary>
/// 根据机构获取对应的角色列表(判断机构角色中间表)
/// </summary>
/// <param name="ouID">机构的ID</param>
/// <returns></returns>
public async Task<List<RoleInfo>> GetRolesByOu(int ouID)
{
var query = this.Client.Queryable<RoleInfo, OU_RoleInfo>(
(t, m) => t.Id == m.Role_ID && m.Ou_ID == ouID)
.Select(t => t); //联合条件获取对象 query = query.OrderBy(t => t.CreateTime);//排序
var list = await query.ToListAsync();//获取列表
return list;
}
我们对于后端的数据查询,一般都是传入一个条件对象,通过条件类的属性进行构建查询信息,如下简单的处理操作。
/// <summary>
/// 应用层服务接口实现
/// </summary>
public class CustomerService : MyCrudService<CustomerInfo, string, CustomerPagedDto>, ICustomerService
{
/// <summary>
/// 自定义条件处理
/// </summary>
/// <param name="input">查询条件Dto</param>
/// <returns></returns>
protected override ISugarQueryable<CustomerInfo> CreateFilteredQueryAsync(CustomerPagedDto input)
{
var query = base.CreateFilteredQueryAsync(input); query = query
.WhereIF(!input.ExcludeId.IsNullOrWhiteSpace(), t => t.Id != input.ExcludeId) //不包含排除ID
.WhereIF(!input.Name.IsNullOrWhiteSpace(), t => t.Name.Contains(input.Name)) //如需要精确匹配则用Equals
//年龄区间查询
.WhereIF(input.AgeStart.HasValue, s => s.Age >= input.AgeStart.Value)
.WhereIF(input.AgeEnd.HasValue, s => s.Age <= input.AgeEnd.Value) //创建日期区间查询
.WhereIF(input.CreateTimeStart.HasValue, s => s.CreateTime >= input.CreateTimeStart.Value)
.WhereIF(input.CreateTimeEnd.HasValue, s => s.CreateTime <= input.CreateTimeEnd.Value)
; return query;
}
上面的 CreateFilteredQueryAsync 方法是一个基类函数,主要是构建该业务表的一些数据查询的匹配处理,如对于复杂一些的查询条件,这个内容会增加很多,不过都是可以通过代码生成工具基于数据库表字段来进行一一对应的生成,从而避免人工繁琐的敲击代码。
如下面是基类函数的常规条件查询和计数的函数处理。
/// <summary>
/// 根据条件获取列表
/// </summary>
/// <param name="input">分页查询条件</param>
/// <returns></returns>
public virtual async Task<PagedResultDto<TEntity>> GetListAsync(TGetListInput input)
{
var query = CreateFilteredQueryAsync(input);
var totalCount = await query.CountAsync(); query = ApplySorting(query, input);
query = ApplyPaging(query, input); var list = await query.ToListAsync(); return new PagedResultDto<TEntity>(
totalCount,
list
);
} /// <summary>
/// 根据条件计算记录数量
/// </summary>
/// <param name="input">查询条件,忽略分页信息</param>
/// <returns></returns>
public virtual async Task<long> CountAsync(TGetListInput input)
{
var query = CreateFilteredQueryAsync(input); var totalCount = await query.CountAsync();
return totalCount; //返回符合条件的所有数量
}
上面的 CreateFilteredQueryAsync 方法一般会在具体的业务类中进行重写,从而实现具体条件的查询过滤。
2、对于多表的联合处理操作
而对于复杂的多表之间的联合查询处理,如果分开多个函数来实现,可能会比较麻烦,而且也不够统一,因此我们可以统一整合在CreateFilteredQueryAsync 实现。
而一些特殊的条件,我们可以在原有生成的条件分页类里面,增加更多的属性,用来在联合查询中赋值、或者获取值。如下图是我们额外增加的几个特殊的属性,用来在其他业务表中进行关联查询的字段。
由于客户分组是在另外一张表里面记录的,客户和分组之间的关联,是通过中间表的联合查询获得的。
客户和供应商也有一个中间表的关联关系,因此我们如何联合查询,根据条件,可以通过下面的代码进行联合查询获得。
if (!input.GroupId.IsNullOrWhiteSpace())
{
// 联合 CustomerGroup_CustomerInfo 表进行查询
query = this.Client.Queryable<CustomerInfo, CustomerGroup_CustomerInfo>(
(t, m) => t.Id == m.Customer_ID && m.CustomerGroup_ID == input.GroupId)
.Select(t => t).MergeTable(); //联合条件获取对象
}
if(!input.SupplierId.IsNullOrEmpty())
{
query = this.Client.Queryable<CustomerInfo, Customer_SupplierInfo>(
(t, m) => t.Id == m.Customer_ID && m.Supplier_ID == input.SupplierId)
.Select(t => t).MergeTable(); //联合条件获取对象
}
上面的代码,需要注意的是,不同表之间联合获得的结果,如果需要整合到主表进行的查询中,则需要使用 .MergeTable() 操作进行合并处理。
这种最终我们可以得到比较复杂一些的查询处理了。
/// <summary>
/// 自定义条件处理
/// </summary>
/// <param name="input">查询条件Dto</param>
/// <returns></returns>
protected override ISugarQueryable<CustomerInfo> CreateFilteredQueryAsync(CustomerPagedDto input)
{
var query = base.CreateFilteredQueryAsync(input);
if (!input.GroupId.IsNullOrWhiteSpace())
{
// 联合 CustomerGroup_CustomerInfo 表进行查询
query = this.Client.Queryable<CustomerInfo, CustomerGroup_CustomerInfo>(
(t, m) => t.Id == m.Customer_ID && m.CustomerGroup_ID == input.GroupId)
.Select(t => t).MergeTable(); //联合条件获取对象
}
if(!input.SupplierId.IsNullOrEmpty())
{
query = this.Client.Queryable<CustomerInfo, Customer_SupplierInfo>(
(t, m) => t.Id == m.Customer_ID && m.Supplier_ID == input.SupplierId)
.Select(t => t).MergeTable(); //联合条件获取对象
} //通过名称或代码查询,任一符合即可
query = query.WhereIF(!input.NameOrCode.IsNullOrWhiteSpace(), t => t.Name.Contains(input.NameOrCode) || t.SimpleName.Contains(input.NameOrCode) || t.HandNo.Contains(input.NameOrCode)); query = query
.WhereIF(!input.ExcludeId.IsNullOrWhiteSpace(), t => t.Id != input.ExcludeId) //不包含排除ID
.WhereIF(!input.HandNo.IsNullOrWhiteSpace(), t => t.HandNo.Contains(input.HandNo)) //如需要精确匹配则用Equals
.WhereIF(!input.Name.IsNullOrWhiteSpace(), t => t.Name.Contains(input.Name)) //如需要精确匹配则用Equals
.WhereIF(!input.SimpleName.IsNullOrWhiteSpace(), t => t.SimpleName.Contains(input.SimpleName)) //如需要精确匹配则用Equals
.WhereIF(!input.Province.IsNullOrWhiteSpace(), t => t.Province.Contains(input.Province)) //如需要精确匹配则用Equals
.WhereIF(!input.City.IsNullOrWhiteSpace(), t => t.City.Contains(input.City)) //如需要精确匹配则用Equals
.WhereIF(!input.District.IsNullOrWhiteSpace(), t => t.District.Contains(input.District)) //如需要精确匹配则用Equals
.WhereIF(!input.Area.IsNullOrWhiteSpace(), t => t.Area.Contains(input.Area)) //如需要精确匹配则用Equals
.WhereIF(!input.Address.IsNullOrWhiteSpace(), t => t.Address.Contains(input.Address)) //如需要精确匹配则用Equals
.WhereIF(!input.ZipCode.IsNullOrWhiteSpace(), t => t.ZipCode.Contains(input.ZipCode)) //如需要精确匹配则用Equals
.WhereIF(!input.Telephone.IsNullOrWhiteSpace(), t => t.Telephone.Contains(input.Telephone)) //如需要精确匹配则用Equals
.WhereIF(!input.Fax.IsNullOrWhiteSpace(), t => t.Fax.Contains(input.Fax)) //如需要精确匹配则用Equals
.WhereIF(!input.Contact.IsNullOrWhiteSpace(), t => t.Contact.Contains(input.Contact)) //如需要精确匹配则用Equals
.WhereIF(!input.ContactPhone.IsNullOrWhiteSpace(), t => t.ContactPhone.Contains(input.ContactPhone)) //如需要精确匹配则用Equals
.WhereIF(!input.ContactMobile.IsNullOrWhiteSpace(), t => t.ContactMobile.Contains(input.ContactMobile)) //如需要精确匹配则用Equals
.WhereIF(!input.Email.IsNullOrWhiteSpace(), t => t.Email.Contains(input.Email)) //如需要精确匹配则用Equals
.WhereIF(!input.QQ.IsNullOrWhiteSpace(), t => t.QQ.Contains(input.QQ)) //如需要精确匹配则用Equals
.WhereIF(!input.Industry.IsNullOrWhiteSpace(), t => t.Industry.Contains(input.Industry)) //如需要精确匹配则用Equals
.WhereIF(!input.BusinessScope.IsNullOrWhiteSpace(), t => t.BusinessScope.Contains(input.BusinessScope)) //如需要精确匹配则用Equals
.WhereIF(!input.Brand.IsNullOrWhiteSpace(), t => t.Brand.Contains(input.Brand)) //如需要精确匹配则用Equals
.WhereIF(!input.PrimaryClient.IsNullOrWhiteSpace(), t => t.PrimaryClient.Contains(input.PrimaryClient)) //如需要精确匹配则用Equals
.WhereIF(!input.PrimaryBusiness.IsNullOrWhiteSpace(), t => t.PrimaryBusiness.Contains(input.PrimaryBusiness)) //如需要精确匹配则用Equals
//注册资金区间查询
.WhereIF(input.RegisterCapitalStart.HasValue, s => s.RegisterCapital >= input.RegisterCapitalStart.Value)
.WhereIF(input.RegisterCapitalEnd.HasValue, s => s.RegisterCapital <= input.RegisterCapitalEnd.Value)
//营业额区间查询
.WhereIF(input.TurnOverStart.HasValue, s => s.TurnOver >= input.TurnOverStart.Value)
.WhereIF(input.TurnOverEnd.HasValue, s => s.TurnOver <= input.TurnOverEnd.Value)
.WhereIF(!input.LicenseNo.IsNullOrWhiteSpace(), t => t.LicenseNo.Contains(input.LicenseNo)) //如需要精确匹配则用Equals
.WhereIF(!input.Bank.IsNullOrWhiteSpace(), t => t.Bank.Contains(input.Bank)) //如需要精确匹配则用Equals
.WhereIF(!input.BankAccount.IsNullOrWhiteSpace(), t => t.BankAccount.Contains(input.BankAccount)) //如需要精确匹配则用Equals
.WhereIF(!input.LocalTaxNo.IsNullOrWhiteSpace(), t => t.LocalTaxNo.Contains(input.LocalTaxNo)) //如需要精确匹配则用Equals
.WhereIF(!input.NationalTaxNo.IsNullOrWhiteSpace(), t => t.NationalTaxNo.Contains(input.NationalTaxNo)) //如需要精确匹配则用Equals
.WhereIF(!input.LegalMan.IsNullOrWhiteSpace(), t => t.LegalMan.Contains(input.LegalMan)) //如需要精确匹配则用Equals
.WhereIF(!input.LegalTelephone.IsNullOrWhiteSpace(), t => t.LegalTelephone.Contains(input.LegalTelephone)) //如需要精确匹配则用Equals
.WhereIF(!input.LegalMobile.IsNullOrWhiteSpace(), t => t.LegalMobile.Contains(input.LegalMobile)) //如需要精确匹配则用Equals
.WhereIF(!input.Source.IsNullOrWhiteSpace(), t => t.Source.Contains(input.Source)) //如需要精确匹配则用Equals
.WhereIF(!input.WebSite.IsNullOrWhiteSpace(), t => t.WebSite.Contains(input.WebSite)) //如需要精确匹配则用Equals
.WhereIF(!input.CompanyPictureGUID.IsNullOrWhiteSpace(), t => t.CompanyPictureGUID.Contains(input.CompanyPictureGUID)) //如需要精确匹配则用Equals
.WhereIF(!input.CustomerType.IsNullOrWhiteSpace(), t => t.CustomerType.Contains(input.CustomerType)) //如需要精确匹配则用Equals
.WhereIF(!input.Grade.IsNullOrWhiteSpace(), t => t.Grade.Contains(input.Grade)) //如需要精确匹配则用Equals
.WhereIF(!input.CreditStatus.IsNullOrWhiteSpace(), t => t.CreditStatus.Contains(input.CreditStatus)) //如需要精确匹配则用Equals
.WhereIF(!input.Importance.IsNullOrWhiteSpace(), t => t.Importance.Contains(input.Importance)) //如需要精确匹配则用Equals
.WhereIF(input.IsPublic.HasValue, t => t.IsPublic == input.IsPublic) //如需要精确匹配则用Equals
.WhereIF(input.Satisfaction.HasValue, t => t.Satisfaction == input.Satisfaction) //如需要精确匹配则用Equals
.WhereIF(!input.Note.IsNullOrWhiteSpace(), t => t.Note.Contains(input.Note)) //如需要精确匹配则用Equals
.WhereIF(input.TransactionCount.HasValue, t => t.TransactionCount == input.TransactionCount) //如需要精确匹配则用Equals //交易金额区间查询
.WhereIF(input.TransactionTotalStart.HasValue, s => s.TransactionTotal >= input.TransactionTotalStart.Value)
.WhereIF(input.TransactionTotalEnd.HasValue, s => s.TransactionTotal <= input.TransactionTotalEnd.Value)
//首次交易时间区间查询
.WhereIF(input.TransactionFirstDayStart.HasValue, s => s.TransactionFirstDay >= input.TransactionFirstDayStart.Value)
.WhereIF(input.TransactionFirstDayEnd.HasValue, s => s.TransactionFirstDay <= input.TransactionFirstDayEnd.Value)
//最近交易时间区间查询
.WhereIF(input.TransactionLastDayStart.HasValue, s => s.TransactionLastDay >= input.TransactionLastDayStart.Value)
.WhereIF(input.TransactionLastDayEnd.HasValue, s => s.TransactionLastDay <= input.TransactionLastDayEnd.Value)
//最近联系日期区间查询
.WhereIF(input.LastContactDateStart.HasValue, s => s.LastContactDate >= input.LastContactDateStart.Value)
.WhereIF(input.LastContactDateEnd.HasValue, s => s.LastContactDate <= input.LastContactDateEnd.Value) //创建时间区间查询
.WhereIF(input.CreateTimeStart.HasValue, s => s.CreateTime >= input.CreateTimeStart.Value)
.WhereIF(input.CreateTimeEnd.HasValue, s => s.CreateTime <= input.CreateTimeEnd.Value)
//编辑时间区间查询
.WhereIF(input.EditTimeStart.HasValue, s => s.EditTime >= input.EditTimeStart.Value)
.WhereIF(input.EditTimeEnd.HasValue, s => s.EditTime <= input.EditTimeEnd.Value) .WhereIF(!input.Stage.IsNullOrWhiteSpace(), t => t.Stage.Contains(input.Stage)) //如需要精确匹配则用Equals
.WhereIF(!input.Status.IsNullOrWhiteSpace(), s => s.Status == input.Status)
.WhereIF(!input.Creator.IsNullOrWhiteSpace(), t => t.Creator.Contains(input.Creator)) //如需要精确匹配则用Equals
.WhereIF(!input.Editor.IsNullOrWhiteSpace(), t => t.Editor.Contains(input.Editor)) //如需要精确匹配则用Equals
.WhereIF(input.Deleted.HasValue, s => s.Deleted == input.Deleted)
.WhereIF(!input.Dept_ID.IsNullOrWhiteSpace(), t => t.Dept_ID.Contains(input.Dept_ID)) //如需要精确匹配则用Equals
.WhereIF(!input.Company_ID.IsNullOrWhiteSpace(), t => t.Company_ID.Contains(input.Company_ID)) //如需要精确匹配则用Equals
.WhereIF(!input.MarkColor.IsNullOrWhiteSpace(), t => t.MarkColor.Contains(input.MarkColor)) //如需要精确匹配则用Equals
.WhereIF(!input.ShareUsers.IsNullOrWhiteSpace(), t => t.ShareUsers.Contains(input.ShareUsers)) //如需要精确匹配则用Equals
; return query;
}
有了这个丰富条件的处理,我们就可以在前端进行属性赋值就可以了,简单的调用后端通用的接口查询即可。
//构建分页的条件和查询条件
pagerDto = new CustomerPagedDto(this.winGridViewPager1.PagerInfo)
{
//添加所需条件
NameOrCode = this.txtCustomerNo.Text.Trim(),
Deleted = 0
};
查询获得接口数据处理如下代码所示。
var result = await BLLFactory<ICustomerService>.Instance.GetListAsync(pagerDto);
return result;
在分页列表中展示获得的记录详细信息如下代码所示。
/// <summary>
/// 绑定列表数据
/// </summary>
private async void BindData()
{
//entity
this.winGridViewPager1.DisplayColumns = displayColumns;
this.winGridViewPager1.ColumnNameAlias = await BLLFactory<ICustomerService>.Instance.GetColumnNameAlias();//字段列显示名称转义 //获取分页数据列表
var result = await GetData(); //设置所有记录数和列表数据源
this.winGridViewPager1.PagerInfo.RecordCount = result.TotalCount; //需先于DataSource的赋值,更新分页信息
this.winGridViewPager1.DataSource = result.Items;
this.winGridViewPager1.PrintTitle = "客户信息列表";
}
3、对于多种属性、状态条件的统一处理
我在之前介绍过的CRM系统主界面中,关于客户关系信息的展示的时候,是通过一个复杂的树形列表来承载不同属性来进行快速的查询,如下界面所示。
这些树形列表的属性信息,在SqlSugar开发框架中,我们统一进行生成,首先定义一个通用的承载对象,如下类所示。
/// <summary>
/// 对CRM的业务数据进行统计的一个公共类
/// </summary>
public class CrmStaticsDto
{
/// <summary>
/// 节点显示名称
/// </summary>
public string Label { get; set; } /// <summary>
/// 属性名称
/// </summary>
public string TypeName { get; set; } /// <summary>
/// 数量
/// </summary>
public long Count { get; set; } /// <summary>
/// 业务分类
/// </summary>
public string Category { get; set; } /// <summary>
/// 记录的日期开始
/// </summary>
public DateTime? DateStart { get; set; }
/// <summary>
/// 记录的日期结束
/// </summary>
public DateTime? DateEnd { get; set; } /// <summary>
/// 创建人信息
/// </summary>
public CListItem Creator { get; set; } /// <summary>
/// 子节点集合
/// </summary>
public List<CrmStaticsDto> children { get; set; } = new List<CrmStaticsDto>();
}
这个类似一个嵌套的集合,通过children进行添加更多的子集记录。
后端提供一个获取统计信息的树形列表的方法,如下定义所示。
/// <summary>
/// 获取列表统计信息
/// </summary>
/// <returns></returns>
public async Task<List<CrmStaticsDto>> GetStatics(string compnayId)
{
................
}
但我们为它添加各种属性的时候,设置相关的节点文本、类别信息即可。
//所有记录
var allNode = new CrmStaticsDto()
{
Label = "所有记录"
};
list.Add(allNode); var propertyNode = new CrmStaticsDto()
{
Label = "客户属性分类"
};
list.Add(propertyNode); var typeName = "客户状态";
var count = await baseQuery.Clone().CountAsync();//Clone()避免进行多次查询时,可能会出现结果不正确的问题
var statusNode = new CrmStaticsDto()
{
Label = $"{typeName}({count})",
Count = count,
TypeName = typeName
};
var dict = await dictDataService.FindByDictType(typeName);
foreach (var info in dict)
{
var value = info.Value;
var subCount = baseQuery.Clone().Where(s => s.Status == value).Count();
statusNode.children.Add(new CrmStaticsDto()
{
Label = $"{info.Name}({subCount})",
Count = subCount,
Category = info.Value,
TypeName = typeName
});
}
propertyNode.children.Add(statusNode);
这样我们在前端的WInform界面中展示树形列表的时候,就会变得非常简单,通过一个递归的函数就可以添加相关的节点信息了,如下代码所示。
private async void InitTree()
{
this.treeView1.BeginUpdate();
this.treeView1.Nodes.Clear(); //获取所有的统计列表
var staticsList = await BLLFactory<ICustomerService>.Instance.GetStatics(this.SelectedCompanyID);
await AddTreeData(staticsList, null); //this.treeView1.ExpandAll();
this.treeView1.EndUpdate();
} private async Task AddTreeData(List<CrmStaticsDto> staticsList, TreeNode parentNode = null)
{
var i = 0;
if (staticsList != null)
{
foreach (var info in staticsList)
{
var node = new TreeNode(info.Label, i, i);
node.Tag = info;
node.Text = info.Label; await AddTreeData(info.children, node); if (parentNode == null)
{
this.treeView1.Nodes.Add(node); //如果是顶级处理,则treeView1节点加入
}
else
{
parentNode.Nodes.Add(node); //如果是递归的,则加到父节点上
}
}
}
}
以上就是对联合多个表进行查询以及树形列表的条件展示的处理思路,系统能够给大家一些参考思路。
基于SqlSugar的开发框架循序渐进介绍(31)-- 在查询接口中实现多表联合和单表对象的统一处理的更多相关文章
- 基于SqlSugar的开发框架循序渐进介绍(3)-- 实现代码生成工具Database2Sharp的整合开发
我喜欢在一个项目开发模式成熟的时候,使用代码生成工具Database2Sharp来配套相关的代码生成,对于我介绍的基于SqlSugar的开发框架,从整体架构确定下来后,我就着手为它们量身定做相关的代码 ...
- 基于SqlSugar的开发框架循序渐进介绍(4)-- 在数据访问基类中对GUID主键进行自动赋值处理
我们在设计数据库表的时候,往往为了方便,主键ID一般采用字符串类型或者GUID类型,这样对于数据库表记录的迁移非常方便,而且有时候可以在处理关联记录的时候,提前对应的ID值.但有时候进行数据记录插入的 ...
- 基于SqlSugar的开发框架循序渐进介绍(5)-- 在服务层使用接口注入方式实现IOC控制反转
在前面随笔,我们介绍过这个基于SqlSugar的开发框架,我们区分Interface.Modal.Service三个目录来放置不同的内容,其中Modal是SqlSugar的映射实体,Interface ...
- 基于SqlSugar的开发框架循序渐进介绍(6)-- 在基类接口中注入用户身份信息接口
在基于SqlSugar的开发框架中,我们设计了一些系统服务层的基类,在基类中会有很多涉及到相关的数据处理操作的,如果需要跟踪具体是那个用户进行操作的,那么就需要获得当前用户的身份信息,包括在Web A ...
- 基于SqlSugar的开发框架循序渐进介绍(8)-- 在基类函数封装实现用户操作日志记录
在我们对数据进行重要修改调整的时候,往往需要跟踪记录好用户操作日志.一般来说,如对重要表记录的插入.修改.删除都需要记录下来,由于用户操作日志会带来一定的额外消耗,因此我们通过配置的方式来决定记录那些 ...
- 基于SqlSugar的开发框架循序渐进介绍(12)-- 拆分页面模块内容为组件,实现分而治之的处理
在早期的随笔就介绍过,把常规页面的内容拆分为几个不同的组件,如普通的页面,包括列表查询.详细资料查看.新增资料.编辑资料.导入资料等页面场景,这些内容相对比较独立,而有一定的代码量,本篇随笔介绍基于V ...
- 基于SqlSugar的开发框架循序渐进介绍(13)-- 基于ElementPlus的上传组件进行封装,便于项目使用
在我们实际项目开发过程中,往往需要根据实际情况,对组件进行封装,以更简便的在界面代码中使用,在实际的前端应用中,适当的组件封装,可以减少很多重复的界面代码,并且能够非常简便的使用,本篇随笔介绍基于El ...
- 基于SqlSugar的开发框架循序渐进介绍(14)-- 基于Vue3+TypeScript的全局对象的注入和使用
刚完成一些前端项目的开发,腾出精力来总结一些前端开发的技术点,以及继续完善基于SqlSugar的开发框架循序渐进介绍的系列文章,本篇随笔主要介绍一下基于Vue3+TypeScript的全局对象的注入和 ...
- 基于SqlSugar的开发框架循序渐进介绍(15)-- 整合代码生成工具进行前端界面的生成
在前面随笔<基于SqlSugar的开发框架循序渐进介绍(12)-- 拆分页面模块内容为组件,实现分而治之的处理>中我们已经介绍过,对于相关的业务表的界面代码,我们已经尽可能把不同的业务逻辑 ...
- 基于SqlSugar的开发框架循序渐进介绍(17)-- 基于CSRedis实现缓存的处理
在一个应用系统的开发框架中,往往很多地方需要用到缓存的处理,有些地方是为了便于记录用户的数据,有些地方是为了提高系统的响应速度,如有时候我们在发送一个短信验证码的时候,可以在缓存中设置几分钟的过期时间 ...
随机推荐
- Ubuntu18.04二进制安装elasticsearch
1. 什么是Elasticsearch Elasticsearch 是位于 Elastic Stack 核心的分布式搜索和分析引擎.Logstash 和 Beats 有助于收集.聚合和丰富您的数据并将 ...
- v-model 和 .sync
v-model的本质是父子组件间的通讯,父组件给子组件传递一个value自定义属性和input自定义事件:子组件接收value 并触发自定义事件修改value 父组件中 <Child v-mod ...
- 一次对pool的误用导致的.net频繁gc的诊断分析
(最近有读者朋友表示,希望能加一些示意图来描述分析过程中用到的原理知识.好的,之后我会注意,谢谢这位读者) 背景 有位朋友找我,希望我能帮看一下他的一个service.从他的描述看,并没有资源方面的泄 ...
- k8s 1.24 1.25 集群使用docker作为容器
Kubernetes 1.24 1.25 集群使用docker作为容器 背景 在新版本Kubernetes环境(1.24以及以上版本)下官方不在支持docker作为容器运行时了,若要继续使用docke ...
- 五月八号java基础知识点
1.对于容器中元素进行访问时,经常需要按照某种次序对容器中的每个元素访问且仅访问 一次,这就是遍历,也称为迭代.2.遍历是指从容器中获得当前元素的后续元素.对元素的遍历有很多种:第一种就是foreac ...
- socket 到底是个啥
哈喽大家好,我是咸鱼 我相信大家在面试过程中或多或少都会被问到这样一个问题:你能解释一下什么是 socket 吗 我记得我当初的回答很是浅显:socket 也叫套接字,用来负责不同主机程序之间的网络通 ...
- 从零开始学Vue(二~三)—— Vue 实例 / 模板语法(插值、指令)
概述 vue.js作为现在笔记热门的JS框架,使用比较简单易上手,也成为很多公司首选的JS框架. 但是对于初学者可能学起来有些麻烦,所以推出<从零开始学Vue>系列博客,本系列计划推出19 ...
- 什么是BFC,BFC的作用,以及怎么触发BFC
什么是BFC: 块级格式化上下文 BFC的作用: BFC其实就是规定了网页布局的规范 1.BFC就是页面上的一个独立容器,容器里面的元素不会影响到外面的元素 解释:BFC的基本改变,最 ...
- HMS Core 6.10.0版本发布公告
分析服务 ◆ 事件分析下新增商品订阅分析报告,帮助开发者了解应用内用户付费订阅概况,评估订阅付费价值: ◆ 营销分析.用户质量.转化分析以及过滤器中,新增广告系列/广告任务通过ID进行搜索的功能,通过 ...
- Tomcat总体架构,启动流程与处理请求流程
系列文章目录和关于我 参考书籍<Tomcat架构解析> 一丶Tomcat总体架构 本文沿袭<Tomcat架构解析>中启发式的方式来总结Tomcat总体架构 1 Server S ...