-之动态查询,查询逻辑封装复用

基于领域驱动设计(DDD)超轻量级快速开发架构详细介绍请看

https://www.cnblogs.com/neozhu/p/13174234.html

需求

  1. 配合EasyUI datagird filter实现多字段(任意字段)的筛选
  2. 根据业务需求筛选特定的状态或条件,如:查看结案的订单,最近30天的订单,查看属于我的订单.等等,这些逻辑是固定也是可以被重用,但又不想每次写相同的条件,那么下面我会给我的解决方案.

需求1只是一个偷懒的实现方式,因为datagrid自带这个功能,但又不想根据具体的需求来画查询条件,如果需求必须要再datagrid上面做一块查询条件的输入那目前只能在前端自己手工添加,在组织后传入后台,暂时不在这里讨论

需求2可能不太好解释,看完代码就自然理解为什么要这么做了,这么做的好处有哪些

具体实现的方式

默认情况下 datagrid 有几列就可以对这几列进行筛选,对于日期型的字段会采用between,选择2个时间之间进行筛选,数字类型会提供大于小于等符号选择,可以自行尝试,其原理是datagrid 会根据datagrid 头部输入的值生成一个Json字符串发送后台请求数据

JSON:格式

filterRules: [
{field:field,op:op,value:value},
{field:field,op:op,value:value},
] 
  • 通常的做法是一个一个判断加条件

 var filters = JsonConvert.DeserializeObject<IEnumerable<filterRule>>(filterRules);
foreach (var rule in filters)
{
if (rule.field == "Id" && !string.IsNullOrEmpty(rule.value) && rule.value.IsInt())
{
var val = Convert.ToInt32(rule.value);
switch (rule.op)
{
case "equal":
this.And(x => x.Id == val);
break;
case "notequal":
this.And(x => x.Id != val);
break;
case "less":
this.And(x => x.Id < val);
break;
case "lessorequal":
this.And(x => x.Id <= val);
break;
case "greater":
this.And(x => x.Id > val);
break;
case "greaterorequal":
this.And(x => x.Id >= val);
break;
default:
this.And(x => x.Id == val);
break;
}
}
if (rule.field == "Name" && !string.IsNullOrEmpty(rule.value))
{
this.And(x => x.Name.Contains(rule.value));
}
if (rule.field == "Code" && !string.IsNullOrEmpty(rule.value))
{
this.And(x => x.Code.Contains(rule.value));
} if (rule.field == "Address" && !string.IsNullOrEmpty(rule.value))
{
this.And(x => x.Address.Contains(rule.value));
} if (rule.field == "Contect" && !string.IsNullOrEmpty(rule.value))
{
this.And(x => x.Contect.Contains(rule.value));
} if (rule.field == "PhoneNumber" && !string.IsNullOrEmpty(rule.value))
{
this.And(x => x.PhoneNumber.Contains(rule.value));
} if (rule.field == "RegisterDate" && !string.IsNullOrEmpty(rule.value))
{
if (rule.op == "between")
{
var datearray = rule.value.Split(new char[] { '-' });
var start = Convert.ToDateTime(datearray[]);
var end = Convert.ToDateTime(datearray[]); this.And(x => SqlFunctions.DateDiff("d", start, x.RegisterDate) >= );
this.And(x => SqlFunctions.DateDiff("d", end, x.RegisterDate) <= );
}
}
if (rule.field == "CreatedDate" && !string.IsNullOrEmpty(rule.value))
{
if (rule.op == "between")
{
var datearray = rule.value.Split(new char[] { '-' });
var start = Convert.ToDateTime(datearray[]);
var end = Convert.ToDateTime(datearray[]); this.And(x => SqlFunctions.DateDiff("d", start, x.CreatedDate) >= );
this.And(x => SqlFunctions.DateDiff("d", end, x.CreatedDate) <= );
}
} if (rule.field == "CreatedBy" && !string.IsNullOrEmpty(rule.value))
{
this.And(x => x.CreatedBy.Contains(rule.value));
} if (rule.field == "LastModifiedDate" && !string.IsNullOrEmpty(rule.value))
{
if (rule.op == "between")
{
var datearray = rule.value.Split(new char[] { '-' });
var start = Convert.ToDateTime(datearray[]);
var end = Convert.ToDateTime(datearray[]); this.And(x => SqlFunctions.DateDiff("d", start, x.LastModifiedDate) >= );
this.And(x => SqlFunctions.DateDiff("d", end, x.LastModifiedDate) <= );
}
} if (rule.field == "LastModifiedBy" && !string.IsNullOrEmpty(rule.value))
{
this.And(x => x.LastModifiedBy.Contains(rule.value));
} }
  • 新的做法是动态根据field,op,value生成一个linq 表达式,不用再做繁琐的判断,这块代码也可以被其它项目使用,非常好用

namespace SmartAdmin
{ public static class PredicateBuilder
{ public static Expression<Func<T, bool>> FromFilter<T>(string filtergroup) {
Expression<Func<T, bool>> any = x => true;
if (!string.IsNullOrEmpty(filtergroup))
{
var filters = JsonSerializer.Deserialize<filter[]>(filtergroup); foreach (var filter in filters)
{
if (Enum.TryParse(filter.op, out OperationExpression op) && !string.IsNullOrEmpty(filter.value))
{
var expression = GetCriteriaWhere<T>(filter.field, op, filter.value);
any = any.And(expression);
}
}
} return any;
} #region -- Public methods --
public static Expression<Func<T, bool>> GetCriteriaWhere<T>(Expression<Func<T, object>> e, OperationExpression selectedOperator, object fieldValue)
{
var name = GetOperand<T>(e);
return GetCriteriaWhere<T>(name, selectedOperator, fieldValue);
} public static Expression<Func<T, bool>> GetCriteriaWhere<T, T2>(Expression<Func<T, object>> e, OperationExpression selectedOperator, object fieldValue)
{
var name = GetOperand<T>(e);
return GetCriteriaWhere<T, T2>(name, selectedOperator, fieldValue);
} public static Expression<Func<T, bool>> GetCriteriaWhere<T>(string fieldName, OperationExpression selectedOperator, object fieldValue)
{
var props = TypeDescriptor.GetProperties(typeof(T));
var prop = GetProperty(props, fieldName, true);
var parameter = Expression.Parameter(typeof(T));
var expressionParameter = GetMemberExpression<T>(parameter, fieldName);
if (prop != null && fieldValue != null)
{ BinaryExpression body = null;
switch (selectedOperator)
{
case OperationExpression.equal:
body = Expression.Equal(expressionParameter, Expression.Constant(Convert.ChangeType(fieldValue, Nullable.GetUnderlyingType(prop.PropertyType)?? prop.PropertyType), prop.PropertyType));
return Expression.Lambda<Func<T, bool>>(body, parameter);
case OperationExpression.notequal:
body = Expression.NotEqual(expressionParameter, Expression.Constant(Convert.ChangeType(fieldValue, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType), prop.PropertyType));
return Expression.Lambda<Func<T, bool>>(body, parameter);
case OperationExpression.less:
body = Expression.LessThan(expressionParameter, Expression.Constant(Convert.ChangeType(fieldValue, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType), prop.PropertyType));
return Expression.Lambda<Func<T, bool>>(body, parameter);
case OperationExpression.lessorequal:
body = Expression.LessThanOrEqual(expressionParameter, Expression.Constant(Convert.ChangeType(fieldValue, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType), prop.PropertyType));
return Expression.Lambda<Func<T, bool>>(body, parameter);
case OperationExpression.greater:
body = Expression.GreaterThan(expressionParameter, Expression.Constant(Convert.ChangeType(fieldValue, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType), prop.PropertyType));
return Expression.Lambda<Func<T, bool>>(body, parameter);
case OperationExpression.greaterorequal:
body = Expression.GreaterThanOrEqual(expressionParameter, Expression.Constant(Convert.ChangeType(fieldValue, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType), prop.PropertyType));
return Expression.Lambda<Func<T, bool>>(body, parameter);
case OperationExpression.contains:
var contains = typeof(string).GetMethod("Contains", new[] { typeof(string) });
var bodyLike = Expression.Call(expressionParameter, contains, Expression.Constant(Convert.ChangeType(fieldValue, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType), prop.PropertyType));
return Expression.Lambda<Func<T, bool>>(bodyLike, parameter);
case OperationExpression.endwith:
var endswith = typeof(string).GetMethod("EndsWith",new[] { typeof(string) });
var bodyendwith = Expression.Call(expressionParameter, endswith, Expression.Constant(Convert.ChangeType(fieldValue, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType), prop.PropertyType));
return Expression.Lambda<Func<T, bool>>(bodyendwith, parameter);
case OperationExpression.beginwith:
var startswith = typeof(string).GetMethod("StartsWith", new[] { typeof(string) });
var bodystartswith = Expression.Call(expressionParameter, startswith, Expression.Constant(Convert.ChangeType(fieldValue, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType), prop.PropertyType));
return Expression.Lambda<Func<T, bool>>(bodystartswith, parameter);
case OperationExpression.includes:
return Includes<T>(fieldValue, parameter, expressionParameter, prop.PropertyType);
case OperationExpression.between:
return Between<T>(fieldValue, parameter, expressionParameter, prop.PropertyType);
default:
throw new Exception("Not implement Operation");
}
}
else
{
Expression<Func<T, bool>> filter = x => true;
return filter;
}
} public static Expression<Func<T, bool>> GetCriteriaWhere<T, T2>(string fieldName, OperationExpression selectedOperator, object fieldValue)
{ var props = TypeDescriptor.GetProperties(typeof(T));
var prop = GetProperty(props, fieldName, true); var parameter = Expression.Parameter(typeof(T));
var expressionParameter = GetMemberExpression<T>(parameter, fieldName); if (prop != null && fieldValue != null)
{
switch (selectedOperator)
{
case OperationExpression.any:
return Any<T, T2>(fieldValue, parameter, expressionParameter); default:
throw new Exception("Not implement Operation");
}
}
else
{
Expression<Func<T, bool>> filter = x => true;
return filter;
}
} public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expr, Expression<Func<T, bool>> or)
{
if (expr == null)
{
return or;
} return Expression.Lambda<Func<T, bool>>(Expression.OrElse(new SwapVisitor(expr.Parameters[], or.Parameters[]).Visit(expr.Body), or.Body), or.Parameters);
} public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expr, Expression<Func<T, bool>> and)
{
if (expr == null)
{
return and;
} return Expression.Lambda<Func<T, bool>>(Expression.AndAlso(new SwapVisitor(expr.Parameters[], and.Parameters[]).Visit(expr.Body), and.Body), and.Parameters);
} #endregion
#region -- Private methods -- private static string GetOperand<T>(Expression<Func<T, object>> exp)
{
if (!( exp.Body is MemberExpression body ))
{
var ubody = (UnaryExpression)exp.Body;
body = ubody.Operand as MemberExpression;
} var operand = body.ToString(); return operand.Substring(); } private static MemberExpression GetMemberExpression<T>(ParameterExpression parameter, string propName)
{
if (string.IsNullOrEmpty(propName))
{
return null;
} var propertiesName = propName.Split('.');
if (propertiesName.Count() == )
{
return Expression.Property(Expression.Property(parameter, propertiesName[]), propertiesName[]);
} return Expression.Property(parameter, propName);
} private static Expression<Func<T, bool>> Includes<T>(object fieldValue, ParameterExpression parameterExpression, MemberExpression memberExpression ,Type type)
{
var safetype= Nullable.GetUnderlyingType(type) ?? type; switch (safetype.Name.ToLower())
{
case "string":
var strlist = (IEnumerable<string>)fieldValue;
if (strlist == null || strlist.Count() == )
{
return x => true;
}
var strmethod = typeof(List<string>).GetMethod("Contains", new Type[] { typeof(string) });
var strcallexp = Expression.Call(Expression.Constant(strlist.ToList()), strmethod, memberExpression);
return Expression.Lambda<Func<T, bool>>(strcallexp, parameterExpression);
case "int32":
var intlist = (IEnumerable<int>)fieldValue;
if (intlist == null || intlist.Count() == )
{
return x => true;
}
var intmethod = typeof(List<int>).GetMethod("Contains", new Type[] { typeof(int) });
var intcallexp = Expression.Call(Expression.Constant(intlist.ToList()), intmethod, memberExpression);
return Expression.Lambda<Func<T, bool>>(intcallexp, parameterExpression);
case "float":
var floatlist = (IEnumerable<float>)fieldValue;
if (floatlist == null || floatlist.Count() == )
{
return x => true;
}
var floatmethod = typeof(List<int>).GetMethod("Contains", new Type[] { typeof(int) });
var floatcallexp = Expression.Call(Expression.Constant(floatlist.ToList()), floatmethod, memberExpression);
return Expression.Lambda<Func<T, bool>>(floatcallexp, parameterExpression);
default:
return x => true;
} }
private static Expression<Func<T, bool>> Between<T>(object fieldValue, ParameterExpression parameterExpression, MemberExpression memberExpression, Type type)
{ var safetype = Nullable.GetUnderlyingType(type) ?? type;
switch (safetype.Name.ToLower())
{
case "datetime":
var datearray = ( (string)fieldValue ).Split(new char[] { '-' }, StringSplitOptions.RemoveEmptyEntries);
var start = Convert.ToDateTime(datearray[] + " 00:00:00", CultureInfo.CurrentCulture);
var end = Convert.ToDateTime(datearray[] + " 23:59:59", CultureInfo.CurrentCulture);
var greater = Expression.GreaterThan(memberExpression, Expression.Constant(start, type));
var less = Expression.LessThan(memberExpression, Expression.Constant(end, type));
return Expression.Lambda<Func<T, bool>>(greater, parameterExpression)
.And(Expression.Lambda<Func<T, bool>>(less, parameterExpression));
case "int":
case "int32":
var intarray = ( (string)fieldValue ).Split(new char[] { '-' }, StringSplitOptions.RemoveEmptyEntries);
var min = Convert.ToInt32(intarray[] , CultureInfo.CurrentCulture);
var max = Convert.ToInt32(intarray[], CultureInfo.CurrentCulture);
var maxthen = Expression.GreaterThan(memberExpression, Expression.Constant(min, type));
var minthen = Expression.LessThan(memberExpression, Expression.Constant(max, type));
return Expression.Lambda<Func<T, bool>>(maxthen, parameterExpression)
.And(Expression.Lambda<Func<T, bool>>(minthen, parameterExpression));
case "decimal":
var decarray = ( (string)fieldValue ).Split(new char[] { '-' }, StringSplitOptions.RemoveEmptyEntries);
var dmin = Convert.ToDecimal(decarray[], CultureInfo.CurrentCulture);
var dmax = Convert.ToDecimal(decarray[], CultureInfo.CurrentCulture);
var dmaxthen = Expression.GreaterThan(memberExpression, Expression.Constant(dmin, type));
var dminthen = Expression.LessThan(memberExpression, Expression.Constant(dmax, type));
return Expression.Lambda<Func<T, bool>>(dmaxthen, parameterExpression)
.And(Expression.Lambda<Func<T, bool>>(dminthen, parameterExpression));
case "float":
var farray = ((string)fieldValue).Split(new char[] { '-' }, StringSplitOptions.RemoveEmptyEntries);
var fmin = Convert.ToDecimal(farray[], CultureInfo.CurrentCulture);
var fmax = Convert.ToDecimal(farray[], CultureInfo.CurrentCulture);
var fmaxthen = Expression.GreaterThan(memberExpression, Expression.Constant(fmin, type));
var fminthen = Expression.LessThan(memberExpression, Expression.Constant(fmax, type));
return Expression.Lambda<Func<T, bool>>(fmaxthen, parameterExpression)
.And(Expression.Lambda<Func<T, bool>>(fminthen, parameterExpression));
case "string":
var strarray = ( (string)fieldValue ).Split(new char[] { '-' }, StringSplitOptions.RemoveEmptyEntries);
var smin = strarray[];
var smax = strarray[]; var strmethod = typeof(string).GetMethod("Contains");
var mm = Expression.Call(memberExpression, strmethod, Expression.Constant(smin, type));
var nn = Expression.Call(memberExpression, strmethod, Expression.Constant(smax, type)); return Expression.Lambda<Func<T, bool>>(mm, parameterExpression)
.Or(Expression.Lambda<Func<T, bool>>(nn, parameterExpression));
default:
return x => true;
} } private static Expression<Func<T, bool>> Any<T, T2>(object fieldValue, ParameterExpression parameterExpression, MemberExpression memberExpression)
{
var lambda = (Expression<Func<T2, bool>>)fieldValue;
var anyMethod = typeof(Enumerable).GetMethods(BindingFlags.Static | BindingFlags.Public)
.First(m => m.Name == "Any" && m.GetParameters().Count() == ).MakeGenericMethod(typeof(T2)); var body = Expression.Call(anyMethod, memberExpression, lambda); return Expression.Lambda<Func<T, bool>>(body, parameterExpression);
} private static PropertyDescriptor GetProperty(PropertyDescriptorCollection props, string fieldName, bool ignoreCase)
{
if (!fieldName.Contains('.'))
{
return props.Find(fieldName, ignoreCase);
} var fieldNameProperty = fieldName.Split('.');
return props.Find(fieldNameProperty[], ignoreCase).GetChildProperties().Find(fieldNameProperty[], ignoreCase); }
#endregion
} internal class SwapVisitor : ExpressionVisitor
{
private readonly Expression from, to;
public SwapVisitor(Expression from, Expression to)
{
this.from = from;
this.to = to;
}
public override Expression Visit(Expression node) => node == from ? to : base.Visit(node);
}
public enum OperationExpression
{
equal,
notequal,
less,
lessorequal,
greater,
greaterorequal,
contains,
beginwith,
endwith,
includes,
between,
any
}
}

 public async Task<JsonResult> GetData(int page = , int rows = , string sort = "Id", string order = "asc", string filterRules = "")
{
try
{
var filters = PredicateBuilder.FromFilter<Company>(filterRules);
var total = await this.companyService
.Query(filters)
.AsNoTracking()
.CountAsync()
;
var pagerows = (await this.companyService
.Query(filters)
.AsNoTracking()
.OrderBy(n => n.OrderBy(sort, order))
.Skip(page - ).Take(rows)
.SelectAsync())
.Select(n => new
{
Id = n.Id,
Name = n.Name,
Code = n.Code,
Address = n.Address,
Contect = n.Contect,
PhoneNumber = n.PhoneNumber,
RegisterDate = n.RegisterDate.ToString("yyyy-MM-dd HH:mm:ss")
}).ToList();
var pagelist = new { total = total, rows = pagerows };
return Json(pagelist);
}
catch(Exception e) {
throw e;
} }

配合使用的代码

  • 对于固定查询逻辑的封装和复用,当然除了复用还可以明显的提高代码的可读性.

public class OrderSalesQuery : QueryObject<Order>
{
public decimal Amount { get; set; }
public string Country { get; set; }
public DateTime FromDate { get; set; }
public DateTime ToDate { get; set; } public override Expression<Func<Order, bool>> Query()
{
return (x =>
x.OrderDetails.Sum(y => y.UnitPrice) > Amount &&
x.OrderDate >= FromDate &&
x.OrderDate <= ToDate &&
x.ShipCountry == Country);
}
}

查看订单的销售情况,条件 金额,国家,日期

var orderRepository = new Repository<Order>(this);

var orders = orderRepository
.Query(new OrderSalesQuery(){
Amount = ,
Country = "USA",
FromDate = DateTime.Parse("01/01/1996"),
ToDate = DateTime.Parse("12/31/1996" )
})
.Select();

调用查询方法

public class CustomerLogisticsQuery : QueryObject<Customer>
{
public CustomerLogisticsQuery FromCountry(string country)
{
Add(x => x.Country == country);
return this;
} public CustomerLogisticsQuery LivesInCity(string city)
{
Add(x => x.City == city);
return this;
}
}

客户查询 根据国家和城市查询

public class CustomerSalesQuery : QueryObject<Customer>
{
public CustomerSalesQuery WithPurchasesMoreThan(decimal amount)
{
Add(x => x.Orders
.SelectMany(y => y.OrderDetails)
.Sum(z => z.UnitPrice * z.Quantity) > amount); return this;
} public CustomerSalesQuery WithQuantitiesMoreThan(decimal quantity)
{
Add(x => x.Orders
.SelectMany(y => y.OrderDetails)
.Sum(z => z.Quantity) > quantity); return this;
}
}

客户的销售情况,金额和数量

var customerRepository = new Repository<Customer>(this);

var query1 = new CustomerLogisticsQuery()
.LivesInCity("London"); var query2 = new CustomerSalesQuery()
.WithPurchasesMoreThan()
.WithQuantitiesMoreThan(); customerRepository
.Query(query1.And(query2))
.Select()
.Dump();

复用上面的定义的查询方法

以上这些都是改项目提供的方法,非常的好用

基于领域驱动设计(DDD)超轻量级快速开发架构(二)动态linq查询的实现方式的更多相关文章

  1. 基于领域驱动设计(DDD)超轻量级快速开发架构

    smartadmin.core.urf 这个项目是基于asp.net core 3.1(最新)基础上参照领域驱动设计(DDD)的理念,并参考目前最为了流行的abp架构开发的一套轻量级的快速开发web ...

  2. 领域驱动设计(DDD)

    领域驱动设计(DDD)实现之路 2004年,当Eric Evans的那本<领域驱动设计——软件核心复杂性应对之道>(后文简称<领域驱动设计>)出版时,我还在念高中,接触到领域驱 ...

  3. 领域驱动设计(DDD:Domain-Driven Design)

    领域驱动设计(DDD:Domain-Driven Design) Eric Evans的"Domain-Driven Design领域驱动设计"简称DDD,Evans DDD是一套 ...

  4. python 全栈开发,Day116(可迭代对象,type创建动态类,偏函数,面向对象的封装,获取外键数据,组合搜索,领域驱动设计(DDD))

    昨日内容回顾 1. 三个类 ChangeList,封装列表页面需要的所有数据. StarkConfig,生成URL和视图对应关系 + 默认配置 AdminSite,用于保存 数据库类 和 处理该类的对 ...

  5. 关于领域驱动设计 DDD(Domain-Driven Design)

    以下旨在 理解DDD. 1.     什么是领域? 妈妈好是做母婴新零售的产品,应该属于电商平台,那么电商平台就是一个领域. 同一个领域的系统都有相同的核心业务. eg: 电商领域都有:商品浏览.购物 ...

  6. 分享我对领域驱动设计(DDD)的学习成果

    本文内容提要: 1. 领域驱动设计之领域模型 2. 为什么建立一个领域模型是重要的 3. 领域通用语言(Ubiquitous Language) 4.将领域模型转换为代码实现的最佳实践 5. 领域建模 ...

  7. 我对领域驱动设计(DDD)的学习成果

    领域驱动设计之领域模型 2004年Eric Evans发表Domain-Driven Design – Tackling Complexity in the Heart of Software (领域 ...

  8. 领域驱动设计(DDD)实践之路(一)

    本文首发于 vivo互联网技术 微信公众号 链接: https://mp.weixin.qq.com/s/gk-Hb84Dt7JqBRVkMqM7Eg  作者:张文博 领域驱动设计(Domain Dr ...

  9. 领域驱动设计(DDD)实现之路

    2004年,当Eric Evans的那本<领域驱动设计——软件核心复杂性应对之道>(后文简称<领域驱动设计>)出版时,我还在念高中,接触到领域驱动设计(DDD)已经是8年后的事 ...

随机推荐

  1. 【C++】赋值过程中类型转换

    注意:以下内容摘自文献[1],修改了部分内容. 1.赋值过程中的类型转换 如果赋值运算符两侧的类型不一致,但都是数值型或字符型时,在赋值时自动进行类型转换. (1) 将浮点型数据(包括单.双精度)赋给 ...

  2. Servlet配置及生命周期

    1.设置Ecilipse快捷  file new 2.创建Servlet程序 1). 创建一个 Servlet 接口的实现类.              public class HelloServl ...

  3. Maven本地仓库/中央仓库(阿里镜像)/JDK配置

    第一步打开你已经下载好的Maven,进入:根磁盘:\......\apache-maven-3.6.2\conf文件夹找到settings.xml文件(没有的可以自行创建一个同名的文件即可) 使用文本 ...

  4. Java并发编程 (九) 线程调度-线程池

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 声明:实际上,在开发中并不会普遍的使用Thread,因为它具有一些弊端,对并发性能的影响比较大,如下: ...

  5. 高性能可扩展mysql 笔记(四)项目分区表演示

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 登录日志的分区 如何为Customer_login_log表分区? 从以下两个业务场景入手: 用户每次登 ...

  6. 初学者对Git的使用安装教程,以及对unknown key type -rsa的解决办法

    第一次使用Git,诚惶诚恐. Git在每个电脑上第一次使用必须要配置环境,才能通过SSH秘钥的方式安全稳定的拉取代码! 此文适合对Git一无所知的小白观看,大神勿扰.下面我将讲解一个傻瓜式的Git安装 ...

  7. Java实现 LeetCode 780 到达终点(逻辑题)

    780. 到达终点 从点 (x, y) 可以转换到 (x, x+y) 或者 (x+y, y). 给定一个起点 (sx, sy) 和一个终点 (tx, ty),如果通过一系列的转换可以从起点到达终点,则 ...

  8. Java实现 LeetCode 622 设计循环队列(暴力大法)

    622. 设计循环队列 设计你的循环队列实现. 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环.它也被称为"环形缓冲器" ...

  9. Java实现 LeetCode 538 把二叉搜索树转换为累加树(遍历树)

    538. 把二叉搜索树转换为累加树 给定一个二叉搜索树(Binary Search Tree),把它转换成为累加树(Greater Tree),使得每个节点的值是原来的节点值加上所有大于它的节点值之和 ...

  10. Java实现 LeetCode 372 超级次方

    372. 超级次方 你的任务是计算 ab 对 1337 取模,a 是一个正整数,b 是一个非常大的正整数且会以数组形式给出. 示例 1: 输入: a = 2, b = [3] 输出: 8 示例 2: ...