关于序列化信息映射的问题

前天犯了一个不大不小的错误,由于上层映射的属性没有删除,直接修改了SQL,造成数据映射发生错位,进而数据异常。觉得这类错误,当时是想到了的,但是还是错误发生了。进而思考了一下,原来Java也有类似的东西,ORM映射。那个时候并没有出过类似的问题,后来看了一下客户端读取csv的时候,有了进一步的思考。OO语言的映射方式和注意点和C++映射方式的注意点是有区分的。并且变向也体现出来OO语言的便利性。

假如让我用代码实现一个映射关系的化,我第一个想到的是反射机制,反射提供了很方便的反序列化,反射是和序列化相关的。都说反射消耗效率,那么看我下面用C#写的一个测试代码,10W次通过反射创建实体类和通过普通的直接创建的时间对比。

   1: using System;
   2: using System.Collections.Generic;
   3: using System.Linq;
   4: using System.Text;
   5: using System.Threading.Tasks;
   6: using System.Reflection;
   7:  
   8: namespace test
   9: {
  10:     class Program
  11:     {
  12:         static void Main(string[] args)
  13:         {
  14:             Console.Write("Reflection begin:{0}s,{1}ms\n", DateTime.Now.Second,DateTime.Now.Millisecond);
  15:             for (int i = 0; i < 1000*10*10; i++)
  16:             {
  17:                 Test ect = (Test)Assembly.GetExecutingAssembly().CreateInstance("test.Test");
  18:             }
  19:             DateTime stopTime = DateTime.Now;
  20:             Console.Write("Reflection end:{0}s,{0}ms\n", DateTime.Now.Second, DateTime.Now.Millisecond);
  21:  
  22:             Console.Write("Normal begin:{0}s,{0}ms\n", DateTime.Now.Second, DateTime.Now.Millisecond);
  23:             for (int i = 0; i < 1000 * 10 * 10; i++)
  24:             {
  25:                 Test ect = (Test)Assembly.GetExecutingAssembly().CreateInstance("test.Test");
  26:             }
  27:             Console.Write("Normal end:{0}s,{0}ms", DateTime.Now.Second, DateTime.Now.Millisecond);
  28:             Console.ReadKey();
  29:         }
  30:     }
  31:  
  32:     public class Test
  33:     {
  34:         public int test_0 { get; set; }
  35:         public int test_1 { get; set; }
  36:         public int test_2 { get; set; }
  37:         public int test_3 { get; set; }
  38:         public int test_4 { get; set; }
  39:         public int test_5 { get; set; }
  40:         public int test_6 { get; set; }
  41:         public int test_7 { get; set; }
  42:         public int test_8 { get; set; }
  43:         public int test_9 { get; set; }
  44:         public int test_10 { get; set; }
  45:         public int test_11 { get; set; }
  46:         public int test_12 { get; set; }
  47:         public int test_13 { get; set; }
  48:         public int test_14 { get; set; }
  49:     }
  50: }

输出如下:

反射在于效率消耗上还是挺大的,看起来倒是很恐怖,但是少写了很多的东西,并且策划表也很难到10W这个量级。更何况一个SQL查询出来更是不可能一下子这么多数据。基本差别还是在毫秒以内。

如果客户端采用反射机制来读取csv表,那么程序这边只需要保证变量名和表里面的填写的头名字一致就可以了,通过反射自动创建实例和方法,只要保证类名和csv对应即可。如果出现错误也是编译时错误,并且异常控制而言更精准。不会造成运行时才会出错的情况且方便只需要修改一处就可以了,不需要两头名字还需要对齐之类的操作,当列多的时候策划频繁更改表的时候,能够保证程序这里第一时间能够反映出来,并且异常提示精准。

然而C++就没这么好命了,C++没有反射。现在仔细一看csv表解析的映射和DBServer处理的映射手法是一致的。csv还好是采用字符串做的一一匹配不会出现错位的情况。然而DB数据的映射并没有根据列名做一个精准对应,而是根据列数组下标形式做的结果集对应。编译时是不过检查的!运行时不看到也不见得能知道错!

C++很类似于C语言,C++更加方便与内存映射。这就很直接牵扯到一个序列化,反序列化的问题。我们只能定义序列化和反序列化方法来自己做处理。当然也可以通过json,xml,protobuf来做序列化和反序列化的操作来减少运行时错误。

补充一点:对于异常的处理,断言,错误告警等处理,如果在效率考量的前提下尽量还是控制在编译时,进而再是启动时运行,进而再是操作时的运行!

时间: 2024-10-28 05:51:32

关于序列化信息映射的问题的相关文章

使用attribute + 扩展方法完成 enum中field的信息映射

attribute可用来做信息映射,比起Dictionary或者Tuple,attribute显得更灵活,解耦,并可对应多种类型 以下是一个enum中的field的信息映射 1. 创建field attribute [AttributeUsage(AttributeTargets.Field)] public class JobActionMetadatAttribute : Attribute { public JobActionUIType UIType { get; private set

Tinking in Java ---Java的NIO和对象序列化

前面一篇博客的IO被称为经典IO,因为他们大多数都是从Java1.0开始就有了的:然后今天这篇博客是关于NIO的,所以的NIO其实就是JDK从1.4开始,Java提供的一系列改进的输入/输出处理的新功能,这些新功能被统称为新IO(New IO ,简称NIO).另一个概念对象序列化指的是将那些实现了Serializable接口的对象转换成一个字节序列,并能够在以后将这个字节序列再转换成原来的对象.这样的话我们就可以将对象写入磁盘中,或者是将对象在网络上进行传递.下面就对这两个内容进行总结. 一.J

MyBatis入门第2天--高级映射与查询缓存

文档版本 开发工具 测试平台 工程名字 日期 作者 备注 V1.0 2016.06.28 lutianfei none mybatis框架执行过程: 1.配置mybatis的配置文件,SqlMapConfig.xml(名称不固定) 2.通过配置文件,加载mybatis运行环境,创建SqlSessionFactory会话工厂 SqlSessionFactory在实际使用时按单例方式. 3.通过SqlSessionFactory创建SqlSession SqlSession是一个面向用户接口(提供操

MyBatis结果映射与MyBatis缓存初探学习记录

MyBatis高级结果映射(一对一.一对多.多对多的映射),延迟加载,查询缓存(一级缓存),二级缓存的学习记录: 1.学习中所使用到的例子,数据库基础分析 2.高级结果映射 3.延迟加载 4.一级缓存 5.二级缓存 1.学习中所使用到的例子,数据库基础分析 2.高级结果映射 resultType与resultMap: resultType来进行结果映射,数据库中查询几条记录,那么在resultType就会映射成几条记录:resultType映射是一个平铺式的映射: resultMap比较繁琐一些

【MyBatis学习08】高级映射之一对一查询

从这一篇博文开始,将总结一下mybatis中的几个高级映射,即一对一.一对多.多对多查询,这篇先总结一下mybatis中的一对一查询. 为了模拟这些需求,事先要建立几个表,不同的表之间将对应上面提到的不同的映射,为此,我建立4个表,如下: DROP TABLE IF EXISTS `items`; DROP TABLE IF EXISTS `orders`; DROP TABLE IF EXISTS `user`; DROP TABLE IF EXISTS `orderdetail`; /*it

Java 序列化Serializable

1.什么是序列化和反序列化Serialization(序列化)是一种将对象以一连串的字节描述的过程:反序列化deserialization是一种将这些字节重建成一个对象的过程.   2.什么情况下需要序列化 a)当你想把的内存中的对象保存到一个文件中或者数据库中时候:b)当你想用套接字在网络上传送对象的时候:c)当你想通过RMI传输对象的时候: 3.如何实现序列化 将需要序列化的类实现Serializable接口就可以了,Serializable接口中没有任何方法,可以理解为一个标记,即表明这个

初探Java序列化(Serialization)

Serialization(序列化)是一种将对象以一连串的字节描述的过程:反序列化Deserialization是一种将这些字节重建成一个对象的过程.[字节流的来回转换] Java中,一切都是对象,在分布式环境中经常需要将Object从这一端网络或设备传递到另一端.这就需要有一种可以在两端传输数据的协议.Java序列化机制就是为了解决这个问题而产生. 将对象状态转换成字节流之后,可以用java.io包中各种字节流的类将其保存到文件中,管道到另一线程中或通过网络连接将对象数据发送到另一主机.对象序

Hibernate4.x之映射文件

POJO类和数据库的映射文件*.hbm.xml POJO类和关系数据库之间的映射可以用一个XML文档来定义 通过POJO类的数据库映射文件,Hibernate可以理解持久化类和数据库表之间的对应关系,也可以理解持久化类属性与数据库表列之间的对应关系 在运行时Hibernate将根据这个映射文件来生成各种SQL语句 映射文件的扩展名为.hbm.xml 映射文件说明 hibernate-mapping -类层次:class 主键:id 基本类型:property 实体引用类:many-to-one

Mybatis学习记录(六)----Mybatis的高级映射

作者:余家小子 1.一对多查询 1.1 需求 查询订单及订单明细的信息. 1.2 sql语句 确定主查询表:订单表 确定关联查询表:订单明细表 在一对一查询基础上添加订单明细表关联即可. SELECT orders.*, USER.username, USER.sex, USER.address, orderdetail.id orderdetail_id, orderdetail.items_id, orderdetail.items_num, orderdetail.orders_id FR