.NET架构小技巧(4)——反射,架构人员法宝II

上一篇博文中,利用属性反射的特点,用两个方法完成了字符转实体,实体转字符的工作,但有些复杂的场景,上面方法就没那么好用了,就需要更复杂的方式来组装处理。

先来看一个接口文档,下面是接口的调用方式

long  OltpTransData(unsigned long msgType,unsigned long packageType,unsigned long packageLength,char *str,LPTSTR com);

I.msgType:业务请求类型;

II.packageType:数据解析格式类型,系统重组数据时使用

III.packageLength:数据串的长度;

IV. str:数据串;调用时,通过数据串传入参数;函数返回时,数据串中包含返回的数据,数据按字符串方式组合,并且在字符串第一位保留一个空格;另外,除了16位日期右补空格,其他的字段均以左空格补位

V. com:数据请求串口

业务请求类型

数据解析格式类型

数据串最小长度

说明

1001

101

126

实时验卡(读卡、验卡)

1002

12

610

实时结算

1003

7

291

实时明细数据传输

1004

9

253

实时住院登记数据传输

1005

8

309

实时医嘱数据传输

1006

12

610

实时结算预算

1007

2

1101

实时住院首次病程记录传输

1009

504

85

医师信息查询

1010

510

331

出入院标准传输

读卡

序号

定义

数据原型

起始位置

数据长度

备注

数据填充

1

个人编号

CHAR

1

8

医保编号,以’E’开头的为异地社保卡,详见说明

院端

2

姓名

CHAR

9

20


中心

3

身份证号

CHAR

29

18

18位或15位

中心

4

IC卡号

CHAR

47

9


院端

5

治疗序号

NUM

56

4


中心

6

职工就医类别

CHAR

60

1

A在职、B退休、L事业离休、T特诊、Q企业离休、E退老、N农民工、X未成年居民、O老年居民(老年居民、低收入人员、残疾人)、D低保人员、S  三无人员、U 大学生

中心

7

基本个人帐户余额

NUM

61

10


中心

8

补助个人帐户余额

NUM

71

10

现用于公务员单独列帐

中心

9

统筹累计

NUM

81

10


中心

10

门诊慢病统筹累计

NUM

91

10


中心

11

月缴费基数

NUM

101

10

月缴费工资

中心

12

帐户状态

CHAR

111

1

A正常、B半止付、C全止付、D销户

中心

13

参保类别1

CHAR

112

1

是否享受高额:

0 不享受高额、1  享受高额、2 医疗保险不可用

中心

14

参保类别2

CHAR

113

1

是否享受补助(商业补助、公务员补助):0  不享受、1 商业、2  公务员、3事业离休差额拨款人员

中心

15

参保类别3

CHAR

114

1

0 企保、1 事保、2企业慢病、3事业慢病、4异地就医,详见说明

中心

16

参保类别4

CHAR

115

1

0或2生育不可用、1或3生育可用

中心

17

参保类别5

CHAR

116

1

0工伤不可用、1工伤可用

中心

18

住院次数累计

NUM

117

4


中心

19

家床次数累计

NUM

121

4


中心

查询医师

序号

定义

数据原型

起始位置

数据长度

备注

填写方式

1

医师编码

CHAR

1

8


院端

2

医师姓名

CHAR

9

20


中心

3

身份证号

CHAR

29

18


中心

4

可出诊医院编号

CHAR

47

20

详见说明

中心

5

终止日期

DATETIME

67

16

YYYYMMDDHHMMSS

中心

6

有效标志

CHAR

83

1

‘0’无效,‘1’有效

中心

这个接口是拼接方式,每个数据项都有固定的长度,有些数据也有固定的格式,比如日期,还有很多类型,都是有固定值固定含义的。这种情况下需要更多的信息来告诉两个转换方法该怎么转换,这里就引出了Attribute——一个专门来给类或属性方法加特征的知识点。

    /// <summary>/// 发送报文类型/// </summary>[AttributeUsage(AttributeTargets.Class)]public class PackageTypeAttribute : Attribute{/// <summary>/// 发关报文实体类属性特性类/// </summary>/// <param name="SN">属性的序号,从1开始</param>/// <param name="Length">属性转成字符串后长度</param>public PackageTypeAttribute(uint OperationType, uint DataFormaterType, uint MinLength){this.OperationType = OperationType;this.DataFormaterType = DataFormaterType;this.MinLength = MinLength;}/// <summary>/// 业务请求类型/// </summary>public uint OperationType{ get; private set; }/// <summary>/// 数据解析格式类型/// </summary>public uint DataFormaterType{ get; private set; }/// <summary>/// 数据串最小长度/// </summary>public uint MinLength{ get; private set; }}/// <summary>/// 报文中属性的顺序SN和长度Length/// </summary>[AttributeUsage(AttributeTargets.Property)]public class PackageAttribute : Attribute{/// <summary>/// 序号,从1开始/// </summary>public int SN{ get; private set; }/// <summary>/// 转成字符串后的长度/// </summary>public int Length{ get; private set; }/// <summary>/// 发关报文实体类属性特性类/// </summary>/// <param name="SN">属性的序号,从1开始</param>/// <param name="Length">属性转成字符串后长度</param>public PackageAttribute(int SN, int Length){this.SN = SN;this.Length = Length;}/// <summary>/// 是否是时间类型,因为时间类型是左对齐,右补空格/// </summary>public bool IsDateTime{ get; set; }}/// <summary>/// 取枚举的值还是/// </summary>[AttributeUsage(AttributeTargets.Enum)]public class EnumValeuNumberAttribute : Attribute{/// <summary>/// 是否把枚举类型属性的的值数转成Char类型/// </summary>public bool IsChar{ get; set; }}

定义了三个特性类,PackageTypeAttribute主用来区分不同的交易类型,从实体类上获取不同交易的函数参数;PackageAttribute是在实体类的属性上的,是核心特性类,它标记了属性的序号,和每个属性的长度,和属性是否是DateTime类型;EnumValeuNumberAttribute是用来专门处理枚举类型的属性的。

    /// <summary>/// 医师信息查询/// </summary>[PackageType(1009, 504, 85)]public class DoctorQuery : Entity{/// <summary>/// 医师编码/// </summary>[Package(1, 8)]public virtual String DoctorCode{get; set;}/// <summary>/// 医师姓名/// </summary>[Package(2, 20)]public virtual String DoctorName{ get; set; }/// <summary>/// 身份证号/// </summary>[Package(3, 18)]public virtual string PersonID{ get; set; }///编号为0002的医院, 下属有编号为0113的定点, 在总院注册登记的医师可以在这样的2家医院出诊, 则“可出诊医院编号”为00020113,若长度不足20位则前补空格。/// <summary>/// 可出诊医院编号/// </summary>[Package(4, 20)]public virtual string CanVisitHospitalCode{ get; set; }/// <summary>/// 终止日期/// </summary>[Package(5, 16, IsDateTime = true)]public virtual string TerminationTime{ get; set; }/// <summary>/// 有效标志/// </summary>[Package(6, 1)]public virtual DLYBAvailableMarker DLYBAvailableMarker{ get; set; }}/// <summary>/// 有效标志/// </summary>[EnumValeuNumber]public enum DLYBAvailableMarker{/// <summary>/// 无效/// </summary>nullity = 0,/// <summary>/// 有效/// </summary>Valid = 1}/// <summary>/// 实时验卡(读卡、验卡)/// </summary>[PackageType(1001, 101, 126)] public  class QueryCardEntity : Entity{        /// <summary>/// 个人编号/// </summary>[Package(1, 8)]public virtual string PersonNumber{ get; set; }/// <summary>/// 姓名/// </summary>[Package(2, 20)]public virtual string Name{ get; set; }/// <summary>/// 身份证号/// </summary>[Package(3, 18)]public virtual string PersonID{ get; set; }/// <summary>/// IC卡号/// </summary>[Package(4, 9)]public virtual string ICCardNumber{ get; set; }long therapyNumber;/// <summary>/// 治疗序号/// </summary>[Package(5, 4)]public virtual long TherapyNumber{get{return therapyNumber;}set{if (value >= 0 && value <= 9999){therapyNumber = value;}else{throw new Exception("治疗号在0-9999之间");}}}/// <summary>/// 职工就医类别/// </summary>[Package(6, 1)]public virtual string TherapyCategory{ get; set; }/// <summary>/// 基本个人帐户余额/// </summary>[Package(7, 10)]public virtual decimal BasePersonBalance{ get; set; }/// <summary>/// 补助个人帐户余额/// </summary>[Package(8, 10)]public virtual decimal SubsidyPersonBalance{ get; set; }/// <summary>/// 统筹累计/// </summary>[Package(9, 10)]public virtual decimal PlannerTotal{ get; set; }/// <summary>/// 门诊慢病统筹累计///新/// </summary>[Package(10, 10)]public virtual decimal MZSlowDisease{ get; set; }/// <summary>/// 月缴费基数/// </summary>[Package(11, 10)]public virtual decimal BaseFeeByMonth{ get; set; }/// <summary>/// 帐户状态/// </summary>[Package(12, 1)]public virtual string AccoutState{ get; set; }/// <summary>/// 参保类别1/// </summary>[Package(13, 1)]public virtual string InsuranceCategory1{ get; set; }/// <summary>/// 参保类别2/// </summary>[Package(14, 1)]public virtual string InsuranceCategory2{ get; set; }/// <summary>/// 参保类别3/// </summary>[Package(15, 1)]public virtual string InsuranceCategory3{ get; set; }/// <summary>/// 参保类别4/// </summary>[Package(16, 1)]public virtual string InsuranceCategory4{ get; set; }/// <summary>/// 参保类别5/// </summary>[Package(17, 1)]public virtual string InsuranceCategory5{ get; set; }/// <summary>/// 住院次数累计新/// </summary>[Package(18, 4)]public virtual int ZYAddNumber{ get; set; }/// <summary>/// 家床次数累计新/// </summary>[Package(19, 4)]public virtual int AddBedNumber{ get; set; }}

上面的实体类分别使用了特性类,参照文档就OK。

    public static class StringExtension{  /// <summary>/// 右边不够长度补空格,汉字算两个空格/// </summary>/// <param name="str"></param>/// <param name="length">设定长度</param>/// <returns></returns>public static string ChineseCharacterLeft(this string str, int length){var len = Encoding.Default.GetBytes(str).Length;if (len < length){for (int i = 0; i < length - len; i++){str = " " + str;}}return str;}/// <summary>/// 右边不够长度补空格,汉字算两个空格/// </summary>/// <param name="str"></param>/// <param name="length">设定长度</param>/// <returns></returns>public static string ChineseCharacterRight(this string str, int length){var len = Encoding.Default.GetBytes(str).Length;if (len < length){for (int i = 0; i < length - len; i++){str += " ";}}return str;}/// <summary>/// 切除字符串/// </summary>public static string ChineseCharacterSubstring(this string str, int length, out string remaining){var arr = Encoding.Default.GetBytes(str);var barr = arr.Take(length).ToArray();var valuestr = Encoding.Default.GetString(barr);barr = arr.Skip(length).ToArray();remaining = Encoding.Default.GetString(barr); ;return valuestr;}}

‍上面代码是对某些属性的对齐方式作了处理。

    /// <summary>/// 报文类的父类/// </summary>public abstract class Entity{/// <summary>/// 组装发送报文格式/// </summary>/// <returns></returns>public override string ToString(){var pros = this.GetType().GetProperties();var sortPro = new SortedList<int, PropertyInfo>();  foreach (var pro in pros){foreach (var att in pro.GetCustomAttributes(false)){if (att is PackageAttribute){var packageAtt = att as PackageAttribute;   sortPro.Add(packageAtt.SN, pro);}}}var content = new StringBuilder();#region 组合发送字符串//遍历属性 foreach (var pro in sortPro){//遍历属性上的特性                foreach (var att in pro.Value.GetCustomAttributes(false)){//判断是否为自定义的PackageAttribute类型if (att is PackageAttribute){//转换属性上的特性类var packageAtt = att as PackageAttribute;//取拼接时字符长度var length = packageAtt.Length;//取属性的值var proValue = pro.Value.GetValue(this, new Object[0]);//对decimal作处理if (pro.Value.PropertyType.Name.ToLower() == "decimal"){proValue = Math.Round(Convert.ToDecimal(proValue), 2);if (Encoding.Default.GetByteCount(proValue.ToString()) > length){proValue = "0";}}//判断字符串长度过长if (proValue != null && (pro.Value.PropertyType.Name.ToLower() == "string")){if (System.Text.Encoding.Default.GetBytes(proValue.ToString()).Length > length){throw new Exception(string.Format("属性{0}的值{1},长度超过{2}", pro.Value.Name, proValue, length));}}//如果值为非空if (proValue != null){//日期是右补空格,其他是左补空格if (!packageAtt.IsDateTime){//这里注册,有些属性是枚举类型,有些属性拼接枚举的值,有些取枚举值对应的枚举数值,这里是从该属性类型上的EnumValeuNumberAttribute特性的IsValue属性来判断的,IsValue为true,就取枚举的值,为false取该值对应的枚举数if (pro.Value.PropertyType.IsEnum){foreach (var eatt in pro.Value.PropertyType.GetCustomAttributes(false)){if (eatt is EnumValeuNumberAttribute){var enumVaNu = eatt as EnumValeuNumberAttribute;if (enumVaNu.IsChar){var enumNumber = ((char)(int)Enum.Parse(pro.Value.PropertyType, proValue.ToString())).ToString();content.Append(enumNumber.ChineseCharacterLeft(length));}else{var enumNumber = ((int)Enum.Parse(pro.Value.PropertyType, proValue.ToString())).ToString();content.Append(enumNumber.ChineseCharacterLeft(length));}}}}else{content.Append(proValue.ToString().ChineseCharacterLeft(length));}}else//日期类型右补空格{content.Append(proValue.ToString().ChineseCharacterRight(length));}}else{content.Append("".ChineseCharacterLeft(length));}}}}#endregionreturn content.ToString();}/// <summary>/// 把一个字符串转成一个对象/// </summary>/// <param name="content"></param>/// <returns></returns>public  Entity ToEntity(Type entityType,string content){var pros = entityType.GetProperties();//按照特性类上的SN序号把属性名存入集合proPackageList中List<PropertyInfo> proPackageList = new List<PropertyInfo>(pros.Length);//初始化属性集合for (int i = 0; i < pros.Length; i++){foreach (var att in pros[i].GetCustomAttributes(false)){if (att is PackageAttribute){proPackageList.Add(null);break;}}}//按属性顺序排列属性foreach (var pro in pros){foreach (var att in pro.GetCustomAttributes(false)){if (att is PackageAttribute){var packageAtt = att as PackageAttribute;var index = packageAtt.SN - 1;proPackageList[index] = pro;}}}//创建实体对象var constructor = entityType.GetConstructor(new Type[0]);var entity = constructor.Invoke(new object[0]);foreach (var pro in proPackageList){//遍历属性上的特性foreach (var att in pro.GetCustomAttributes(false)){//判断是否为自定义的PackageAttribute类型if (att is PackageAttribute){//转换属性上的特性类var packageAtt = att as PackageAttribute;var length = packageAtt.Length;var valuestr = content.ChineseCharacterSubstring(length, out content).Trim();if (pro.PropertyType.IsEnum){foreach (var eatt in pro.PropertyType.GetCustomAttributes(false)){if (eatt is EnumValeuNumberAttribute){var eat = eatt as EnumValeuNumberAttribute;if (eat.IsChar){var chr = Convert.ToChar(valuestr);var value = Convert.ChangeType(Enum.Parse(pro.PropertyType, ((int)chr).ToString()), pro.PropertyType);pro.SetValue(entity, value, null);}else{var value = Convert.ChangeType(Enum.Parse(pro.PropertyType, valuestr), pro.PropertyType);pro.SetValue(entity, value, null);}break;}}}else{var value = Convert.ChangeType(valuestr, pro.PropertyType);pro.SetValue(entity, value, null);}}}}return (Entity)entity;}}

这两个方法核心里通过反射属性上的特性,取特性中定义的固定值,来生成接口要求的字符串,合理的设计特性,可以使两个转换方法更优雅,更简便,在开发过程中,也需要不断调整理,适配,逐渐完善。

可以用下面的代码完成测试

using System;
namespace ArchitectureDemo04
{class Program{static void Main(string[] args){var backQueryCard = Send(new QueryCardEntity { PersonNumber = "0000001", ICCardNumber = "C00000001" });var backDoctorQuery = Send(new DoctorQuery { DoctorCode = "0001" });}/// <summary>/// 发送/// </summary>/// <param name="entity"></param>/// <returns></returns>static Entity Send(Entity entity){try{foreach (var att in entity.GetType().GetCustomAttributes(false)){if (att is PackageTypeAttribute){var attPackage = att as PackageTypeAttribute;    Console.WriteLine($"入参:");Console.WriteLine(entity);Console.WriteLine("模拟函数调用:");Console.WriteLine($"OltpTransData({attPackage.OperationType},{attPackage.DataFormaterType},{attPackage.MinLength},{entity})");var backContent = BackOperation(entity);var backEntity = entity.ToEntity(entity.GetType(),backContent);return backEntity;}}return null;}catch{throw;}}/// <summary>/// 模拟医保中心返回/// </summary>/// <param name="entity">参数</param>/// <returns></returns>static string BackOperation(Entity entity){switch (entity.GetType().Name){case "QueryCardEntity":return " 0000001                Jack210213198411113111C00000001   1A   1000.66         0         0         0      1800A00131   0   0"; case "DoctorQuery":return "    0001            DcotorLi210211198707182233            0002011320201029190850  1";}return null;}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/307141.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

后端学习 - 设计模式与设计原则

文章目录设计原则1 单一职责原则2 开闭原则3 Liskov 替换原则4 依赖倒置原则5 接口隔离原则6 迪米特法则设计模式&#xff1a;创建型模式1 工厂模式2 抽象工厂模式3 单例模式设计模式&#xff1a;行为型模式1 观察者模式2 模板模式3 备忘录模式设计模式&#xff1a;结构型模式1…

ai的预览模式切换_AI字体制作,用AI制作创意阶梯式文字

本篇教程通过AI制作一款创意阶梯式文字&#xff0c;教程中有很多知识点需要掌握&#xff0c;比如路径分割为网络&#xff0c;3D效果应用等&#xff0c;我们要利用他们创造出我们需要的文字出来&#xff0c;具体是如何制作的&#xff0c;我们通过教程一起来学习一下吧。效果图&a…

.NET架构小技巧(5)——反射,架构人员法宝III

通过两篇博文&#xff0c;我们了解到&#xff0c;反射是通过非实例化(new)的手段来对对象和对象内的成员访问的&#xff0c;不仅仅如此&#xff0c;反射还可以突破访问修饰符的限制&#xff0c;以上帝视角来窥探对象内部全部成员(字段&#xff0c;属性&#xff0c;方法)&#x…

分类计数原理与分步计数原理_《分类计数原理与分步计数原理》优秀说课稿

《分类计数原理与分步计数原理》优秀说课稿一、本节内容的地位与重要性“分类计数原理与分步计数原理”是《高中数学》一节独特内容。这一节课与排列、组合的基本概念有着紧密的联系&#xff0c;通过对这一节课的学习&#xff0c;既可以让学生接受、理解分类计数原理与分步计数…

新版本 Swashbuckle swagger 组件中的 坑

新版本 Swashbuckle swagger 组件中的 Servers 坑Intro上周做了公司的项目升级&#xff0c;从 2.2 更新到 3.1&#xff0c; swagger 直接更新到了最新&#xff0c;swagger 用的组件是 Swashbuckle.AspNetCore&#xff0c;然后遇到一个 swagger 的问题&#xff0c; 在本地测试是…

后端学习 - MySQL存储引擎、索引与事务

文章目录一 存储引擎1 MyISAM 与 InnoDB 的差异二 索引1 主键索引与二级索引、索引覆盖、延迟关联2 聚簇索引与非聚簇索引3 数据结构3.1 哈希表3.2 B树3.3 B树3.4 跳表3.5 为什么不使用红黑树3.6 为什么不使用B树**4 索引下推 ICP **5 索引失效&#xff08;索引不命中&#xff…

itext设置pdf的尺寸_如何获取pdf文档iText 7的页面大小-问答-阿里云开发者社区-阿里云...

我在iText 7中有一个Java程序&#xff0c;可以接收JSON数据并生成一个PDF文档(带有页眉和页脚)&#xff0c;该文档可以很好地处理clientData注释中的变量中的数据&#xff0c;但是当在无注释clientData中使用变量不起作用时&#xff0c;我得到了此错误java.lang.NullPointerExc…

. NET5正式版本月来袭,为什么说gRPC大有可为?

当前企业正在慢慢改用微服务架构来构建面向未来的应用程序&#xff0c;微服务使企业能够有效管理基础架构&#xff0c;轻松部署更新或改进&#xff0c;并帮助IT团队的创新和学习。它还可以帮助企业能够设计出可以轻松按需扩展的应用程序&#xff0c;此外&#xff0c;随着企业转…

宝塔部署node项目_宝塔面板部署 node.js 项目

安装&#xff1a; Nginx 1.16.1安装&#xff1a;MySQL 5.5.62安装&#xff1a;PM2管理器 4.2.3Nginx 配置如下&#xff1a;user www www;worker_processes auto;error_log /www/wwwlogs/nginx_error.log crit;pid /www/server/nginx/logs/nginx.pid;worker_rlimit_nofile 51200…

后端学习 - 操作系统

文章目录一 基本概念1 操作系统的特征2 操作系统的位置3 计算机的硬件组成4 中断与异常5 系统调用二 进程管理1 进程控制块 PCB&#xff08;Process Control Block&#xff09;2 进程的状态与转换3 进程间的通信4 线程5 调度算法6 死锁7 PV 操作三 内存管理1 内存的非连续分配2…

西门子触摸屏脚本程序_通过驿唐PLC501远程下载Smart Line触摸屏

通过驿唐PLC-501远程下载Smart Line触摸屏一、触摸屏设置将PLC-501和Smart 700 IE V3通过网线连到一起。触摸屏上电后&#xff0c;点击Control Panel进入控制面板界面。进入控制面板后&#xff0c;点击Ethernet设置IP地址&#xff0c;与PLC-501联网宝在同一个网段。联网宝的IP地…

.NET for Apache Spark 1.0 版本发布

.NET for Apache Spark 1.0 现已发布&#xff0c;这是一个用于 Spark 大数据的 .NET 框架&#xff0c;可以让 .NET 开发者轻松地使用 Apache Spark。该软件包由微软和 .NET Foundation 牵头&#xff0c;经过大约两年的开发。在 2019 年的 Spark AI 峰会上&#xff0c;微软曾宣…

算法 - 排序算法

文章目录1 快速排序2 堆排序3.冒泡排序4.选择排序5.插入排序1 快速排序 时间复杂度 O(nlogn)不稳定在大多数情况下都是适用的&#xff0c;尤其在数据量大的时候性能优越性更加明显 def quicksort(start, end, nums):if start > end:return flag nums[start]r_ptr endl_pt…

fillrect不填充被覆盖的区域 mfc_quot;条带覆盖quot;猜想的中二证明:quot;球面条线覆盖或点覆盖quot;积分π...

注销&#xff1a;“黎曼猜想”复平面质数单向“虚”圆柱螺旋&#xff1a;几何法证明&#xff0c;技术应用​zhuanlan.zhihu.com假设有这样一部针点打印机从球心对球面打印&#xff0c;外部有一台蓝牙打印&#xff0c;球面打印蓝牙条带打印同步&#xff0c;球面被覆盖&#xff0…

让你变厉害的7个底层思维

职场&认知洞察 丨 作者 / findyi这是findyi公众号分享的第89篇原创文章如果把你的思维比做操作系统&#xff0c;那思维模型就是一个个App。这些App会给你提供新的视角&#xff0c;快速帮你决策&#xff0c;提升你的工作效率。顶级的思维模型能提高你成功的可能性&#xff0…

后端学习 - 计算机网络

文章目录一 基本概念1 计算机网络体系结构2 时延二 应用层&#xff1a;HTTP1 请求和响应报文、常见 header2 URL & RESTful API3 HTTP 协议通信过程4 HTTP 方法5 HTTP 状态码6 短连接、长连接与流水线7 Cookie8 Session三 应用层&#xff1a;HTTPS1 加密方式2 证书认证四 应…

跟我一起学Redis之Redis配置文件啃了一遍之后,从尴尬变得有底气了(总结了一张思维图)...

前言秋高气爽的一天&#xff0c;那时候年轻帅气的我正在参照着搜索引擎写代码&#xff0c;迷之微笑般的敲着键盘(又从搜索引擎上找到代码案例啦)&#xff0c;突然领导在小隔间里传来了呼唤声&#xff0c;然后有了以下场景&#xff1a;领导&#xff1a;小Z&#xff0c;你过来一下…

1093芯片做正弦波逆变器_长途自驾游“缺电”如何选购正确车载逆变器,避开商家套路...

让车友三分钟就能看明白如何选择车用逆变器&#xff0c;节约车友时间。长途自驾游充电是一个难题&#xff0c;手机充电还好办&#xff0c;其他笔记本、电饭煲、车载冰箱或者无人机电池等充电就会用到220V电源&#xff0c;那就必须用到逆变器(逆变器就是将12V或24V直流电&#x…

Spring 相关问题

文章目录Spring1 Spring 框架中用到的设计模式2 Spring 事务、隔离级别3 单例 Bean 是线程安全的吗Spring IOC1 Spring 容器&#xff1a;BeanFactory & ApplicationContext2 依赖注入的两种方式3 Bean 的生命周期4 依赖注入的四个注解5 如何解决循环依赖Spring AOP1 基本概…

达梦php_pdo不同机器安装

现象 extensionphp74_pdo_dm.so extensionlibphp74_dm.so 普通安装达梦pdo.so后运行php报错&#xff1a;Unable to start PDO_DM module in Unknown on line 0 机器上没有达梦服务器环境。 步骤&#xff1a; 1. 拷贝达梦php_pdo到php拓展目录下&#xff0c;更新php.ini。…