Git.Framework 是近几年工作的一些工作经验总结,虽不能和某些知名的框架相提并论,但是还是比较实用的。此框架经过三年多的升级和维护,已经具有较强的实用性,在此记录该框架的使用操作方式,贡献给公司第一线开发的技术人员们,感谢你们所付出的努力。

  一. 框架由来

    前几年我都是在互联网公司工作,做什么大型B2B,B2C网站。至于有多大就不提了,但是在其间做开发人员使用的技术的确比较辛苦,那个时候公司使用的技术还比较落后,最起码我是这么认为的,开发效率很低,一层不变的开发模式,Copy到想吐的代码。我是从事.NET技术开发的,当时公司还是使用的.NET2.0开发的,要知道2.0 和 3.0 差别还是挺大的,最起码在语法上。

    据说公司的框架是参考某个大型B2C网站的,据说当时公司某技术君就是从那里面出来的,使用微软企业库(Enterprise Library) , 于是一个B2C网站+ SNS社区 几乎所有的数据访问操作都是写的SQL语句,而且都是配置在某个文件夹的配置文件中。做过B2C或者SNS方面开发的可以想象得到有多少个SQL语句,当时我估计也有好几千个吧。于是我就想在原有的技术框架上改进这个操作,经过世事变迁最终改的体无完肤也就是现在所谓的的框架(Git.Framework)了。

  二. 写SQL语句复杂在哪里

    先给大家看看当时我们的SQL语句的写法,以及如何配置:

<dataCommand name="User.UpdateAllBase" database="Git" commandType="Text">
<commandText>
<![CDATA[
UPDATE [Gas_BasicCenter].[dbo].[User_Base]
SET [UserName] = @UserName
,[Email] = @Email
,[Password] = @Password
,[RegisterDate] = @RegisterDate
,[RegisterIp] = @RegisterIp
,[Status] = @Status
,[RegisterApplicationID] = @RegisterApplicationID
,[ActiveDate] = @ActiveDate
,[LastLoginDate] = @LastLoginDate
,[LastLoginApplicationID] = @LastLoginApplicationID
,[RegisterSource] = @RegisterSource
,[AuditStatus] = @AuditStatus
,[IsLogin] = @IsLogin
,[LoginCount] = @LoginCount
,[LastLoginIp] = @LastLoginIp
,[AuditUser] = @AuditUser
,[AuditDate] = @AuditDate
,[IsDeleted] = @IsDeleted
,[OLDApplicationID] = @OLDApplicationID
,[OLDID] = @OLDID
,[RowGuid] = @RowGuid
,[IMNum] = @IMNum
,[Phone] = @Phone
,[IsEmailValidate] = @IsEmailValidate
,[IsPhoneValidate] = @IsPhoneValidate
,[StepNum] = @StepNum
,[SaleCode]=@SaleCode
,[PasswordIM]=PasswordIM
,[ActiveIP]=@ActiveIP
,[CompanyType]=@CompanyType
Where UserId=@UserId
]]>
</commandText>
<parameters>
<param name="@UserId" dbType="Int32" direction="Input"/>
<param name="@UserName" dbType="String" direction="Input"/>
<param name="@Email" dbType="String" direction="Input"/>
<param name="@Password" dbType="String" direction="Input"/>
<param name="@RegisterDate" dbType="DateTime" direction="Input"/>
<param name="@RegisterIp" dbType="String" direction="Input"/>
<param name="@Status" dbType="Int32" direction="Input"/>
<param name="@RegisterApplicationID" dbType="Int32" direction="Input"/>
<param name="@ActiveDate" dbType="DateTime" direction="Input"/>
<param name="@LastLoginDate" dbType="DateTime" direction="Input"/>
<param name="@LastLoginApplicationID" dbType="Int32" direction="Input"/>
<param name="@RegisterSource" dbType="Int32" direction="Input"/>
<param name="@AuditStatus" dbType="Int32" direction="Input"/>
<param name="@IsLogin" dbType="Int16" direction="Input"/>
<param name="@LoginCount" dbType="Int32" direction="Input"/>
<param name="@LastLoginIp" dbType="String" direction="Input"/>
<param name="@AuditUser" dbType="String" direction="Input"/>
<param name="@AuditDate" dbType="DateTime" direction="Input"/>
<param name="@IsDeleted" dbType="Int16" direction="Input"/>
<param name="@OLDApplicationID" dbType="Int32" direction="Input"/>
<param name="@OLDID" dbType="Int32" direction="Input"/>
<param name="@RowGuid" dbType="String" direction="Input"/>
<param name="@IMNum" dbType="String" direction="Input"/>
<param name="@Phone" dbType="String" direction="Input"/>
<param name="@IsEmailValidate" dbType="Int32" direction="Input"/>
<param name="@IsPhoneValidate" dbType="Int32" direction="Input"/>
<param name="@StepNum" dbType="Int32" direction="Input"/>
<param name="@SaleCode" dbType="String" direction="Input"/>
<param name="@PasswordIM" dbType="String" direction="Input"/>
<param name="@ActiveIP" dbType="String" direction="Input"/>
<param name="@CompanyType" dbType="Int32" direction="Input"/>
</parameters>
</dataCommand>

SQL语句的配置

    情况1:看到上面的配置情况,很多人会联系到java中的某些框架,的确如此!个人对java涉略较少,后来在专门去查找了相关的资料。先不讨论SQL语句配置的格式,一个B2C网站+SNS社区需要多少这样的配置节点,项目在不断的增大,配置的难度到了让人无法接受的程度,而且我们无法知道是否有人已经写过一个同样的SQL语句。有多少人的离开或多或少与这个有关系,那个时候系统出现bug我就是每天盯着屏幕ctrl+h 全局查找这样的配置。

    情况2:SQL语句要每个自己去写,转化还必须要占位符的方式,然后要填充参数(<param name="@UserId" dbType="Int32" direction="Input"/> 也就是这个配置)。当然这些都是手工体力劳动,不难当时的确会写死人,比类文件中直接写SQL还要累。

    情况3: <dataCommand name="User.UpdateAllBase" database="Git" commandType="Text"> 配置项name在全局是唯一的,而系统中有很多个这样的配置文件,在这个文件中你查找不到,并不代表其他的文件没有,要每一个文件都去查找一遍然后才能定义这个name值。 database 这个也存在问题,这个是关联数据库的,因为系统中存在多个数据库,必须关联这个sql在哪个库里面执行。

    情况4:<parameters><param name="@UserId" dbType="Int32" direction="Input"/></parameters> 参数项的配置太多,特别是表的字段多的时候,修改好烦躁。有时候修改一个字段,有时候修改其中几个字段,要分别写不同的SQL来执行。

    情况N .... 就不多写了,各种问题足以让人抓狂,拿人钱财替人写代码天经地义的事情所以没办法,硬着头皮写。

  三. 以上问题的改进

    那个时候自己还是小兵啊,人微言轻的,也不敢提框架不好使,不然大牛会生气,后果很严重。想想也是完成好自己的工作就好了。

    配置问题的解决:

      上面贴出来的这个配置文件,其实一个定义好的标准格式,包括里面的参考类型以及名称都是定义好的,后来我使用CodeSmith自定义模板生成,很快速的结果手工写模板的问题,但是有一个问题就是模板没有那么灵活,我需要指定哪些字段要使用哪些不能使用,不是那么自能,只能全部给我生成出来,不过也算是方便了不少。

    实际问题考虑:

    (1) 登录系统,两个步骤: 1. 查询用户名和密码 2. 查询用户详细信息

    都是使用User表,我们可以查询User表的所有数据,但是往往登录的时候我们只会查询用户名和密码,查询用户详细的时候又不查询密码,甚至还有权限的问题,网络传输的问题。只能查询当前业务操作所需的字段。

SELECT [UserNo],[UserPwd] FROM [dbo].[SysUser]

SELECT [UserNo],[UserCode],[UserName],[UserPwd],[IsDelete] FROM [dbo].[SysUser]

    以上两个SQL语句有区别么,肯定有区别,查询的虽然是同一张表,但是返回的数据量大小不一样,为什么要这么做? 后来做信息化管理系统之后,也就不管这么多了都直接使用 Select * From Table 直接代替了。

    (2) 修改个人资料信息

    

    以前工作的项目图片不好找了,直接以博客园的为例。 假设用户头像,昵称,姓名,联系方式,毕业院校等信息是保持在User表中(当然现在很多信息也有是分表处理的,暂且不谈,这是数据结构设计问题)的。看上面的截图,用户信息的维护每次用户数据的提交并不是提交了所有的个人信息数据,而只是部分提交的。

Update [dbo].[SysUser] Set Picture=@Picture where UserNo=@UserNo

Update [dbo].[SysUser] Set LoginCount=@LoginCount,UserName=@UserName where UserNo=@UserNo

    诸如以上的这种太多的有共性但是又有区别的SQL语句太多了。

    后来使用的方式就是,先将某条数据全部查询出来,封装为一个Entity,然后修改Entity中的某个值,然后提交所有的Entity值,也就是修改表中的每一个字段,虽然处理的方式不好,但是比写N个这样的Sql语句配置省事多了。

  四. 如何检查配置项的重复问题

    颇为头疼的就是配置项name值的重复问题,N多个配置文件在某一个文件夹下,而文件夹中又有文件夹,查找不方便。

    软件的作用是什么,这个问题太过于广泛,但是有一点软件能够省人工,这个我是赞同。如何去查找重复项,那么就写一个小程序去区分好了。程序非常简单就是读取所有的配置文件,然后盘点是否有相同的项,这里不必多说,但是这个时候让我学到一个技能,就是如何写VS插件。

    之前写的工具已经不复存在,刚才在网上随便找了一篇文章关于这个的介绍,有兴趣可以参考一下:

    http://blog.csdn.net/clever101/article/details/8733799

  五. 实质性的问题如何解决

    以上种种手段都是暂时的解决问题,并没有达到治本的目的。于是自己开始筹划改进公司的技术框架。

    当时公司的技术体系就是这样,基于以前的工作经验,你想要去推翻公司的技术体系然后再重新来过是不太可能的,而且这个想法也是过于天真的,先不说你是否有这个能力,就算你有公司也不会冒这样的风险。

    当然当时我也提过技术框架的改进,当时领导评估风险太大,只能慢慢的去维护,也就是公司不可能专门设计组织或项目来搞这个东西,所以我只能自己业余时间来了。

    1. 数据操作使用ORM是不可避免的方向

      当时推崇过一段时间的Linq to SQL,包括Entity Framework ,也给公司提过,公司坚决的否定了,而后来我也对此嗤之以鼻因为其臃肿度,也不知道我是否理解错了。研究了好长一段时间的Linq to SQL ,Entity Framework 后来也不不再理这个。

      对比了一些较为常见的ORM,无论怎么吹嘘怎么怎么强大但都有其天生的缺陷性,没有一个是万能的。后来我也承认这些东西不可能是万能的,所谓真正好的框架是在实际的业务中提炼出来的,而不是你想怎样就能帮你解决问题的。

      加上要兼容公司原有的技术体系,所以这个只能改进不能重新来过。

    2. 去配置化

      那个时候还年轻啊,听老前辈说配置化如何的牛逼,特别是java程序员,java中的配置化多么牛逼,系统如何的灵活! 现在我始终认为那是一个骗局,要么是我没有理解其精髓,要么他们也就是照书上照本宣科的胡乱说一通。这不是重点,重点是如果我改进一定要去配置化,因为配置已经让我们身处火热之中。

    3. 蛋疼的跨数据库查询

      如果在同一个数据库实例中,两个或者多个数据库跨库查询貌似还比较好解决,如果涉及到跨网络肿么办,貌似没有ORM专门去解决这个问题,或许是我孤陋寡闻了。在公司的改进中我提议是跨库查询还是在内存中去处理,就是多次去查询数据库然后内存整合数据,后来也证明了我还是有点明智的,多数据库分离到不同的服务器上了。

    

  六. 本文小结

    在平时的工作中还有很多类似的问题,不知道是因为自己遇到的东西少了还是其他的原因,都是一些非常低级而又苦恼的问题,真正有什么科研技术的问题我真没有遇到。决定写这个文章只是为了总结一下自己这些年的工作,觉得有很多地方是值得借鉴的。

    1. 在一个技术体系已经成型的团队里面,不要妄想去推翻现有的技术体系,虽然这样的体系问题非常多,多到让你无法接受,你要做的是改进,去提升,而不是抱怨问题太多。"要么忍要么滚" 这是我的格言。

    2. 问题多是一个团队的正常表现,如果没有问题团队也就不需要你了。

    3. 只要是问题肯定就会有解决的办法,如果你自己没有去尝试过,不要轻易去评判别人的对与错,否则就闭嘴。

    4. 刚出道或者刚进公司不要认为领导都是傻逼,如果你有这种想法只能说明你比他们更傻逼,几年前我也站在骂领导是傻逼的行列。

    5. 任何一个公司的技术体系都有值得你去借鉴学习的,只要它摆在那里就不会是垃圾。

    如今自己做实施了,虽然程序还写,相比之前心情放松了很多,不是为了丢弃代码,只是有时候该换一种方式去思考或许程序会写的更好一点。

    成功的定义永远只有一个,那就是对结果负责!

    

Git.Framework 框架随手记--历史原因的更多相关文章

  1. Git.Framework 框架随手记--存储过程简化

    在很多的ORM中对存储过程操作都是一个棘手的地方,因为存储过程是一段预编译的代码,其中可以包含很多处理过程.在Git.Framework中也同样存在这样的问题,目前没有能力解决这个问题.但是对于存储过 ...

  2. Git.Framework 框架随手记--ORM条件组合

    在上一篇<Git.Framework 框架随手记--ORM新增操作>中简单记录了如何对数据进行删除和修改,其用法都非常简单,在文章中提到了Where()方法,本文将详述Where() 等条 ...

  3. Git.Framework 框架随手记--ORM编辑删除

    前面一篇文章<Git.Framework 框架随手记--ORM新增操作>主要讲解了如何使用Git.Framework往数据库中添加数据.其操作过程相对简单,本章主要记录如何编辑数据和修改数 ...

  4. Git.Framework 框架随手记--ORM项目工程

    前面已经简单介绍过了该框架(不一定是框架),本文开始重点记录其使用过程.可能记录的内容不是太详尽,框架也可能非常烂,但是里面的代码句句是实战项目所得.本文非教唆之类的文章,也非批判之类的文章,更不是炫 ...

  5. Git.Framework 框架随手记--IIS7运行序列化问题

    客户反馈系统又登录不了,这是最近几次连续出现相同的问题,从日志反应情况来看: 日志级别:[info] 日志位置:Git.Framework.Resource.ResourceManager 日志时间: ...

  6. Git.Framework 框架随手记--SQL配置文件的使用

    前面几篇文章讲到了如何使用框架进行简单结构的增删改查操作,由于个人能力有限在对于复杂的SQL操作面前也是无能为力,只能自己动手来写SQL语句.在Git.Framework中提供了一个公共的接口来直接操 ...

  7. Git.Framework 框架随手记--ORM查询数据集合 二

    一.  分组查询 在SQL中使用Group By 来对数据分组,在实际中分组中一般与聚合函数一并使用.在Git.Framework中提供了相应的分组方法 DataTable Group(T entit ...

  8. Git.Framework 框架随手记--ORM新增操作

    本篇主要记录具体如何新增数据,废话不多说,开始进入正文. 一. 生成工程结构 上一篇已经说到了如何生成工程结构,这里在累述一次. 1. 新建项目总体结构 使用VS新建项目结构,分层结构可以随意.我们使 ...

  9. Git.Framework 框架随手记-- 分享一个"比较垃圾"的项目

    本文主要分享一个Git.Framework 开发的一个项目的部分源码,此项目代码"比较垃圾",所以请各位码农,码畜,码神,码圣勿喷!发此文只为记录工作问题以及分享问题! 一. 项目 ...

随机推荐

  1. 在Myeclipse中配置Maven

    第一步:下载maven安装包,配置环境变量M2_HOME;变量值为maven的解压目录. 第二步:在eclipse4.0之前的版本需要安装maven插件,方法即:将maven插件包复制到eclipse ...

  2. php基本语法

    <?phpecho "hello test01";$var ="PHP";echo "$var";echo "<br ...

  3. 第十章 MySQL 常用函数

    第十章 MySQL 常用函数 第一节:日期和时间函数 1,CURDATE() 返回当前日期:2,CURTIME() 返回当前时间:3,MONTH(d) 返回日期 d 中的月份值,范围是 1~12 第二 ...

  4. Xamarin.Android splash页面瞬间响应_避免APP启动闪白屏

    Application和Activity中的onCreate都进行了优化,基本没有耗时操作,但是启动应用之后还是会闪现一下白色背景,然后才进入Splash页面,对比了一下QQ.微信.微博等客户端,点击 ...

  5. ipc之消息队列

    消息队列以链表的方式将消息存储于内核中,调用msgsnd,msgrcv函数往消息队列里面投送,取出指定的消息. 创建一个消息队列 生成一个消息队列或者获取已有消息队列id #include <s ...

  6. 在AngularJS中实现自定义表单验证

    除了一些已经定义好了的验证(例如 必填项.最小长度.最大长度)之外,更常用的,还是需要我们自己定义表单验证,这样才能对于项目中遇到的很多非常规问题给出自己的合适的解决方案. 在表单中控制变量 表单的属 ...

  7. pixel art之 hqx 算法

    在去年的时候,偶然看到hqx算法. 一个高质量的插值放大算法. 与双线性插值等插值算法相比,这个算法放大后对人眼保护相对比较好. 没有双线性插值看起来模糊,固然,也抽空把算法简单优化了一下. 官网及代 ...

  8. Vim配置及说明——IDE编程环境

    Vim配置及说明——IDE编程环境 Vim配置及说明——IDE编程环境 1.基本及字体 2.插件管理 3.主题风格 4.窗口设置 5.目录树导航 6.标签导航 7.taglist 8.多文档编辑 9. ...

  9. HDU 1850 Being a Good Boy in Spring Festival

    此题先考虑第一种,5 7 9的情况,先手如果想赢,则必定要把异或值变为0,因为随便取,所以此处的异或指的是对堆中的石子数进行异或,而非异或其SG函数. 首先7^9=14,因为要异或为0,则5要变成14 ...

  10. AC日记——积木大赛 洛谷 P1969

    题目描述 春春幼儿园举办了一年一度的“积木大赛”.今年比赛的内容是搭建一座宽度为n的大厦,大厦可以看成由n块宽度为1的积木组成,第i块积木的最终高度需要是hi. 在搭建开始之前,没有任何积木(可以看成 ...