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表中(當然現在很多信息也有是分表處理的,暫且不談,這是數據結構設計問題)的??瓷厦娴慕貓D,用戶信息的維護每次用戶數據的提交并不是提交了所有的個人信息數據,而只是部分提交的。
Update [dbo].[SysUser] Set Picture=@Picture where UserNo=@UserNoUpdate [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. 去配置化
那個時候還年輕啊,聽老前輩說配置化如何的牛逼,
新聞熱點
疑難解答