<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    qileilove

    blog已經(jīng)轉(zhuǎn)移至github,大家請訪問 http://qaseven.github.io/

    Web開發(fā)測試中的18個關(guān)鍵性錯誤

     前幾年,我有機會能參與一些有趣的項目,并且獨立完成開發(fā)、升級、重構(gòu)以及新功能的開發(fā)等工作。
      本文總結(jié)了一些PHP程序員在Web開發(fā)中經(jīng)常 忽略的關(guān)鍵錯誤,尤其是在處理中大型的項目上問題更為突出。典型的錯誤表現(xiàn)在不能很好區(qū)分各種開發(fā)環(huán)境和沒有使用緩存和備份等。
      下面以PHP為例,但是其核心思想對每一個Web程序員都是適用的。
      應(yīng)用程序級別的錯誤
      1、在開發(fā)階段關(guān)閉了錯誤報告
      我唯一想問的是:為什么?為什么在開發(fā)的時候要關(guān)閉錯誤報告?
      PHP有很多級別的錯誤報告,在開發(fā)階段我們必須將它們?nèi)块_啟。
      如果你覺得錯誤不會發(fā)生,那么你把程序太理想化了,在現(xiàn)實世界中,錯誤是必然的。error_reporting和display_error是兩個完全不同的方法,error_reporting()設(shè)置了錯誤的級別,而display_errors則是設(shè)置錯誤信息是否要被輸出。
      在開發(fā)階段,錯誤報告的級別應(yīng)該設(shè)置成最高的,比如以下設(shè)置: error_reporting(E_ALL);以及ini_set(‘display_errors’, true);
      2、淹沒錯誤
      和上一點相反,很多程序員喜歡將錯誤淹沒了,你明知道錯誤會發(fā)生,但是你選擇將錯誤隱藏掉,然后可以早早回家睡大覺,殊不知將來會發(fā)生更嚴(yán)重的錯誤。
      3、代碼中任何地方都沒有使用日志
      軟件開發(fā)的一開始你就要牢記使用日志,不能到項目結(jié)束了才去彌補日志功能。很多程序員都會用這樣或那樣的手段進行日志記錄,但是很少有人能真正用日志來記錄異常信息,試問一個沒有人查看的日志系統(tǒng)有什么用?
      4、沒有使用緩存
      在的應(yīng)用系統(tǒng)中,我們可以在多個系統(tǒng)層次上使用緩存,比如在服務(wù)端、應(yīng)用端和數(shù)據(jù)庫端等。和日志一樣,緩存也應(yīng)該在一開始就應(yīng)用到系統(tǒng)中去,你可以在開發(fā)階段禁用緩存,等到了產(chǎn)品發(fā)布后再將緩存開啟。
      5、丟棄了最佳實踐和設(shè)計模式
      你看到過多少人使用自己的密碼加密算法?很遺憾的告訴你,有很多,因為他們認(rèn)為將更了解它。
      最好的實踐方式和設(shè)計模式已經(jīng)由前輩創(chuàng)建了,這往往比你自己再造一個輪子要來的簡單奏效,我們開發(fā)者只需要熟練掌握這些設(shè)計模式并且合理地應(yīng)用在項目中即可,比如一些加密算法。
      6、沒有使用自動化測試
      在每一個Web項目中都會使用到測試,就像日志一樣,如果沒有人管理和使用,那么測試也是一無是處的。
      運行測試工程是一項枯燥乏味的工作,幸好有一系列工具幫助我們實現(xiàn)自動化測試。在PHP開發(fā)中,有一款很好的測試工具叫Jenkins,使用起來非常方便。
      7、沒有做代碼審查
      在團隊中工作是一項非常大的挑戰(zhàn),因為每一個成員都有自己不同的工作習(xí)慣和方式,如果沒有良好的規(guī)范,那么項目開發(fā)就會走很多彎路。
      團隊中的每一個成員都應(yīng)該互相審查代碼,就像單元測試,它可以幫助項目變得更加干凈和一致性。
      8、編程只考慮理想情況
      你是否遇到過自己或者別人的代碼在交到客戶手中后經(jīng)常出問題,甚至是亂套了?我當(dāng)然沒有。
      出現(xiàn)這種情況往往是因為開發(fā)者懶惰了,只考慮了理想情況,這會導(dǎo)致數(shù)據(jù)庫崩潰了、PHP發(fā)生致命錯誤、甚至是服務(wù)器被黑。程序員在寫代碼時不僅要考慮最理想的情況,更要考慮最壞的情況,思考全面,才能讓代碼覆蓋所有的情況。
      9、沒有正確運用面向?qū)ο缶幊痰乃枷?/strong>
      大部分PHP初學(xué)者都不會再其代碼中運用面向?qū)ο蟮乃枷耄驗檫@個概念在剛開始的時候很難理解。
      當(dāng)然面向?qū)ο蟮母拍畈⒉皇呛唵蔚貙⒁恍╊惤M織在一起。
      對象、屬性、方法、繼承和封裝等都是OOP中最基本的概念,開發(fā)者正確使用了面向?qū)ο笤O(shè)計模式后,就有能力寫出更干凈、更有擴展性的代碼了。
    10、“飛行模式”(On-the-fly)編程
      大部分開發(fā)者都會遇到這樣的情況:“快,客戶需要一項新功能,要能運行ASAP”,于是你就在源代碼上新增一些功能,然后直接上傳到正在運行的服務(wù)器上,這種編程方式我們稱其為“飛行模式”(On-the-fly)編程。
      我們在開發(fā)軟件時,尤其是中大型的項目,都必須按照工作流程來進行分析、編程和發(fā)布,這將大大減少未來軟件的bug。這種“飛行模式”并不可取。
      數(shù)據(jù)庫級別的錯誤
      11、沒有將數(shù)據(jù)庫讀寫分離
      為了能長時間運行復(fù)雜的系統(tǒng),每一個程序員都應(yīng)該考慮到系統(tǒng)的可擴展性,系統(tǒng)99%的時間都不需要考慮擴展,因為并沒有如此大的流量。
      為什么要數(shù)據(jù)庫讀寫分離?
      在每一個系統(tǒng)中,數(shù)據(jù)庫將會是第一個出現(xiàn)的瓶頸,在大流量的沖擊下,數(shù)據(jù)庫很可能將會是第一個陣亡的。所以大部分情況下我們會用多個數(shù)據(jù)庫來分散流量,開發(fā)者經(jīng)常會使用Master – Slave模式或者Master – Master 模式。Master – Slave是最受歡迎的一種數(shù)據(jù)庫分壓模式,它會將指定的select語句路由到每一個Slave服務(wù)器,這樣Master服務(wù)器的壓力會減輕不少。
      12、代碼只能連接到一個數(shù)據(jù)庫
      這和上一個錯誤非常像,但是開發(fā)者有時候因為某些原因需要連接到多個數(shù)據(jù)庫,比如你會將用戶日志、活動信息流、實時數(shù)據(jù)分析等高負(fù)載的數(shù)據(jù)放到不同的數(shù)據(jù)庫中來緩解對主數(shù)據(jù)庫的壓力。
      13、沒有檢測數(shù)據(jù)庫漏洞
      如果你不對數(shù)據(jù)庫進行漏洞檢測,就相當(dāng)于給大部分黑客敞開了服務(wù)器的大門。
      在眾多漏洞中,數(shù)據(jù)庫漏洞是最脆弱的,最常見的就是SQL注入。因此定期做數(shù)據(jù)庫漏洞檢測還是很有必要的。
      14、數(shù)據(jù)表不建索引
      索引在數(shù)據(jù)表中有著非常重要的作用,合適的索引可以提高每張表的性能,這里有一篇文章就講述了如何創(chuàng)建索引以及何時創(chuàng)建索引。
      15、沒有使用事務(wù)機制
      數(shù)據(jù)完整性對Web系統(tǒng)非常重要,如果數(shù)據(jù)一致性發(fā)生錯誤,那么整個系統(tǒng)都會崩潰并且難以修復(fù)。合理地運用數(shù)據(jù)庫的事務(wù)機制將有效地解決這個問題。比如你要保存用戶數(shù)據(jù),在table1中有e-mail, username和password,table2中有first name, last name,和gender age。我們可以利用事務(wù)對兩張表更新時保證數(shù)據(jù)同時被更新或者同時不被更新。
      16、沒有加密敏感數(shù)據(jù)
      對于數(shù)據(jù)庫中的敏感信息,如果你不對它們進行加密,或者用簡單的算法進行加密,那么在2014年你肯定會遇到一些麻煩的問題,黑客們一旦入侵你的數(shù)據(jù)庫,用戶的密碼或者其他重要信息就會一覽無余。
      PHP5.5中提供了一個哈希加密方法,使用如下:
      $hash = password_hash( $password, PASSWORD_BCRYPT );
      17、沒有備份
      看到下面這張圖片沒,如果遇到這樣的情況,你又沒有備份,那么一切都o(jì)ver了。
      18、沒有監(jiān)控
      沒有監(jiān)控,你將不知道接下來會發(fā)生什么事情,對于監(jiān)控,要注意以下幾個問題:
      有多少人可以直接訪問這個應(yīng)用服務(wù)?
      服務(wù)器是否在高負(fù)載下運行?
      我們需要用另一臺數(shù)據(jù)庫服務(wù)器來擴展系統(tǒng)嗎?
      應(yīng)用系統(tǒng)的失敗點在哪里?
      系統(tǒng)目前正處于離線狀態(tài)嗎?

    posted @ 2014-09-26 10:08 順其自然EVO 閱讀(181) | 評論 (0)編輯 收藏

    性能測試中如何選取被測對象的業(yè)務(wù)邏輯

    很多搞性能測試的人員,只會跟著網(wǎng)上、前輩教導(dǎo)的方法進行測試:挑選業(yè)務(wù)邏輯中并發(fā)量、訪問量最高的業(yè)務(wù)邏輯、結(jié)合讀寫等業(yè)務(wù)進行測試,然后取整條業(yè)務(wù)邏輯(模擬用戶全流程動作)的邏輯進行測試;結(jié)果就是:準(zhǔn)備大堆的測試數(shù)據(jù),復(fù)雜的準(zhǔn)備工作;其實那些數(shù)據(jù)只是用來滿足業(yè)務(wù)流中的條件,而不是真的能產(chǎn)生壓力的部分;
      筆者采用的方法:
      1、B/S結(jié)構(gòu)中,用戶操作功能流程其實是前端js依次調(diào)用不同的CGI接口,后臺實現(xiàn)上面其實并沒有強依賴關(guān)系(只要滿足對應(yīng)條件進行發(fā)包都能執(zhí)行)。
      所以,首先挑選業(yè)務(wù)邏輯中用戶訪問最高的流程,然后從流程中挑選調(diào)用次數(shù)、壓力最大的CGI接口;這樣聚焦于對應(yīng)的測試對象,可以避免很多無用的測試數(shù)據(jù);
      2、根據(jù)業(yè)務(wù)邏輯,分析被測對象券流程中,所調(diào)用的接口,對于安全旁路、分支判斷等,根據(jù)情況進行取舍(有些業(yè)務(wù)只測試某個CGI,有些是測試全平臺,測試中根據(jù)情況進行聚焦)。
      3、根據(jù)分析情況直接修改被測對象代碼:通常接口調(diào)用形式都會使用iret方式來判斷,例如:
    /*原有代碼----begin*/
    iret=xxx.call(args1,args2,args3);
    if(iret != 0){
    print("xxxxx");
    break;
    }
    /*原有代碼----end*/
    iret=0 ---------- 添加iret=0,讓程序繼續(xù)走。
      這樣不會影響外部接口調(diào)用次數(shù),不會影響網(wǎng)絡(luò)發(fā)包次數(shù),但可能會影響單個網(wǎng)絡(luò)包大小進而影響網(wǎng)絡(luò)流量;同時稍微增加cpu負(fù)擔(dān)(賦值造成內(nèi)存讀寫)。但其實我們要測的是業(yè)務(wù)主流程,而不是外部接口(外部接口如果有需要可單獨進行壓測),所以筆者認(rèn)為也是可以采取此種方案,而不需要準(zhǔn)備一大堆無用的數(shù)據(jù),只需有針對性的進行業(yè)務(wù)邏輯選取即可;

    posted @ 2014-09-26 10:07 順其自然EVO 閱讀(216) | 評論 (0)編輯 收藏

    測試用例設(shè)計的價值與誤區(qū)

    測試用例是一系列特定的軟件行為,用于驗證軟件的某特定功能、檢查軟件能否正確處理某種出錯行為、或者檢查其他一些軟件質(zhì)量衡量的屬性 (如性能、安全、可靠性等)。 一個測試用例是一個正式的文件或記錄,描述了測試活動是怎樣具體執(zhí)行的。測試用例設(shè)計的目的就是發(fā)現(xiàn)缺陷,但是測試用例的用處遠(yuǎn)遠(yuǎn)超出發(fā)現(xiàn)缺陷。
      測試用例文檔的一些好處如下:
      1、歷史借鑒:測試用例的存在要遠(yuǎn)遠(yuǎn)超過產(chǎn)品發(fā)布。持續(xù)工程(Sustained engineering)以及產(chǎn)品未來版本的負(fù)責(zé)人往往需要借用測試用例來了解測試過什么,以及是如何測試的。測試用例文檔和一個有組織的儲存系統(tǒng)對長期支持或修訂產(chǎn)品的一部分是至關(guān)重要的策略。----注----為了便于后來者對于測試用例的使用和借鑒,測試用例設(shè)計要盡量描述準(zhǔn)確、步驟清晰。
      2、測試進展跟蹤:通過測試用例文檔,可以跟蹤一些額外的屬性,如測試用例的執(zhí)行數(shù)目,測試用例的通過或失敗數(shù)目,以及每個功能領(lǐng)域的測試用例總數(shù)。 ----注----在測試用例管理系統(tǒng)中要準(zhǔn)確且實際地描述用例的執(zhí)行結(jié)果,包括其他必填的屬性,便于分期人員從各個屬性和維度進行測試過程分析。
      3、可重復(fù)性:好的測試用例文檔可以由任何人在任何時候執(zhí)行。這同樣適用于自動和手動的測試用例。重復(fù)準(zhǔn)確地執(zhí)行同樣的測試對重現(xiàn)步驟或檢測回歸是至關(guān)重要的。 ----注----測試用例的描述要準(zhǔn)確、全面,要能保證除自己以外的測試人員能正確理解和執(zhí)行該用例。
      測試用例文檔也有缺點:
      1、建立文檔的時間:如果建立測試用例文檔的時間比運行測試用例所需的時間還長,建立測試用例文檔也許就沒有意義了。經(jīng)常有這樣的情況,即測試用例只需要在一個單一的環(huán)境下執(zhí)行寥寥幾次。 ----注----但是從測試用例價值的角度來考慮,建立測試用例文檔卻是個不可裁剪的過程。但是,這個缺點會隨著用例設(shè)計的熟練程度的提高以及用例設(shè)計平均時間成本的減小而逐漸減弱。
      2、功能變化引起測試用例過期:建立測試用例所需的時間很可能因功能經(jīng)常變化而增加,以至于失去控制。如果測試用例的功能領(lǐng)域變化頻繁,建立測試用例文檔就不一定是明智的。這種場景之一是嘗試寫測試用例以驗證用戶界面組件。 ----注----功能需求或者設(shè)計和實現(xiàn)的變化常常導(dǎo)致測試用例需要調(diào)整和修改,甚至有時候修改用例的時間會超過新建用例的時間。因此,在用例設(shè)計過程中,保持與設(shè)計、開發(fā)人員的密切溝通,及時了解功能變化的情況十分必要。否則后期再修改用例的時間成本很大。當(dāng)然,在軟件開發(fā)后期,軟件需求和設(shè)計盡量保持穩(wěn)定是最合適的。
      3、很難設(shè)想讀者的知識:寫測試用例的人往往極為熟悉被測試的功能。這些人常犯的錯誤是在測試用例中使用術(shù)語或縮寫,而將來運行測試用例的人很可能看不懂這些測試用例。出現(xiàn)這種情況出現(xiàn)時,測試用例已不再能準(zhǔn)確地重復(fù),測試用例也失去了這關(guān)鍵屬性之一。 ----注----為了用例便于后來者正常使用該用例,用例設(shè)計應(yīng)盡量避免使用只有自己熟悉的專業(yè)詞匯和縮寫詞,或者存在用例描述太簡潔但自己能理解的情況。
      測試用例設(shè)計的誤區(qū)
      創(chuàng)建好的測試用例是一個困難的過程。即使一個錯誤就可以毀掉測試用例的意圖。一些易出問題的領(lǐng)域如下:
      1、步驟缺乏:  匆忙建立的測試用例或假設(shè)測試用例的一些步驟會被執(zhí)行而未將它們包括在測試用例里是非常常見的錯誤, 它造成不能準(zhǔn)確地重復(fù)。----注----必要的用例步驟不能省,避免在執(zhí)行用例的時候出現(xiàn)描述不清導(dǎo)致模棱兩可的情況發(fā)生,從而影響案例執(zhí)行進度。
      2、太多細(xì)節(jié): 雖然提供具體和足夠的信息很重要,不必要的字詞或冗長的解釋,會使測試用例難以遵循。僅需包含足夠的信息以便精確地運行測試用例。  ----注----太多的細(xì)節(jié)描述會增加案例設(shè)計的成本,適可而止即可。
      3、行話太多: 不要以為運行測試用例的人(包括產(chǎn)品技術(shù)支持和持續(xù)工程)都知道所有你寫的縮略語,代號和縮寫。闡明任何對整個產(chǎn)品生命周期有價值和必要的信息。  ----注----同上缺點3的注釋。
      4、不明確的通過/失敗標(biāo)準(zhǔn): 如果運行測試后,不清楚測試是否通過或失敗,那測試用例是毫無用處的。----注----測試用例的預(yù)期結(jié)果一定要準(zhǔn)確和清晰。對于測試后存在不符合預(yù)期結(jié)果的情況,即可判斷為失敗,全部符合預(yù)期結(jié)果則為成功。

    posted @ 2014-09-26 10:06 順其自然EVO 閱讀(161) | 評論 (0)編輯 收藏

    JDBC連接MySQL數(shù)據(jù)庫及演示樣例

     JDBC是Sun公司制定的一個能夠用Java語言連接數(shù)據(jù)庫的技術(shù)。
      一、JDBC基礎(chǔ)知識
      JDBC(Java Data Base Connectivity,java數(shù)據(jù)庫連接)是一種用于執(zhí)行SQL語句的Java API,能夠為多種關(guān)系數(shù)據(jù)庫提供統(tǒng)一訪問,它由一組用Java語言編寫的類和接口組成。JDBC為數(shù)據(jù)庫開發(fā)者提供了一個標(biāo)準(zhǔn)的API,據(jù)此能夠構(gòu)建更高級的工具和接口,使數(shù)據(jù)庫開發(fā)者能夠用純 Java API 編寫數(shù)據(jù)庫應(yīng)用程序,而且可跨平臺執(zhí)行,而且不受數(shù)據(jù)庫供應(yīng)商的限制。
      1、跨平臺執(zhí)行:這是繼承了Java語言的“一次編譯,到處執(zhí)行”的特點;
      2、不受數(shù)據(jù)庫供應(yīng)商的限制:巧妙在于JDBC設(shè)有兩種接口,一個是面向應(yīng)用程序?qū)?,其作用是使得開發(fā)者通過SQL調(diào)用數(shù)據(jù)庫和處理結(jié)果,而不須要考慮數(shù)據(jù)庫的提供商;還有一個是驅(qū)動程序?qū)樱幚砼c詳細(xì)驅(qū)動程序的交互,JDBC驅(qū)動程序能夠利用JDBC API創(chuàng)建Java程序和數(shù)據(jù)源之間的橋梁。應(yīng)用程序僅僅須要編寫一次,便能夠移到各種驅(qū)動程序上執(zhí)行。Sun提供了一個驅(qū)動管理器,數(shù)據(jù)庫供應(yīng)商——如MySQL、Oracle,提供的驅(qū)動程序滿足驅(qū)動管理器的要求就能夠被識別,就能夠正常工作。所以JDBC不受數(shù)據(jù)庫供應(yīng)商的限制。
      JDBC API能夠作為連接Java應(yīng)用程序與各種關(guān)系數(shù)據(jù)庫的紐帶,在帶來方便的同一時候也有負(fù)面影響,下面是JDBC的優(yōu)、缺點。長處例如以下:
      操作便捷:JDBC使得開發(fā)者不須要再使用復(fù)雜的驅(qū)動器調(diào)用命令和函數(shù);
      可移植性強:JDBC支持不同的關(guān)系數(shù)據(jù)庫,所以能夠使同一個應(yīng)用程序支持多個數(shù)據(jù)庫的訪問,僅僅要載入對應(yīng)的驅(qū)動程序就可以;
      通用性好:JDBC-ODBC橋接驅(qū)動器將JDBC函數(shù)換成ODBC;
      面向?qū)ο螅耗軌驅(qū)⒔?jīng)常使用的JDBC數(shù)據(jù)庫連接封裝成一個類,在使用的時候直接調(diào)用就可以。
      缺點例如以下:
      訪問數(shù)據(jù)記錄的速度受到一定程度的影響;
      更改數(shù)據(jù)源困難:JDBC可支持多種數(shù)據(jù)庫,各種數(shù)據(jù)庫之間的操作必有不同,這就給更改數(shù)據(jù)源帶來了非常大的麻煩
      二、JDBC連接數(shù)據(jù)庫的流程及其原理
      1、在開發(fā)環(huán)境中載入指定數(shù)據(jù)庫的驅(qū)動程序。比如,接下來的實驗中,使用的數(shù)據(jù)庫是MySQL,所以須要去下載MySQL支持JDBC的驅(qū)動程序(最新的是:mysql-connector-java-5.1.18-bin.jar);而開發(fā)環(huán)境是MyEclipse,將下載得到的驅(qū)動程序載入進開發(fā)環(huán)境中(詳細(xì)演示樣例的時候會解說怎樣載入)。
      2、在Java程序中載入驅(qū)動程序。在Java程序中,能夠通過 “Class.forName(“指定數(shù)據(jù)庫的驅(qū)動程序”)” 方式來載入加入到開發(fā)環(huán)境中的驅(qū)動程序,比如載入MySQL的數(shù)據(jù)驅(qū)動程序的代碼為:  Class.forName(“com.mysql.jdbc.Driver”)
      3、創(chuàng)建數(shù)據(jù)連接對象:通過DriverManager類創(chuàng)建數(shù)據(jù)庫連接對象Connection。DriverManager類作用于Java程序和JDBC驅(qū)動程序之間,用于檢查所載入的驅(qū)動程序能否夠建立連接,然后通過它的getConnection方法,依據(jù)數(shù)據(jù)庫的URL、username和password,創(chuàng)建一個JDBC Connection 對象。如:Connection connection =  DriverManager.geiConnection(“連接數(shù)據(jù)庫的URL", "username", "password”)。當(dāng)中,URL=協(xié)議名+IP地址(域名)+port+數(shù)據(jù)庫名稱;username和password是指登錄數(shù)據(jù)庫時所使用的username和password。詳細(xì)演示樣例創(chuàng)建MySQL的數(shù)據(jù)庫連接代碼例如以下:
      Connection connectMySQL  =  DriverManager.geiConnection(“jdbc:mysql://localhost:3306/myuser","root" ,"root" );
      4、創(chuàng)建Statement對象:Statement 類的主要是用于運行靜態(tài) SQL 語句并返回它所生成結(jié)果的對象。通過Connection 對象的 createStatement()方法能夠創(chuàng)建一個Statement對象。比如:Statement statament = connection.createStatement(); 詳細(xì)演示樣例創(chuàng)建Statement對象代碼例如以下:
      Statement statamentMySQL =connectMySQL.createStatement();
      5、調(diào)用Statement對象的相關(guān)方法運行相相應(yīng)的 SQL 語句:通過execuUpdate()方法用來數(shù)據(jù)的更新,包含插入和刪除等操作,比如向staff表中插入一條數(shù)據(jù)的代碼:
      statement.excuteUpdate( "INSERT INTO staff(name, age, sex,address, depart, worklen,wage)" + " VALUES ('Tom1', 321, 'M', 'china','Personnel','3','3000' ) ") ;
      通過調(diào)用Statement對象的executeQuery()方法進行數(shù)據(jù)的查詢,而查詢結(jié)果會得到 ResulSet對象,ResulSet表示運行查詢數(shù)據(jù)庫后返回的數(shù)據(jù)的集合,ResulSet對象具有能夠指向當(dāng)前數(shù)據(jù)行的指針。通過該對象的next()方法,使得指針指向下一行,然后將數(shù)據(jù)以列號或者字段名取出。假設(shè)當(dāng)next()方法返回null,則表示下一行中沒有數(shù)據(jù)存在。使用演示樣例代碼例如以下:
      ResultSet resultSel = statement.executeQuery( "select * from staff" );
      6、關(guān)閉數(shù)據(jù)庫連接:使用完數(shù)據(jù)庫或者不須要訪問數(shù)據(jù)庫時,通過Connection的close() 方法及時關(guān)閉數(shù)據(jù)連接。
      三、JDBC應(yīng)用演示樣例實驗
      實驗內(nèi)容:使用phpMyAdmin在MySQL中創(chuàng)建數(shù)據(jù)庫(myuser),并加入實驗所需的數(shù)據(jù)(新建staff表,加入一些記錄);編寫Java程序,利用JDBC連接在MySQL中創(chuàng)建好的數(shù)據(jù)庫(myuser),對staff表格進行插入、更新、刪除和查詢等操作。
      實驗環(huán)境及開發(fā)工具:Win7操作系統(tǒng);jdk1.6.0_26;XAMPP1.7.7(MySQL 5.1,  phpMyAdmin);MyEclipse 8.5
      實驗環(huán)境的搭建:可參考我的博客
      Java環(huán)境搭配:http://blog.csdn.net/cxwen78/article/details/6400798;
      windows系統(tǒng)XAMPP安裝配置使用:http://blog.csdn.net/cxwen78/article/details/6847927
      實驗過程及步驟:
      1、下載MySQL支持JDBC的驅(qū)動程序:假設(shè)已經(jīng)有了,可跳過這一步。前往MySQL官網(wǎng)(http://www.mysql.com/products/connector/ )下載驅(qū)動程序,,MySQL針對不同的平臺提供了不同的連接器,我們須要的是DBC Driver for MySQL (Connector/J),例如以下圖所看到的,點擊 Download 跟著站點的引導(dǎo)進行下載。打開下載得到的壓縮包(mysql-connector-java-5.1.18.zip),將當(dāng)中的Java包(mysql-connector-java-5.1.18-bin.jar),拷貝到MySQL文件夾下(僅是為了方便才放到這里),以備載入驅(qū)動程序時使用。
      2、創(chuàng)建數(shù)據(jù)庫:使用phpMyAdmin,登錄MySQL,創(chuàng)建數(shù)據(jù)庫myuser,并在當(dāng)中插入一個名為staff的表格。并加入一些數(shù)據(jù),操作步驟如圖,登錄進去MySQL數(shù)據(jù)庫后:
      1)創(chuàng)建數(shù)據(jù)庫,名稱為myuser,編碼為utf8_general_ci(支持中文);
      2)新建表格,名稱為staff,表格有8個字段;
      3)8個字段的設(shè)置,包含名稱、類型、值的長度、初始值、編碼等等(點擊查看大圖);
      4)加入成功后,查看的staff表格情況:
      5)往表格中插入一些實驗所需數(shù)據(jù),須要插入兩條,一個是員工lucy的,還有l(wèi)ili的:
      3、在MyEclips中創(chuàng)建項目并在項目中加入MySQL驅(qū)動程序:創(chuàng)建的項目類型能夠是Java項目或者是Java Web項目都能夠。這里創(chuàng)建的是Web項目,項目名稱能夠隨便取,我命名為“JavaWebChp07”。創(chuàng)建成功后將步驟1里下載得到的MySQL驅(qū)動程序包(mysql-connector-java-5.1.18-bin.jar)加入到project的Build path中,加入過程如圖所看到的:
     4、編寫JDBC連接MySQL數(shù)據(jù)庫的實例詳細(xì)代碼,JDBC_Test.java:
      詳細(xì)代碼:
      <pre name="code" class="java">package chp07;
      import java.sql.Connection;
      import java.sql.DriverManager;
      import java.sql.ResultSet;
      import java.sql.SQLException;
      import java.sql.Statement;
      public class JDBC_Test {
      // 創(chuàng)建靜態(tài)全局變量
      static Connection conn;
      static Statement st;
      public static void main(String[] args) {
      insert(); //插入加入記錄
      update(); //更新記錄數(shù)據(jù)
      delete(); //刪除記錄
      query(); //查詢記錄并顯示
      }
      /* 插入數(shù)據(jù)記錄,并輸出插入的數(shù)據(jù)記錄數(shù)*/
      public static void insert() {
      conn = getConnection(); // 首先要獲取連接,即連接到數(shù)據(jù)庫
      try {
      String sql = "INSERT INTO staff(name, age, sex,address, depart, worklen,wage)"
      + " VALUES ('Tom1', 32, 'M', 'china','Personnel','3','3000')"; // 插入數(shù)據(jù)的sql語句
      st = (Statement) conn.createStatement(); // 創(chuàng)建用于運行靜態(tài)sql語句的Statement對象
      int count = st.executeUpdate(sql); // 運行插入操作的sql語句,并返回插入數(shù)據(jù)的個數(shù)
      System.out.println("向staff表中插入 " + count + " 條數(shù)據(jù)"); //輸出插入操作的處理結(jié)果
      conn.close(); //關(guān)閉數(shù)據(jù)庫連接
      } catch (SQLException e) {
      System.out.println("插入數(shù)據(jù)失敗" + e.getMessage());
      }
      }
      /* 更新符合要求的記錄,并返回更新的記錄數(shù)目*/
      public static void update() {
      conn = getConnection(); //相同先要獲取連接,即連接到數(shù)據(jù)庫
      try {
      String sql = "update staff set wage='2200' where name = 'lucy'";// 更新數(shù)據(jù)的sql語句
      st = (Statement) conn.createStatement(); //創(chuàng)建用于運行靜態(tài)sql語句的Statement對象,st屬局部變量
      int count = st.executeUpdate(sql);// 運行更新操作的sql語句,返回更新數(shù)據(jù)的個數(shù)
      System.out.println("staff表中更新 " + count + " 條數(shù)據(jù)"); //輸出更新操作的處理結(jié)果
      conn.close(); //關(guān)閉數(shù)據(jù)庫連接
      } catch (SQLException e) {
      System.out.println("更新數(shù)據(jù)失敗");
      }
      }
      /* 查詢數(shù)據(jù)庫,輸出符合要求的記錄的情況*/
      public static void query() {
      conn = getConnection(); //相同先要獲取連接,即連接到數(shù)據(jù)庫
      try {
      String sql = "select * from staff"; // 查詢數(shù)據(jù)的sql語句
      st = (Statement) conn.createStatement(); //創(chuàng)建用于運行靜態(tài)sql語句的Statement對象,st屬局部變量
      ResultSet rs = st.executeQuery(sql); //運行sql查詢語句,返回查詢數(shù)據(jù)的結(jié)果集
      System.out.println("最后的查詢結(jié)果為:");
      while (rs.next()) { // 推斷是否還有下一個數(shù)據(jù)
      // 依據(jù)字段名獲取對應(yīng)的值
      String name = rs.getString("name");
      int age = rs.getInt("age");
      String sex = rs.getString("sex");
      String address = rs.getString("address");
      String depart = rs.getString("depart");
      String worklen = rs.getString("worklen");
      String wage = rs.getString("wage");
      //輸出查到的記錄的各個字段的值
      System.out.println(name + " " + age + " " + sex + " " + address
      + " " + depart + " " + worklen + " " + wage);
      }
      conn.close(); //關(guān)閉數(shù)據(jù)庫連接
      } catch (SQLException e) {
      System.out.println("查詢數(shù)據(jù)失敗");
      }
      }
      /* 刪除符合要求的記錄,輸出情況*/
      public static void delete() {
      conn = getConnection(); //相同先要獲取連接,即連接到數(shù)據(jù)庫
      try {
      String sql = "delete from staff  where name = 'lili'";// 刪除數(shù)據(jù)的sql語句
      st = (Statement) conn.createStatement(); //創(chuàng)建用于運行靜態(tài)sql語句的Statement對象,st屬局部變量
      int count = st.executeUpdate(sql);// 運行sql刪除語句,返回刪除數(shù)據(jù)的數(shù)量
      System.out.println("staff表中刪除 " + count + " 條數(shù)據(jù)\n"); //輸出刪除操作的處理結(jié)果
      conn.close(); //關(guān)閉數(shù)據(jù)庫連接
      } catch (SQLException e) {
      System.out.println("刪除數(shù)據(jù)失敗");
      }
      }
      /* 獲取數(shù)據(jù)庫連接的函數(shù)*/
      public static Connection getConnection() {
      Connection con = null; //創(chuàng)建用于連接數(shù)據(jù)庫的Connection對象
      try {
      Class.forName("com.mysql.jdbc.Driver");// 載入Mysql數(shù)據(jù)驅(qū)動
      con = DriverManager.getConnection(
      "jdbc:mysql://localhost:3306/myuser", "root", "root");// 創(chuàng)建數(shù)據(jù)連接
      } catch (Exception e) {
      System.out.println("數(shù)據(jù)庫連接失敗" + e.getMessage());
      }
      return con; //返回所建立的數(shù)據(jù)庫連接
      }
      }
      項目部署到server,然后執(zhí)行結(jié)果:

    posted @ 2014-09-24 15:39 順其自然EVO 閱讀(825) | 評論 (0)編輯 收藏

    Unix/Linux中Cron的用法

    cron是unix或者linux下用來定時任務(wù)的命令,大致的用法如下:
      1、服務(wù)的啟動和關(guān)閉
      /sbin/service crond start   //啟動服務(wù)
      /sbin/service crond stop    //關(guān)閉服務(wù)
      /sbin/service crond restart //重啟服務(wù)
      /sbin/service crond reload  //重新載入配置
      也可以讓該服務(wù)在開機時自啟動:在/etc/rc.d/rc.local這個腳本的末尾加上如下腳本:
      /sbin/service crond start
      2、編輯cron服務(wù)
      crontab -u //設(shè)定某個用戶的cron服務(wù),一般root用戶在執(zhí)行這個命令的時候需要此參數(shù)crontab -l //列出某個用戶cron服務(wù)的詳細(xì)內(nèi)容
      crontab -r //刪除沒個用戶的cron服務(wù)
      crontab -e //編輯某個用戶的cron服務(wù)
      用crontab -u user -e 進入vi編輯模式,編輯的內(nèi)容一定要符合下面的格式:
      * * * * * command
      這個格式的前一部分是對時間的設(shè)定,后面一部分是要執(zhí)行的命令,當(dāng)然,這個命令也可以是一個腳本。五個 * 的作用如下:
      分鐘 (0-59)
      小時 (0-23)
      日期 (1-31)
      月份 (1-12)
      星期 (0-6)//0代表星期天
      每 次編輯完某個用戶的cron設(shè)置后,cron自動在/var/spool/cron下生成一個與此用戶同名的文件,此用戶的cron信息都記錄在這個文件 中,這個文件是不可以直接編輯的,只可以用crontab -e 來編輯。cron啟動后每過一份鐘讀一次這個文件,檢查是否要執(zhí)行里面的命令。因此此文件修改后不需要重新啟動cron服務(wù)。
      3、定時方法說明
      除了數(shù)字之外,還有幾個特殊的符號("*"、"/"和"-"、",")可以用來編輯啟動時間,*代表所有的取值范圍內(nèi)的數(shù)字,"/"代表每的意思,"*/5"表示每5個單位,"-"代表從某個數(shù)字到某個數(shù)字,","分開幾個離散的數(shù)字。以下舉幾個例子說明問題:
      每天早上6點:0 6 * * * command
      每兩個小時:0 */2 * * * command
      晚上11點到早上8點之間每兩個小時,早上八點:0 23-7/2,8 * * * command
      每個月的4號和每個禮拜的禮拜一到禮拜三的早上11點:0 11 4 * 1-3 command
      1月1日早上4點:0 4 1 1 * command
      4、配置文件/etc/crontab的編輯
      cron 服務(wù)每分鐘不僅讀一次/var/spool/cron內(nèi)的文件,還要讀一次/etc/crontab,因此我們配置這個文件也能運用cron服務(wù)做一些事 情。用crontab配置是針對某個用戶的,而編輯/etc/crontab是針對系統(tǒng)的任務(wù)。此文件的文件格式是:
    SHELL=/bin/bash
    PATH=/sbin:/bin:/usr/sbin:/usr/bin
    MAILTO=root //如果出現(xiàn)錯誤,或者有數(shù)據(jù)輸出,數(shù)據(jù)作為郵件發(fā)給這個帳號
    HOME=/ //使用者運行的路徑,這里是根目錄
    # run-parts
    01 * * * * root run-parts /etc/cron.hourly //每小時執(zhí)行/etc/cron.hourly內(nèi)的腳本
    02 4 * * * root run-parts /etc/cron.daily //每天執(zhí)行/etc/cron.daily內(nèi)的腳本
    22 4 * * 0 root run-parts /etc/cron.weekly //每星期執(zhí)行/etc/cron.weekly內(nèi)的腳本
    42 4 1 * * root run-parts /etc/cron.monthly //每月去執(zhí)行/etc/cron.monthly內(nèi)的腳本
      大家注意"run-parts"這個參數(shù)了,如果去掉這個參數(shù)的話,后面就可以寫要運行的某個腳本名,而不是文件夾名了。
      5、權(quán)限設(shè)置
      默認(rèn)情況下,所有用戶都能訪問cron工具,要對cron進行訪問控制,則可以生成/etc/cron.allow與/etc/cron.deny文件。
      ①、這兩個文件都不存在時,每個用戶都可以訪問cron工具。
      ②、默認(rèn)情況下,應(yīng)該有cron.deny(空文件),cron.allow需要自己創(chuàng)建。
      ③、存在/etc/cron.allow文件時,則只有cron.allow文件中允許的用戶才能訪問cron工具,如果也有/etc/cron.deny文件,則忽略cron.deny文件中的內(nèi)容。

    posted @ 2014-09-24 15:38 順其自然EVO 閱讀(233) | 評論 (0)編輯 收藏

    深入理解Java:類加載機制及反射

     一、Java類加載機制
      1.概述
      Class文件由類裝載器裝載后,在JVM中將形成一份描述Class結(jié)構(gòu)的元信息對象,通過該元信息對象可以獲知Class的結(jié)構(gòu)信息:如構(gòu)造函數(shù),屬性和方法等,Java允許用戶借由這個Class相關(guān)的元信息對象間接調(diào)用Class對象的功能。
      虛擬機把描述類的數(shù)據(jù)從class文件加載到內(nèi)存,并對數(shù)據(jù)進行校驗,轉(zhuǎn)換解析和初始化,最終形成可以被虛擬機直接使用的Java類型,這就是虛擬機的類加載機制。
      2.工作機制
      類裝載器就是尋找類的字節(jié)碼文件,并構(gòu)造出類在JVM內(nèi)部表示的對象組件。在Java中,類裝載器把一個類裝入JVM中,要經(jīng)過以下步驟:
      (1) 裝載:查找和導(dǎo)入Class文件;
      (2) 鏈接:把類的二進制數(shù)據(jù)合并到JRE中;
      (a)校驗:檢查載入Class文件數(shù)據(jù)的正確性;
      (b)準(zhǔn)備:給類的靜態(tài)變量分配存儲空間;
      (c)解析:將符號引用轉(zhuǎn)成直接引用;
      (3) 初始化:對類的靜態(tài)變量,靜態(tài)代碼塊執(zhí)行初始化操作
      Java程序可以動態(tài)擴展是由運行期動態(tài)加載和動態(tài)鏈接實現(xiàn)的;比如:如果編寫一個使用接口的應(yīng)用程序,可以等到運行時再指定其實際的實現(xiàn)(多態(tài)),解析過程有時候還可以在初始化之后執(zhí)行;比如:動態(tài)綁定(多態(tài));
      【類初始化】
      (1) 遇到new、getstatic、putstatic或invokestatic這4條字節(jié)碼指令時,如果類沒有進行過初始化,則需要先觸發(fā)其初始化。生成這4條指令的最常見的Java代碼場景是:使用new關(guān)鍵字實例化對象的時候,讀取或設(shè)置一個類的靜態(tài)字段(被final修飾、已在編譯期把結(jié)果放入常量池的靜態(tài)字段除外)的時候,以及調(diào)用一個類的靜態(tài)方法的時候。
      (2) 使用java.lang.reflect包的方法對類進行反射調(diào)用的時候,如果類沒有進行過初始化,則需要先觸發(fā)其初始化。
      (3) 當(dāng)初始化一個類的時候,如果發(fā)現(xiàn)其父類還沒有進行過初始化,則需要先觸發(fā)其父類的初始化。
      (4)當(dāng)虛擬機啟動時,用戶需要指定一個要執(zhí)行的主類(包含main()方法的那個類),虛擬機會先初始化這個主類。
      只有上述四種情況會觸發(fā)初始化,也稱為對一個類進行主動引用,除此以外,所有其他方式都不會觸發(fā)初始化,稱為被動引用
      代碼清單1
      上述代碼運行后,只會輸出【---SuperClass init】, 而不會輸出【SubClass init】,對于靜態(tài)字段,只有直接定義這個字段的類才會被初始化,因此,通過子類來調(diào)用父類的靜態(tài)字段,只會觸發(fā)父類的初始化,但是這是要看不同的虛擬機的不同實現(xiàn)。
      代碼清單2
      此處不會引起SuperClass的初始化,但是卻觸發(fā)了【[Ltest.SuperClass】的初始化,通過arr.toString()可以看出,對于用戶代碼來說,這不是一個合法的類名稱,它是由虛擬機自動生成的,直接繼承于Object的子類,創(chuàng)建動作由字節(jié)碼指令newarray觸發(fā),此時數(shù)組越界檢查也會伴隨數(shù)組對象的所有調(diào)用過程,越界檢查并不是封裝在數(shù)組元素訪問的類中,而是封裝在數(shù)組訪問的xaload,xastore字節(jié)碼指令中.
    代碼清單3
      對常量ConstClass.value 的引用實際都被轉(zhuǎn)化為NotInitialization類對自身常量池的引用,這兩個類被編譯成class后不存在任何聯(lián)系。
      【裝載】
      在裝載階段,虛擬機需要完成以下3件事情
      (1) 通過一個類的全限定名來獲取定義此類的二進制字節(jié)流
      (2) 將這個字節(jié)流所代表的靜態(tài)存儲結(jié)構(gòu)轉(zhuǎn)化為方法區(qū)的運行時數(shù)據(jù)結(jié)構(gòu)
      (3) 在Java堆中生成一個代表這個類的java.lang.Class對象,作為方法區(qū)這些數(shù)據(jù)的訪問入口。
      虛擬機規(guī)范中并沒有準(zhǔn)確說明二進制字節(jié)流應(yīng)該從哪里獲取以及怎樣獲取,這里可以通過定義自己的類加載器去控制字節(jié)流的獲取方式。
      【驗證】
      虛擬機如果不檢查輸入的字節(jié)流,對其完全信任的話,很可能會因為載入了有害的字節(jié)流而導(dǎo)致系統(tǒng)奔潰。
      【準(zhǔn)備】
      準(zhǔn)備階段是正式為類變量分配并設(shè)置類變量初始值的階段,這些內(nèi)存都將在方法區(qū)中進行分配,需要說明的是:
      這時候進行內(nèi)存分配的僅包括類變量(被static修飾的變量),而不包括實例變量,實例變量將會在對象實例化時隨著對象一起分配在Java堆中;這里所說的初始值“通常情況”是數(shù)據(jù)類型的零值,假如:
      public static int value = 123;
      value在準(zhǔn)備階段過后的初始值為0而不是123,而把value賦值的putstatic指令將在初始化階段才會被執(zhí)行
      二、類加載器與雙親委派模型
      類加載器
      (1) Bootstrap ClassLoader : 將存放于<JAVA_HOME>\lib目錄中的,或者被-Xbootclasspath參數(shù)所指定的路徑中的,并且是虛擬機識別的(僅按照文件名識別,如 rt.jar 名字不符合的類庫即使放在lib目錄中也不會被加載)類庫加載到虛擬機內(nèi)存中。啟動類加載器無法被Java程序直接引用
      (2) Extension ClassLoader : 將<JAVA_HOME>\lib\ext目錄下的,或者被java.ext.dirs系統(tǒng)變量所指定的路徑中的所有類庫加載。開發(fā)者可以直接使用擴展類加載器。
      (3) Application ClassLoader : 負(fù)責(zé)加載用戶類路徑(ClassPath)上所指定的類庫,開發(fā)者可直接使用。
      雙親委派模型
      工作過程:如果一個類加載器接收到了類加載的請求,它首先把這個請求委托給他的父類加載器去完成,每個層次的類加載器都是如此,因此所有的加載請求都應(yīng)該傳送到頂層的啟動類加載器中,只有當(dāng)父加載器反饋自己無法完成這個加載請求(它在搜索范圍中沒有找到所需的類)時,子加載器才會嘗試自己去加載。
      好處:java類隨著它的類加載器一起具備了一種帶有優(yōu)先級的層次關(guān)系。例如類java.lang.Object,它存放在rt.jar中,無論哪個類加載器要加載這個類,最終都會委派給啟動類加載器進行加載,因此Object類在程序的各種類加載器環(huán)境中都是同一個類。相反,如果用戶自己寫了一個名為java.lang.Object的類,并放在程序的Classpath中,那系統(tǒng)中將會出現(xiàn)多個不同的Object類,java類型體系中最基礎(chǔ)的行為也無法保證,應(yīng)用程序也會變得一片混亂。
      java.lang.ClassLoader中幾個最重要的方法:
      //加載指定名稱(包括包名)的二進制類型,供用戶調(diào)用的接口
      public Class<?> loadClass(String name);
      //加載指定名稱(包括包名)的二進制類型,同時指定是否解析(但是,這里的resolve參數(shù)不一定真正能達到解析的效果),供繼承用
      protected synchronized Class<?> loadClass(String name, boolean resolve);
      protected Class<?> findClass(String name)
      //定義類型,一般在findClass方法中讀取到對應(yīng)字節(jié)碼后調(diào)用,可以看出不可繼承(說明:JVM已經(jīng)實現(xiàn)了對應(yīng)的具體功能,解析對應(yīng)的字節(jié)碼,產(chǎn)生對應(yīng)的內(nèi)部數(shù)據(jù)結(jié)構(gòu)放置到方法區(qū),所以無需覆寫,直接調(diào)用就可以了)
      protected final Class<?> defineClass(String name, byte[] b, int off, int len) throws ClassFormatError{}
      如下是實現(xiàn)雙親委派模型的主要代碼:
      三、反射
      Reflection機制允許程序在正在執(zhí)行的過程中,利用Reflection APIs取得任何已知名稱的類的內(nèi)部信息,包括:package、 type parameters、 superclass、 implemented interfaces、 inner classes、 outer classes、 fields、 constructors、 methods、 modifiers等,并可以在執(zhí)行的過程中,動態(tài)生成instances、變更fields內(nèi)容或喚起methods。
      1、獲取構(gòu)造方法
      Class類提供了四個public方法,用于獲取某個類的構(gòu)造方法。
      Constructor getConstructor(Class[] params)
      根據(jù)構(gòu)造函數(shù)的參數(shù),返回一個具體的具有public屬性的構(gòu)造函數(shù)
      Constructor getConstructors()
      返回所有具有public屬性的構(gòu)造函數(shù)數(shù)組
      Constructor getDeclaredConstructor(Class[] params)
      根據(jù)構(gòu)造函數(shù)的參數(shù),返回一個具體的構(gòu)造函數(shù)(不分public和非public屬性)
      Constructor getDeclaredConstructors()
      返回該類中所有的構(gòu)造函數(shù)數(shù)組(不分public和非public屬性)
      2、獲取類的成員方法
      與獲取構(gòu)造方法的方式相同,存在四種獲取成員方法的方式。
      Method getMethod(String name, Class[] params)
      根據(jù)方法名和參數(shù),返回一個具體的具有public屬性的方法
      Method[] getMethods()
      返回所有具有public屬性的方法數(shù)組
      Method getDeclaredMethod(String name, Class[] params)
      根據(jù)方法名和參數(shù),返回一個具體的方法(不分public和非public屬性)
      Method[] getDeclaredMethods()
      返回該類中的所有的方法數(shù)組(不分public和非public屬性)
      3、獲取類的成員變量(成員屬性)
      存在四種獲取成員屬性的方法
      Field getField(String name)
      根據(jù)變量名,返回一個具體的具有public屬性的成員變量
      Field[] getFields()
      返回具有public屬性的成員變量的數(shù)組
      Field getDeclaredField(String name)
      根據(jù)變量名,返回一個成員變量(不分public和非public屬性)
      Field[] getDelcaredFields()
      返回所有成員變量組成的數(shù)組(不分public和非public屬性)

    posted @ 2014-09-24 15:36 順其自然EVO 閱讀(173) | 評論 (0)編輯 收藏

    EnterpriseFrameWork框架基礎(chǔ)功能之字典數(shù)據(jù)配置管理

    框架中的“通用字典數(shù)據(jù)配置管理”主要解決的問題是,所有的行業(yè)軟件給客戶實施第一步一般都是基礎(chǔ)數(shù)據(jù)的維護,一個系統(tǒng)的字典是少不了的,涉及業(yè)務(wù)范圍越廣字典就越多,如果每一個字典數(shù)據(jù)都做一個界面來進行維護數(shù)據(jù)的話,那開發(fā)工作量還是比較大的,所以得考慮設(shè)計一個通用的模塊來管理這些字典數(shù)據(jù);
      1)通用字典管理功能清單
      2)通用字典管理界面展示,包括Winform版和Web版
     3)通用字典管理核心業(yè)務(wù)流程圖與數(shù)據(jù)庫表關(guān)系圖
      4)通用字典管理關(guān)鍵點技術(shù)實現(xiàn)
      1.字典保存數(shù)據(jù)實現(xiàn)
    //保存數(shù)據(jù)
    public Object SaveResultDataTable(int titleId, string IdName, object IdValue, Dictionary<string, object> fieldAndValue)
    {
    if (IdValue.Equals(System.DBNull.Value) == true)//插入數(shù)據(jù)
    {
    string fields = "";
    string values = "";
    string strsql = "insert into {0} ({1}) values({2})";
    foreach (KeyValuePair<string, object> val in fieldAndValue)
    {
    fields += (fields == "" ? "" : ",") + val.Key;
    values += (values == "" ? "" : ",") + ConvertDBValue(val.Value);
    }
    BaseGeneralTitle title = NewObject<BaseGeneralTitle>().getmodel(titleId) as BaseGeneralTitle;
    IdValue = oleDb.InsertRecord(string.Format(strsql, title.TableName, fields, values));
    }
    else//更新數(shù)據(jù)
    {
    string field_values = "";
    string strsql = "update  {0} set {1} where {2}";
    foreach (KeyValuePair<string, object> val in fieldAndValue)
    {
    field_values += (field_values == "" ? "" : ",") + val.Key + "=" + ConvertDBValue(val.Value);
    }
    BaseGeneralTitle title = NewObject<BaseGeneralTitle>().getmodel(titleId) as BaseGeneralTitle;
    oleDb.DoCommand(string.Format(strsql, title.TableName, field_values, IdName + "=" + ConvertDBValue(IdValue)));
    }
    return IdValue;
    }
      2.Web版JqueryEasyUI的Gird控件動態(tài)列
    <div id="resulttool" class="toolbar">
    <a href="#" class="easyui-linkbutton" plain="true" iconCls="icon-search" onclick="btnresult_search();">查詢</a>
    <a href="#" class="easyui-linkbutton" plain="true" iconCls="icon-add" onclick="btnresult_addData();">增加</a>
    <a href="#" class="easyui-linkbutton" plain="true" iconCls="icon-edit" onclick="btnresult_editData();">編輯</a>
    <a href="#" class="easyui-linkbutton" plain="true" iconCls="icon-cancel" onclick="btnresult_delData();">刪除</a>
    </div>
    <table id="resultGird"  class="easyui-datagrid" fit="true" border="false" toolbar="#resulttool" iconCls="icon-edit" pagination="true" idField="<%=Session["resulstDataKeyName"]%>">
    <thead>
    <tr>
    <th field="ck" checkbox="true"></th>
    <%=Session["resulstDatacolmodel"]%>
    </tr>
    </thead>
    </table>

    posted @ 2014-09-24 15:34 順其自然EVO 閱讀(201) | 評論 (0)編輯 收藏

    AppScan Source V8.8 中棄用的功能

    從 AppScan Source V8.8 開始,不再支持以下操作系統(tǒng)
      Microsoft Windows XP
      Microsoft Windows Server 2003,所有版本和修訂版
      此外:
      Visual Studio 2005 項目文件不再受支持,而且 AppScan Source for Development(Visual Studio 插件) 不再能適用于 Visual Studio 2005。
      Eclipse V3.3、V3.4 和 V3.5 項目文件和工作空間不再受支持,而且 AppScan Source for Development(Eclipse 插件) 不再能適用于 Eclipse V3.3、V3.4 和 V3.5。
      Rational Application Developer for WebSphere? Software (RAD) V7.x 項目文件和工作空間不再受支持,而且 IBM Security AppScan Source for Development plug-in for IBM Rational Application Developer for WebSphere Software (RAD) 不再能適用于 RAD V7.x。
      Java 和 JSP 編譯不再支持 Tomcat V3 (Jasper 1)。如果要升級 AppScan Source 并使用該版本的 Tomcat,您需要將 Tomcat 升級到 AppScan Source V8.8 支持的版本(請參閱 AppScan Source 系統(tǒng)需求以了解受支持的 Tomcat 版本)。
      IBM Rational ClearQuest? V7.0 和 IBM Rational Team Concert? V2.0.0.2 不再是受支持的缺陷跟蹤系統(tǒng)。
      注意:如果之前裝的8.7的AppScan Enterprise Server,現(xiàn)在把AppScan Source升級到8.8,運行會提示版本不兼容!

    posted @ 2014-09-24 15:33 順其自然EVO 閱讀(508) | 評論 (0)編輯 收藏

    解決Junit單元測試 找不到類

     做junit 單元測試時,發(fā)現(xiàn)怎么執(zhí)行都是以前編譯過得代碼。
      最后找到原因了, src/test/java 編譯完的.class路徑是 Default output folder
      Default output folder:  zphVip/src/main/webapp/WEB-INF/classes
      解決
      1 勾選 Allow output floders for source folders  ------允許源文件夾編譯過后的.class輸入文件夾自己指定
      2 Edit 指定 output floder為 target/classes-----不適用默認(rèn),自己指定output floder

    posted @ 2014-09-24 15:33 順其自然EVO 閱讀(641) | 評論 (0)編輯 收藏

    在MS單元測試中引發(fā)期望異常

     首先準(zhǔn)備一個引發(fā)異常的方法。
      1 public static void ThrowException()
      2 {
      3     throw new ArgumentException();
      4 }
      然后在單元測試項目中,寫下測試方法。
      [TestMethod]
      [ExpectedException(typeof(ArgumentException))]// 構(gòu)造函數(shù)中為期望引發(fā)的異常。
      public void ThrowExceptionTest()
      {
      Program.ThrowException();// 調(diào)用被測試的方法。
      }
      如果測試通過,則說明被測試的方法與預(yù)期正確,否則被測試的方法邏輯存在錯誤。

    posted @ 2014-09-24 15:32 順其自然EVO 閱讀(145) | 評論 (0)編輯 收藏

    僅列出標(biāo)題
    共394頁: First 上一頁 41 42 43 44 45 46 47 48 49 下一頁 Last 
    <2025年5月>
    27282930123
    45678910
    11121314151617
    18192021222324
    25262728293031
    1234567

    導(dǎo)航

    統(tǒng)計

    • 隨筆 - 3936
    • 文章 - 404
    • 評論 - 179
    • 引用 - 0

    常用鏈接

    留言簿(55)

    隨筆分類

    隨筆檔案

    文章分類

    文章檔案

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 亚洲伦理一区二区| 免费影院未满十八勿进网站| 国产亚洲精品bv在线观看| 亚洲免费在线播放| 亚洲乱码卡一卡二卡三| 亚洲精品在线免费看| 亚洲伊人tv综合网色| 亚洲精选在线观看| 亚洲一区二区三区在线| 亚洲伊人久久大香线蕉| 亚洲AV女人18毛片水真多| 亚洲youwu永久无码精品| 亚洲大尺度无码无码专线一区| 免费激情网站国产高清第一页 | 亚洲精品无码av天堂| 成人免费无码精品国产电影| 成人免费无码大片a毛片| 成年男女免费视频网站| 亚洲国产a级视频| 亚洲美女在线国产| 亚洲免费视频网站| 日韩亚洲翔田千里在线| 视频免费1区二区三区| 国产精品免费久久久久电影网| 国产精品玖玖美女张开腿让男人桶爽免费看 | 亚洲精品乱码久久久久久V | 国产黄色片免费看| 在线视频免费观看爽爽爽| 91在线视频免费播放| 色妞WWW精品免费视频| 欧洲精品免费一区二区三区| 国产精品美女自在线观看免费 | 亚洲精品乱码久久久久久中文字幕| 亚洲国产精品福利片在线观看 | 国产精品亚洲精品日韩已满| 亚洲一线产区二线产区精华| jizz日本免费| 天堂在线免费观看中文版| 国产a不卡片精品免费观看 | 一本色道久久综合亚洲精品高清| 国产亚洲婷婷香蕉久久精品 |