1、域名备案:指域名与公网ip的绑定,绑定后即可使用80/443等端口。 2、域名添加A记录子域名后指定对应的公网ip地址,无法指定端口。 3、只要使用https就必须使用证书,证书可以自己购买也可使用openssl生成,但是自己生成的证书安全性较差,仍然容易被串改,而且网页显示与购买的有区别。 4、nginx反向代理配置 可以不使用upstream,直接在prox_pass后添加真正的服务器地址,但是使用upstream好处更多,如实现负载均衡、设置权重等功能。 nginx部分内容详解如下: proxy_redirect off; 重写后端服务器的location和refresh头。 proxy_set_header Host $host; 重写发送给后端服务器的请求头内容。 proxy_connect_timeout 300; 代理服务器接收请求到连接后端服务器的最长等待时间。 proxy_buffer_size 4k; 后端响应的缓冲区数量和大小。 proxy_buffers 4 32k; 请求后端的缓冲区数量和大小。 proxy_busy_buffers_size 64k; 当代理服务器忙时,缓冲区的最大值。 proxy_send_timeout 300 将超时与请求传输到代理服务器分配。 proxy_read_timeout 300 NGINX等待获取请求响应的时间。 upstream ip_hash:指令通过ip地址生成hash值将客户端均匀地连接到所有服务器。 keepalive:指令指定每个worker进程缓存后端服务器的长连接数。 least_conn:指令激活负载均衡算法,使用最少连接数。 server: —- weight:设置服务器的优先级。 —- fail-timeout、max-fails:在fail-timeout时间内出现了max-fails次数的连接失败,nginx则认为该后端服务器已经挂掉了。 —- backup:指定服务器的备用机器,只有非backup机器挂掉,才会接收请求。 —- down:指定当前的服务器不再接收请求。 对upstream仍不了解,可参考此网站实例:https://www.cnblogs.com/wzjhoutai/p/6932007.html from:https://www.cnblogs.com/wdp-home/p/12092480.html
View DetailsLINQ查询方法一共提供了两种扩展方法,在System.Linq命名空间下,有两个静态类:Enumerable类,它针对继承了IEnumerable<T>接口的集合进行扩展;Queryable类,针对继承了IQueryable<T>接口的集合进行扩展。我们会发现接口IQueryable<T>实际也是继承了IEnumerable<T>接口的,既然这样微软为什么要设计出两套扩展方法呢? 从LINQ查询功能上我们知道实际上可以分为三类:LINQ to OBJECTS、LINQ to SQL和LINQ to XML。其实微设计这两套接口主要是针对LINQ to OBJECTS和LINQ to SQL,两者对于查询的内部处理机制是完全不同的。针对LINQ to OBJECTS 时,使用Enumerable中的扩展方法对本地集合进行排序和查询操作,查询参数接受的是Func<>,Func<>叫做谓语表达式,相当于一个委托。针对LINQ to SQL时,则使用Queryable中的扩展方法,它接受的是Expression<>。 那么,到底什么时候使用IQueryable<T>,什么时候使用IEnumerable<T>? 首先我们来看一下LINQ to SQL的代码: using (var context = new NorthwindEntities()) { var orderTmp = context.Orders.Where(p=>p.CustomerID=="RATTC"); var orders = orderTmp.Where(p => p.OrderDate > new DateTime(1997, 1, 1)); foreach (var order in orders) { Console.WriteLine("OrderId:" + order.OrderID); } } 通过vs的Intellisense我们可以看到Where的返回类型为IQueryable,参数是Expression类型的: 我们再看一下这一段代码: using (var context = new NorthwindEntities()) { var orderTmp = context.Orders.Where(p => p.CustomerID == "RATTC").AsEnumerable(); var orders = orderTmp.Where(p => p.OrderDate > new DateTime(1997, 1, 1)); foreach (var order in orders) { Console.WriteLine("OrderId:" + order.OrderID); } } 这段代码的不同在于我们将LINQ的查询返回IEnumerable类型,我们看一下vs的Intellisense效果: 由于我们在LINQ查询的时候加上了AsEnumerable(),因此我们在第二条语句能看到返回类型已经变为IEnumerable,参数也变成了Func<>类型。 至于这两段代码到底有什么区别,我们分别执行代码,在sql profiler里看一下生成的sql语句: 第一段代码效果: 虽然我们使用两条语句进行了查询,但最终只生成了一条SQL语句,将查询参数合并了。 第二代码效果: 这一次我们依然只看到一条SQL语句,但查询条件也只有一个,但两次查询的结果是一致。 原因在于Func<>直接会被编译器编译成IL代码,但是Expression<>只是存储了一个表达式树,在运行期作处理,LINQ to SQL最终会将表达式树转为相应的SQL语句,然后在数据库中执行。 现在我们应该知道何时使用IEnumerable<T>,何时使用Iqueryable<T>。 from:https://www.cnblogs.com/zgqys1980/p/4047315.html
View Details错误写法:
|
1 2 3 4 |
public void GetTableElements<T>() { Table<T> UserTable = m_DataContext.GetTable<T>(); } |
解决方法: 在()后面加上where T : class即可,表示为泛型T为类型才能进行转换
|
1 2 3 4 |
public void GetTableElements<T>() where T : class { Table<T> UserTable = m_DataContext.GetTable<T>(); } |
from:https://blog.csdn.net/lujiachun1/article/details/77941859
View Details先来看看几个LINQ to SQL的几个函数。 Take 说明:获取集合的前n个元素;延迟。即只返回限定数量的结果集。 var q = ( from e in db.Employees orderby e.HireDate select e) .Take(5); 语句描述:选择所雇用的前5个雇员。 Skip 说明:跳过集合的前n个元素;延迟。即我们跳过给定的数目返回后面的结果集。 var q = ( from p in db.Products orderby p.UnitPrice descending select p) .Skip (10); 语句描述:选择10种最贵产品之外的所有产品。 OrderBy 适用场景:对查询出的语句进行排序,比如按时间排序 等等。 说明:按指定表达式对集合排序;延迟,:按指定表达式对集合 排序;延迟,默认是升序,加上descending表示降序,对应的扩展方法是 OrderBy和OrderByDescending 下面这个例子使用 orderby 按雇用日期对雇员进行排序: var q = from e in db.Employees orderby e.HireDate select e; 说明:默认为升序 看完这两个函数的使用方法,那么分页的思路也就很容易推出来了,若要显示第m页,每页n条数据,我们应该跳过n*(m-1)条数据,显示n条数据。 源码如下:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
/// <summary> /// 分页查询 + 条件查询 + 排序 /// </summary> /// <typeparam name="Tkey">泛型</typeparam> /// <param name="pageSize">每页大小</param> /// <param name="pageIndex">当前页码</param> /// <param name="total">总数量</param> /// <param name="whereLambda">查询条件</param> /// <param name="orderbyLambda">排序条件</param> /// <param name="isAsc">是否升序</param> /// <returns>IQueryable 泛型集合</returns> public IQueryable<T> LoadPageItems<Tkey>(int pageSize, int pageIndex, out int total, Expression<Func<T, bool>> whereLambda, Func<T, Tkey> orderbyLambda, bool isAsc) { total = MyBaseDbContext.Set<T>().Where(whereLambda).Count(); if (isAsc) { var temp = MyBaseDbContext.Set<T>().Where(whereLambda) .OrderBy<T, Tkey>(orderbyLambda) .Skip(pageSize * (pageIndex - 1)) .Take(pageSize); return temp.AsQueryable(); } else { var temp = MyBaseDbContext.Set<T>().Where(whereLambda) .OrderByDescending<T, Tkey>(orderbyLambda) .Skip(pageSize * (pageIndex - 1)) .Take(pageSize); return temp.AsQueryable(); } } |
使用示例 //查询要求:每页10条,显示第2页,查询性别为“男”,按年龄增序排列 int totalRecord; List<Student>result = studentService.LoadItems(10,2,out totalRecord,u=>u.Sex==”男”,u=>u.Age,True); 最近研究了点Linq to Sql的知识,发现还挺有意思的,欢迎大家和我一起交流。 from:https://blog.csdn.net/augus3344/article/details/45378877
View Details问题 笔者在项目中迁移数据库时出现Method ‘get_Info’ in type ‘MySql.Data.EntityFrameworkCore.Infraestructure.MySQLOptionsExtension’ from assembly ‘MySql.Data.EntityFrameworkCore, Version=8.0.19.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d’ does not have an implementation.异常,导致数据库迁移失败。 解决 笔者开发环境如下: ASP.NET Core 3.1.1 EF Core 3.1.1 MySql.Data.EntityFrameworkCore 8.0.19 经排查得,上述问题因Oracle提供的MySql.Data.EntityFrameworkCore 8.0.19暂未完全支持ASP.NET Core 3.1.1和EF Core 3.1.1导致。故采用Pomelo.EntityFrameworkCore.MySql(3.1.1)替换MySql.Data.EntityFrameworkCore(8.0.19),问题得以解决。 错误详细堆栈信息如下: stem.TypeLoadException: Method ‘get_Info’ in type ‘MySql.Data.EntityFrameworkCore.Infraestructure.MySQLOptionsExtension’ from assembly ‘MySql.Data.EntityFrameworkCore, Version=8.0.19.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d’ does not have an implementation. at Microsoft.EntityFrameworkCore.MySQLDbContextOptionsExtensions.UseMySQL at GX.ManageSystem.Portal.Startup.<ConfigureServices>b__4_0(DbContextOptionsBuilder options) in C:\Users\mediv\source\repos\GXManageSystem\Code\GX.ManageSystem.Portal\Startup.cs:line 31 at Microsoft.Extensions.DependencyInjection.EntityFrameworkServiceCollectionExtensions.<>c__DisplayClass1_02.<AddDbContext>b__0(IServiceProvider p, DbContextOptionsBuilder b) at Microsoft.Extensions.DependencyInjection.EntityFrameworkServiceCollectionExtensions.CreateDbContextOptions[TContext](IServiceProvider applicationServiceProvider, Action2 optionsAction) at Microsoft.Extensions.DependencyInjection.EntityFrameworkServiceCollectionExtensions.<>c__DisplayClass10_01.<AddCoreServices>b__0(IServiceProvider p) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, RuntimeResolverContext context) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument) at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope […]
View DetailsASP.NET Core操作MySql数据库, 这样整套环境都可以布署在Linux上 使用微软的 Microsoft.EntityFrameworkCore(2.1.4) 和MySql出的 MySql.Data.EntityFrameworkCore(8.0.13) 软件版本 Asp.net Core:2.1 MySql:5.6 项目结构 Snai.Mysql 是 Asp.net core 2.0 Api网站,Database 下的是MySql建库建表脚本 项目实现 一、MySql 建库建表 使用 Database下的 mysql 建库 表 主键 索引.sql 脚本建库建表,脚本如下:
|
1 2 3 4 5 6 7 8 9 10 11 12 |
CREATE DATABASE alan CHARACTER SET utf8 COLLATE utf8_general_ci; USE alan; CREATE TABLE student( id INT AUTO_INCREMENT PRIMARY KEY, -- 自增列需为主键 `name` NVARCHAR(32) NOT NULL DEFAULT '', sex TINYINT NOT NULL DEFAULT 1, -- 0 男生,1 女生,2 保密 age INT NOT NULL DEFAULT 0 ); ALTER TABLE student ADD INDEX ix_student_name(`name`) -- UNIQUE INDEX 唯一索引 |
建库时加上 CHARACTER SET utf8 COLLATE utf8_general_ci 代码,设置数据库字符集为 utf8,配合程序的数据库连接串加上 CharSet=utf8,防止中文保存时乱码 如果建库时不是utf8,就把字符集改为utf8 二、EF Core 连接操作 MySql 数据库 1、新建项目,添加EF Core 和 MySql驱动依赖项 新建 asp.net core api 网站程序,NuGet 添加依赖项 Microsoft.EntityFrameworkCore.Tools(2.1.4) 和 MySql.Data.EntityFrameworkCore(8.0.13) 包 2、添加实体类Student和数据库上下文 新建 Entities 目录,在,根据表及字段,在目录下新建 Student 实体类,在类上加 [Table("student")] 表名、属性上加[Column("id")] 字段名等与表对应,代码如下:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations.Schema; using System.Linq; using System.Threading.Tasks; namespace Snai.Mysql.Entities { [Table("student")] public class Student { [Column("id")] public int ID { get; set; } [Column("name")] public string Name { get; set; } [Column("sex")] public byte Sex { get; set; } [Column("age")] public int Age { get; set; } } } |
在根目录下加上 DataAccess 目录做为数据库操作目录,在该目录下加上 Base 目录做数据库上下文目录 在 Base 目录下新建 AlanContext 上下文类,继承 DbContext 类,通过构造函数注入数据库连接,添加 DbSet<Student> 实体属性,代码如下:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
using Microsoft.EntityFrameworkCore; using Snai.Mysql.Entities; using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; namespace Snai.Mysql.DataAccess.Base { public class AlanContext:DbContext { public AlanContext(DbContextOptions<AlanContext> options) : base(options) { } public DbSet<Student> Student { get; set; } } } |
3、添、删、改、查 数据库记录 在 […]
View Details1.使用jdk自带的webservice工具wsimport生成相关类 测试wsdl http://www.webxml.com.cn/WebServices/IpAddressSearchWebService.asmx?wsdl
|
1 |
wsimport -s d:\wsdl -p com.example.demo.request -encoding utf-8 http://www.webxml.com.cn/WebServices/IpAddressSearchWebService.asmx?wsdl |
-s 存储目录; -p 包名; -encoding 文件编码,默认会采用操作系统编码,中文为gbk,建议使用utf-8; 2.构建相关的配置类及测试方法
|
1 2 3 4 5 6 7 8 |
@Configuration public class IpConfig { @Bean public IpAddressSearchWebServiceSoap webService(){ return new IpAddressSearchWebService().getIpAddressSearchWebServiceSoap(); } } |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
@SpringBootApplication @RestController @RequestMapping("/soap") public class DemoApplication { @Autowired private IpAddressSearchWebServiceSoap soap; public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } @RequestMapping("/{ip}") public ArrayOfString searchIp(@PathVariable("ip") String ip) { ArrayOfString response = soap.getCountryCityByIp(ip); return response; } } |
from:https://blog.csdn.net/VitaminZH/article/details/81123571
View Detailsdynamic类型 简单示例 dynamic expando = new System.Dynamic.ExpandoObject(); //动态类型字段 可读可写 expando.Id = 1; expando.Name = "Test"; string json = Utils.ConvertJson.JsonEncode(expando); //输出{Id:1,Name:’Test'} //动态添加字段 List<string> fieldList = new List<string>() { "Name","Age","Sex"}; //From config or db dynamic dobj = new System.Dynamic.ExpandoObject(); var dic = (IDictionary<string, object>)dobj; foreach (var fieldItem in fieldList) { dic[fieldItem] = "set "+fieldItem+" value"; /*实现类似js里的 动态添加属性的功能 var obj={}; var field="Id"; eval("obj."+field+"=1"); […]
View Details我们是否一样? 估计很多小伙伴(也包括我自己)都有这种情况,在自学Java语言看书时,关于枚举enum这一块的知识点可能都有点 “轻敌” ,觉得这块内容非常简单,一带而过,而且在实际写代码过程中也不注意运用。 是的,我也是这样!直到有一天我提的代码审核没过,被技术总监一顿批,我才重新拿起了《Java编程思想》,把枚举这块的知识点重新又审视了一遍。 为什么需要枚举 常量定义它不香吗?为啥非得用枚举? 举个栗子,就以B站上传视频为例,视频一般有三个状态:草稿、审核和发布,我们可以将其定义为静态常量:
|
1 2 3 4 5 6 7 8 |
public class VideoStatus { public static final int Draft = 1; //草稿 public static final int Review = 2; //审核 public static final int Published = 3; //发布 } |
对于这种单值类型的静态常量定义,本身也没错,主要是在使用的地方没有一个明确性的约束而已,比如:
|
1 2 3 4 5 |
void judgeVideoStatus( int status ) { ... } |
比如这里的 judgeVideoStatus 函数的本意是传入 VideoStatus 的三种静态常量之一,但由于没有类型上的约束,因此传入任意一个int值都是可以的,编译器也不会提出任何警告。 但是在枚举类型出现之后,上面这种情况就可以用枚举严谨地去约束,比如用枚举去定义视频状态就非常简洁了:
|
1 2 3 |
public enum VideoStatus { Draft, Review, Published } |
而且主要是在用枚举的地方会有更强的类型约束:
|
1 2 3 4 5 6 |
// 入参就有明确类型约束 void judgeVideoStatus( VideoStatus status ) { ... } |
这样在使用 judgeVideoStatus 函数时,入参类型就会受到明确的类型约束,一旦传入无效值,编译器就会帮我们检查,从而规避潜在问题。 除此之外,枚举在扩展性方面比普常量更方便、也更优雅。 重新系统认识一下枚举 还是拿前文《答应我,别再if/else走天下了可以吗》中的那个例子来说:比如,在后台管理系统中,肯定有用户角色一说,而且角色一般都是固定的,适合定义成一个枚举:
|
1 2 3 4 5 6 7 8 |
public enum UserRole { ROLE_ROOT_ADMIN, // 系统管理员 ROLE_ORDER_ADMIN, // 订单管理员 ROLE_NORMAL // 普通用户 } |
接下来我们就用这个UserRole为例来说明枚举的所有基本用法:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
UserRole role1 = UserRole.ROLE_ROOT_ADMIN; UserRole role2 = UserRole.ROLE_ORDER_ADMIN; UserRole role3 = UserRole.ROLE_NORMAL; // values()方法:返回所有枚举常量的数组集合 for ( UserRole role : UserRole.values() ) { System.out.println(role); } // 打印: // ROLE_ROOT_ADMIN // ROLE_ORDER_ADMIN // ROLE_NORMAL // ordinal()方法:返回枚举常量的序数,注意从0开始 System.out.println( role1.ordinal() ); // 打印0 System.out.println( role2.ordinal() ); // 打印1 System.out.println( role3.ordinal() ); // 打印2 // compareTo()方法:枚举常量间的比较 System.out.println( role1.compareTo(role2) ); //打印-1 System.out.println( role2.compareTo(role3) ); //打印-2 System.out.println( role1.compareTo(role3) ); //打印-2 // name()方法:获得枚举常量的名称 System.out.println( role1.name() ); // 打印ROLE_ROOT_ADMIN System.out.println( role2.name() ); // 打印ROLE_ORDER_ADMIN System.out.println( role3.name() ); // 打印ROLE_NORMAL // valueOf()方法:返回指定名称的枚举常量 System.out.println( UserRole.valueOf( "ROLE_ROOT_ADMIN" ) ); System.out.println( UserRole.valueOf( "ROLE_ORDER_ADMIN" ) ); System.out.println( UserRole.valueOf( "ROLE_NORMAL" ) ); |
除此之外,枚举还可以用于switch语句中,而且意义更加明确:
|
1 2 3 4 5 6 7 8 9 10 11 12 |
UserRole userRole = UserRole.ROLE_ORDER_ADMIN; switch (userRole) { case ROLE_ROOT_ADMIN: // 比如此处的意义就非常清晰了,比1,2,3这种数字好! System.out.println("这是系统管理员角色"); break; case ROLE_ORDER_ADMIN: System.out.println("这是订单管理员角色"); break; case ROLE_NORMAL: System.out.println("这是普通用户角色"); break; } |
自定义扩充枚举 上面展示的枚举例子非常简单,仅仅是单值的情形,而实际项目中用枚举往往是多值用法。 比如,我想扩充一下上面的UserRole枚举,在里面加入 角色名 — 角色编码 的对应关系,这也是实际项目中常用的用法。 这时候我们可以在枚举里自定义各种属性、构造函数、甚至各种方法:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
public enum UserRole { ROLE_ROOT_ADMIN( "系统管理员", 000000 ), ROLE_ORDER_ADMIN( "订单管理员", 100000 ), ROLE_NORMAL( "普通用户", 200000 ), ; // 以下为自定义属性 private final String roleName; //角色名称 private final Integer roleCode; //角色编码 // 以下为自定义构造函数 UserRole( String roleName, Integer roleCode ) { this.roleName = roleName; this.roleCode = roleCode; } // 以下为自定义方法 public String getRoleName() { return this.roleName; } public Integer getRoleCode() { return this.roleCode; } public static Integer getRoleCodeByRoleName( String roleName ) { for( UserRole enums : UserRole.values() ) { if( enums.getRoleName().equals( roleName ) ) { return enums.getRoleCode(); } } return null; } } |
从上述代码可知,在enum枚举类中完全可以像在普通Class里一样声明属性、构造函数以及成员方法。 枚举 + 接口 = ? 比如在我的前文《答应我,别再if/else走天下了可以吗》中讲烦人的if/else消除时,就讲过如何通过让枚举去实现接口来方便的完成。 这地方不妨再回顾一遍: 什么角色能干什么事,这很明显有一个对应关系,所以我们首先定义一个公用的接口RoleOperation,表示不同角色所能做的操作:
|
1 2 3 |
public interface RoleOperation { String op(); // 表示某个角色可以做哪些op操作 } |
接下来我们将不同角色的情况全部交由枚举类来做,定义一个枚举类RoleEnum,并让它去实现RoleOperation接口:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
public enum RoleEnum implements RoleOperation { // 系统管理员(有A操作权限) ROLE_ROOT_ADMIN { @Override public String op() { return "ROLE_ROOT_ADMIN:" + " has AAA permission"; } }, // 订单管理员(有B操作权限) ROLE_ORDER_ADMIN { @Override public String op() { return "ROLE_ORDER_ADMIN:" + " has BBB permission"; } }, // 普通用户(有C操作权限) ROLE_NORMAL { @Override public String op() { return "ROLE_NORMAL:" + " has CCC permission"; } }; } |
这样,在调用处就变得异常简单了,一行代码就行了,根本不需要什么if/else:
|
1 2 3 4 5 6 |
public class JudgeRole { public String judge( String roleName ) { // 一行代码搞定!之前的if/else灰飞烟灭 return RoleEnum.valueOf(roleName).op(); } } |
而且这样一来,以后假如我想扩充条件,只需要去枚举类中加代码即可,而不用改任何老代码,非常符合开闭原则! 枚举与设计模式 什么?枚举还能实现设计模式? 是的!不仅能而且还能实现好几种! 1、单例模式
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
public class Singleton { // 构造函数私有化,避免外部创建实例 private Singleton() { } //定义一个内部枚举 public enum SingletonEnum{ SEED; // 唯一一个枚举对象,我们称它为“种子选手”! private Singleton singleton; SingletonEnum(){ singleton = new Singleton(); //真正的对象创建隐蔽在此! } public Singleton getInstnce(){ return singleton; } } // 故意外露的对象获取方法,也是外面获取实例的唯一入口 public static Singleton getInstance(){ return SingletonEnum.SEED.getInstnce(); // 通过枚举的种子选手来完成 } } |
2、策略模式 这个也比较好举例,比如用枚举就可以写出一个基于策略模式的加减乘除计算器
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
public class Test { public enum Calculator { ADDITION { public Double execute( Double x, Double y ) { return x + y; // 加法 } }, SUBTRACTION { public Double execute( Double x, Double y ) { return x - y; // 减法 } }, MULTIPLICATION { public Double execute( Double x, Double y ) { return x * y; // 乘法 } }, DIVISION { public Double execute( Double x, Double y ) { return x/y; // 除法 } }; public abstract Double execute(Double x, Double y); } public static void main(String[] args) { System.out.println( Calculator.ADDITION.execute( 4.0, 2.0 ) ); // 打印 6.0 System.out.println( Calculator.SUBTRACTION.execute( 4.0, 2.0 ) ); // 打印 2.0 System.out.println( Calculator.MULTIPLICATION.execute( 4.0, 2.0 ) ); // 打印 8.0 System.out.println( Calculator.DIVISION.execute( 4.0, 2.0 ) ); // 打印 2.0 } } |
专门用于枚举的集合类 我们平常一般习惯于使用诸如:HashMap 和 HashSet等集合来盛放元素,而对于枚举,有它专门的集合类:EnumSet和EnumMap 1、EnumSet EnumSet 是专门为盛放枚举类型所设计的 Set 类型。 还是举例来说,就以文中开头定义的角色枚举为例:
|
1 2 3 4 5 6 7 8 |
public enum UserRole { ROLE_ROOT_ADMIN, // 系统管理员 ROLE_ORDER_ADMIN, // 订单管理员 ROLE_NORMAL // 普通用户 } |
比如系统里来了一批人,我们需要查看他是不是某个角色中的一个:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
// 定义一个管理员角色的专属集合 EnumSet<UserRole> userRolesForAdmin = EnumSet.of( UserRole.ROLE_ROOT_ADMIN, UserRole.ROLE_ORDER_ADMIN ); // 判断某个进来的用户是不是管理员 Boolean isAdmin( User user ) { if( userRoles.contains( user.getUserRole() ) ) return true; return false; } |
2、EnumMap 同样,EnumMap 则是用来专门盛放枚举类型为key的 Map 类型。 比如,系统里来了一批人,我们需要统计不同的角色到底有多少人这种的话:
|
1 2 3 4 5 6 7 8 9 10 |
Map<UserRole,Integer> userStatisticMap = new EnumMap<>(UserRole.class); for ( User user : userList ) { Integer num = userStatisticMap.get( user.getUserRole() ); if( null != num ) { userStatisticMap.put( user.getUserRole(), num+1 ); } else { userStatisticMap.put( user.getUserRole(), 1 ); } } |
用EnumMap可以说非常方便了。 总 结 小小的枚举就玩出这么多的花样,不过好在探索和总结的过程还挺有意思的,也复习了很多知识,慢慢来吧。 from:https://my.oschina.net/hansonwang99/blog/3196498
View Details问题描述: Details -Event filter with query "SELECT * FROM __InstanceModificationEvent WITHIN 60 WHERE TargetInstance ISA "Win32_Processor" AND TargetInstance.LoadPercentage > 99" could not be reactivated in namespace "//./root/CIMV2" because of error 0x80041003. Events cannot be delivered through this filter until the problem is corrected. 解决方案: http://go.microsoft.com/?linkid=9775756 http://download.microsoft.com/download/3/9/D/39DF4B56-9D3A-4645-AC11-803043ED4214/MicrosoftFixit50688.msi 方案详解: http://support.microsoft.com/kb/2545227/en-us#FixItForMeAlways from:https://www.cnblogs.com/heweijian/p/6781382.html
View Details