版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、免費(fèi)在線版本(非印刷免費(fèi)在線版)InfoQ 中文站出品InfoQ中文站本書(shū)由 InfoQ 中文站免費(fèi)提供下載,如果您從其它渠道獲取本書(shū),請(qǐng)?jiān)?InfoQ 中文站上進(jìn)行注冊(cè),以支持作者和出版商,并免費(fèi)下載更多 InfoQ 企業(yè)軟件開(kāi)發(fā)系列圖書(shū)。本書(shū)主頁(yè)為/cn/minibooks/grailsGrails 入門(mén)指南 【美】Jason Rudolph著陳俊 林儀明 彭青 吳仕櫓譯 2006-2007 C4Media Inc.保留所有權(quán)利 C4Media 是企業(yè)軟件開(kāi)發(fā)社區(qū) InfoQ.com 的出版商。本書(shū)是 InfoQ 企業(yè)軟件開(kāi)發(fā)系列之一。 關(guān)于這本書(shū)或者
2、其它InfoQ的書(shū)籍,如果你希望了解相關(guān)信息或進(jìn)行訂購(gòu),請(qǐng)聯(lián)系。 未經(jīng)出版商預(yù)先的書(shū)面許可,不得以如電子、機(jī)械、影印、錄音、掃描或其它任何形式及手段對(duì)本書(shū)的任何部分進(jìn)行翻印或儲(chǔ)存于可重復(fù)使用的系統(tǒng)中。 被公司用來(lái)唯一標(biāo)識(shí)產(chǎn)品的名稱常常被稱作商標(biāo)。在 C4Media Inc.了解相關(guān)聲明的所有產(chǎn)品實(shí)例中,對(duì)應(yīng)的產(chǎn)品名稱都會(huì)以首字母大寫(xiě)或者全部大寫(xiě)的形式出現(xiàn)。如果讀者需要獲得商標(biāo)和注冊(cè)更完整的相關(guān)信息,請(qǐng)與相應(yīng)的公司聯(lián)系。 歡迎共同參與InfoQ中文站的內(nèi)容建設(shè)工作,包括原創(chuàng)內(nèi)容投稿及翻譯等,詳情請(qǐng)垂詢。 英文版責(zé)任編
3、輯: Floyd Marinescu 英文版封面設(shè)計(jì): Gene Steffanson 英文版排版: Laura Brown中文版責(zé)任編輯: 賴翥翔 中文版翻譯:陳俊林儀明 彭青吳仕櫓中文版審校:郭曉剛 賴翥翔 10 9 8 7 6 5 4 3 2 1譯者序隨著 Ruby on Rails 這動(dòng)態(tài)腳本語(yǔ)言的日漸盛行,快速開(kāi)發(fā)的理念逐漸深入民心。但由于新興的 Ruby on Rails 缺乏像 Java 那樣成 熟穩(wěn)健的虛擬機(jī),以及對(duì)企業(yè)級(jí)服務(wù)(如分布式事務(wù)、消息傳遞等) 的成熟支持,讓不少謹(jǐn)慎的企業(yè)和開(kāi)發(fā)者觀而止步,而 Grails 的出現(xiàn)正好彌補(bǔ)了這方面的缺陷。 Grails 構(gòu)建于 Gro
4、ovy 之上,與 Java 無(wú)縫結(jié)合,充分利用了Java 豐富的第三方開(kāi)源庫(kù)。Grails 的內(nèi)核就是基于 Spring 、Hibernate 和 SiteMesh 這些成熟而完善的框架組合之上的。它可被部署到任何主流的 JavaEE 應(yīng)用服務(wù)器(如 WebSphere、 WebLogic 等)之上, 在為你的應(yīng)用開(kāi)發(fā)增添強(qiáng)大的動(dòng)態(tài)語(yǔ)言優(yōu)勢(shì)的同時(shí),又能直接訪問(wèn)你業(yè)務(wù)所依賴的那些企業(yè)服務(wù)。 作者以其風(fēng)趣輕松的文筆貫通全書(shū),由搭建一個(gè)原始的網(wǎng)絡(luò)應(yīng) 用實(shí)例起步,通過(guò)介紹各種緊貼實(shí)際的應(yīng)用需求,逐步建立起功能 完備的應(yīng)用,向你展現(xiàn) Grails 的各種特征,讓你領(lǐng)略“不重復(fù)開(kāi)發(fā)” 和“規(guī)約重于配置”原
5、則的優(yōu)勢(shì),引領(lǐng)你體驗(yàn) Grails 開(kāi)發(fā)簡(jiǎn)便快捷的樂(lè)趣,使你在這愉快的學(xué)習(xí)旅途中愛(ài)上 Grails。 本書(shū)中例子的所有源代碼均可在 InfoQ 網(wǎng)站中下載。如果你是剛接觸 Grails,該書(shū)會(huì)是一本不錯(cuò)的入門(mén)指南,通過(guò)本書(shū)按圖索驥,你可以很快熟悉并領(lǐng)略到 Grails 的方方面面。如果你已熟悉Grails,則可以將該書(shū)作為一本參考手冊(cè),在開(kāi)發(fā)中進(jìn)行借鑒。如果你已有 Ruby 的開(kāi)發(fā)經(jīng)驗(yàn),則能從中體會(huì)到 Grails 不單單是 Rails 的克隆品,還有了許多 Ruby 中并不存在的特性和概念。 本書(shū)翻譯工作由 4 名譯者共同完成:陳俊、林儀明、彭青和吳仕櫓。全書(shū)由InfoQ的編輯賴翥翔和郭曉剛
6、統(tǒng)稿、潤(rùn)色和審校。譯文 中疏漏和錯(cuò)誤在所難免,如果您在閱讀中發(fā)現(xiàn)任何疑問(wèn),或?qū)Ρ緯?shū)有任何建議, 歡迎到InfoQ 中文站( /cn/)交流。 譯者 2007 年 10 月 目錄1.簡(jiǎn)介1通過(guò)例子來(lái)學(xué)習(xí)2RaceTrack應(yīng)用22. 準(zhǔn)備上路5安裝JDK5安裝Grails5安裝數(shù)據(jù)庫(kù)53. 你好,Grails!7創(chuàng)建你的第一個(gè)Grails程序7里面有什么東西呢?8建立你的領(lǐng)域9取得控制13我的數(shù)據(jù)哪去了?17建造更好的腳手架22理解URL和控制器294. 提升用戶體驗(yàn)35自定義錯(cuò)誤消息35添加警告信息39實(shí)現(xiàn)確認(rèn)信息40移除數(shù)據(jù)ID43格式化數(shù)據(jù)445.動(dòng)態(tài)
7、53動(dòng)態(tài)查詢器53構(gòu)建自己的查詢條件586.并不僅限于內(nèi)部網(wǎng)絡(luò)的應(yīng)用65除增刪查改功能外66實(shí)現(xiàn)用戶認(rèn)證74界面美化:布局與CSS867.測(cè)試91單元測(cè)試911目錄 功能測(cè)試958.終點(diǎn)線97日志97部署999.深入應(yīng)用的技巧103自行定義數(shù)據(jù)表103處理遺留數(shù)據(jù)表105ORM問(wèn)題與解決105升級(jí)Grails10610. 總結(jié)109關(guān)于作者111資源1132致謝首先我要感謝 Graeme Rocher ( Grails 項(xiàng)目領(lǐng)導(dǎo)者,The Definitive Guide to Grails的作者)。感謝您審閱了這本書(shū),并在一路上啟發(fā)我深入 Grails 的內(nèi)部工作原理。您細(xì)心審閱了本書(shū),并提
8、出了卓越的見(jiàn)解及寶貴的建議令各個(gè)實(shí)例更加“Groovy”。 我還要感謝 Venkat Subramaniam ( Practices of an Agile Developer的合著者),在審閱此書(shū)過(guò)程中強(qiáng)調(diào)學(xué)習(xí)的體驗(yàn)及如何最好地把 Grails 介紹給讀者。此外,您具有深刻見(jiàn)解的序言,能幫開(kāi)發(fā)人員愉快接受一個(gè)可帶來(lái)許多好處并將敏捷發(fā)揚(yáng)光大的框架。 謝謝 Steve Rollins 勤勉地在這本書(shū)中傾注心血,一一解決殘留的問(wèn)題,哪怕這意味著在幾個(gè)星期里,正常工作時(shí)間外默默無(wú)聞的付出。您關(guān)注細(xì)節(jié)而不知疲倦,成果都清楚地反映在這本書(shū)上了。 此外, 我還要感謝 Jared Richardson(Sh
9、ip it! A Practical Guide to Successful Software Projects的合著者),不僅感謝他審閱了本書(shū),還要感謝他最早鼓勵(lì)我寫(xiě)這本書(shū)。非常感謝在我寫(xiě)書(shū)的過(guò)程中您給予的鼓勵(lì),以及給最后書(shū)稿的可貴觀點(diǎn)。 感謝 Floyd Marinescu(InfoQ.com 的共同創(chuàng)始人之一,EJB Design Patterns的作者),以及為出版此書(shū)作出努力的整個(gè) InfoQ 團(tuán)隊(duì),感謝你們?cè)诔霭孢^(guò)程中的熱情支持。 最要感謝的是永遠(yuǎn)耐心、一直鼓勵(lì)我的妻子 Michelle,感謝你一路對(duì)我的支持。只有你(在一切事情上都)愿意承擔(dān)遠(yuǎn)遠(yuǎn)超過(guò)你本應(yīng)該承擔(dān)的責(zé)任,我才有時(shí)間來(lái)
10、做這件事情。你不但支持我完成了這本書(shū),而且你的創(chuàng)造力、美感和在內(nèi)容編輯上的建議,使這本書(shū)比它原本的樣子更好。 i序言我們當(dāng)中熱衷于程序開(kāi)發(fā)的人會(huì)發(fā)現(xiàn)敏捷開(kāi)發(fā)大大提高了我們成功的機(jī)會(huì)。但什么是敏捷呢?它的核心是,先開(kāi)發(fā)相對(duì)小的一部分功能,然后從客戶那里得到快速的反饋。客戶會(huì)告訴我們方向是否是正確,幫助我們讓開(kāi)發(fā)緊貼他們的需要,同時(shí)共同確保我們創(chuàng)建的程序?qū)?huì)為他們?cè)黾由虡I(yè)價(jià)值。為什么我們需要敏捷呢?作為一個(gè)產(chǎn)業(yè),長(zhǎng)久以來(lái)我們一直看著其它開(kāi)發(fā)方法論在“交付真正滿足客戶需要的系統(tǒng)”這個(gè)問(wèn)題上跌倒。要想最終交付客戶想要的系統(tǒng),我們必須采取更小更快的步伐,頻繁地與客戶一起達(dá)成階段性的目標(biāo),以交付客戶能夠操
11、作和評(píng)審的有用功能。 兩個(gè)關(guān)鍵點(diǎn)影響了我們敏捷開(kāi)發(fā)的能力。 首先,是每個(gè)相關(guān)的人的態(tài)度。團(tuán)隊(duì)里每個(gè)人以及整個(gè)團(tuán)隊(duì)的態(tài)度,對(duì)項(xiàng)目的方方面面都有重大的影響。這些態(tài)度決定了我們有多樂(lè)意去與其他程序員及客戶緊密合作,以獲取他們的反饋,并通過(guò)這些反饋來(lái)改進(jìn)我們的工作。 第二,是開(kāi)發(fā)語(yǔ)言、框架、以及我們用來(lái)開(kāi)發(fā)的工具。我們所選擇的技術(shù)必須能夠讓我們快速創(chuàng)建代碼并快速應(yīng)對(duì)客戶的反饋?zhàn)鞒鲎兏?一些編程語(yǔ)言和框架需要開(kāi)發(fā)人員在開(kāi)發(fā)出有用的可執(zhí)行的代碼前就付出大量的精力。你可能不得不對(duì)付 XML 配置文件,實(shí)現(xiàn)一大堆接口,在應(yīng)用程序的不同層上重復(fù)執(zhí)行某些操作。在這個(gè)環(huán)境中,要想看到任何修改的成果都要先經(jīng)歷過(guò)度的
12、付出。一旦完成了最終的代碼,哪怕用戶在懇求,只要一想到要引入變更你就忍不住推搪。你會(huì)很快下意識(shí)地抵觸需求變更,讓客戶滿意突然間沒(méi)有避免變更那么重要了。 iii幸運(yùn)的是,我們已經(jīng)看到了近年來(lái)出現(xiàn)的一些編程語(yǔ)言和框架支持一種更敏捷的開(kāi)發(fā)方法。它們?cè)试S你在短短幾分鐘內(nèi)開(kāi)發(fā)出可運(yùn)行可演示的代碼,而不是以天算或以周算,同時(shí)又保證了代碼的質(zhì)量。當(dāng)你從客戶那拿到寶貴的反饋時(shí),這些編程語(yǔ)言和框架傾向于使變更更加容易,而不是妨礙變更。 那到底是怎么實(shí)現(xiàn)的呢? 首先, 這些框架遵循不重復(fù)開(kāi)發(fā) (Dont Repeat Yourself,DRY)原則。因?yàn)槌绦虻拿宽?xiàng)功能都只存在一處實(shí)現(xiàn),你不需要修改多層代碼來(lái)僅僅完
13、成一項(xiàng)變更。相反, 你在一個(gè)地方作出修改,大部分情況下,工作就已經(jīng)完成了。第二, 它們遵循一種“規(guī)約取代配置”的策略,所以你不必花費(fèi)時(shí)間去編 寫(xiě)那些顯而易見(jiàn)的東西;相反,你可以直接編 正有用的代碼。 第三,它們是輕量級(jí)的;你可以更改一段代碼然后立即看到更改的 結(jié)果,而不用在外面重編譯或重新做緩慢繁重的部署工作。 那聽(tīng)起來(lái)很吸引人,但你可能會(huì)問(wèn):“那我們對(duì)其它語(yǔ)言和框架如 Java、Hibernate 和 Spring 等等的投入不是白費(fèi)了?”所以Grails 出現(xiàn)了。因?yàn)?Grails 用的是(運(yùn)行在 JVM 上的)Groovy 語(yǔ)言,所以它允許你隨意整合 Java 代碼,因此你仍然可以有效利
14、用當(dāng)前的投資。當(dāng)你研究 Grails 的時(shí)候,你會(huì)發(fā)現(xiàn)它遵循的原則既好又實(shí)用它發(fā)揮了規(guī)約取代配置的力量,崇尚不重復(fù)開(kāi)發(fā)原則,并且是完全輕量級(jí)的這使它成為一個(gè)強(qiáng)健的敏捷框架。但別只信我說(shuō)的,跟著 Jason 幫你創(chuàng)建好的例子,邊讀邊寫(xiě)代碼,親身體驗(yàn)Grails 是如何提升你的敏捷程度的。接著,找個(gè)合伙人,為你的應(yīng)用選個(gè)方向,嘗試去實(shí)現(xiàn)它吧! Venkat Subramaniam2006 年 11 月 iv言簡(jiǎn)而意賅,保持直白;說(shuō)話的目的不是為了賣(mài)弄,而是為了讓人能真正明白其意。- William Penn以身作則并不是影響他人的主要因素,它是“唯一”要素。- Albert SchweitzerI
15、nfoQ 中文站 Java 社區(qū)關(guān)注企業(yè) Java 社區(qū)的變化與創(chuàng)新/cn/java/1簡(jiǎn)介Grails 是一個(gè)開(kāi)源網(wǎng)絡(luò)應(yīng)用框架,它的宗旨是實(shí)用。 曾有位大學(xué)教授向我宣揚(yáng)他的觀點(diǎn):“最好的程序員,是那些能在早上 10 點(diǎn)鐘前離開(kāi)辦公室去參加高爾夫球課程的人。為什么呢?因?yàn)樗麄兌际菍W⒌?、高效的、高產(chǎn)的?!笔聦?shí)上他也試著讓這觀點(diǎn)深入到他的學(xué)生心里。當(dāng)然,主張?jiān)诳Х茸兝渲熬屯瓿梢惶斓墓ぷ魈鋸埩?,但能在喝第二杯咖啡之前完成一天的工作量是不是很令人向往的事情呢?Ruby on Rails包含了一種強(qiáng)大的編程語(yǔ)言,同時(shí)又是一個(gè)堅(jiān)持己見(jiàn),提倡用通情達(dá)理的默認(rèn)值來(lái)
16、替代復(fù)雜的配置的框架,它開(kāi)創(chuàng)了兩者的創(chuàng)造性結(jié)合。開(kāi)發(fā)人員稱贊Rails框架的革命性,因?yàn)樗蟠筇岣吡松a(chǎn)率(的確如此)。但很多機(jī)構(gòu)仍未準(zhǔn)備好脫離Java這個(gè)安全地帶。所以,如果我們能夠達(dá)到類似的生產(chǎn)率,而又同時(shí)擁有一個(gè)更以Java為核心的解決方案,何樂(lè)而不為呢?Grails使這個(gè)想法成為了事實(shí)。因?yàn)镚rails應(yīng)用程序是用Groovy(一種動(dòng)態(tài)類型的腳本語(yǔ)言,即將成為Java標(biāo)準(zhǔn)1 )編寫(xiě)的,所以Grails應(yīng)用程序能跟原有Java代碼的友好結(jié)合,令謹(jǐn)慎的企業(yè)更加放心。 Grails 信 奉 “ 規(guī) 約 重 于 配 置 ( Convention over Configuration)”,這種技
17、術(shù)同時(shí)改善了注意力和生產(chǎn)效率,“規(guī)約(Convention)”支配了每一個(gè)組件在程序中的歸屬、命名,以及如何與其它組件相互作用。簡(jiǎn)而言之,開(kāi)發(fā)人員能確切知道某一組件應(yīng)放在何處,該如何命名,即便是新組員也會(huì)清楚該組件的確切所在。這都是規(guī)約使然。 Groovy 為創(chuàng)建 Grails 應(yīng)用程序提供了高效的表達(dá)方式和完全面 12Grails 入門(mén)指南 向?qū)ο蟮恼Z(yǔ)言。Groovy 允許開(kāi)發(fā)人員以簡(jiǎn)單易懂的風(fēng)格簡(jiǎn)潔自然地傳達(dá)想法。同時(shí),Java 開(kāi)發(fā)人員會(huì)賞識(shí)它跟 Java 相似的語(yǔ)法,以及跟 Java 的無(wú)縫結(jié)合,因?yàn)樗麄兡軌蛟?Groovy 里調(diào)用任何 Java 類, 反之亦然。 Grails 的基礎(chǔ)
18、, 是建立在已被公認(rèn)的技術(shù)上的。 如: H i b e r n a t e , 一個(gè)事實(shí)上的軟件產(chǎn)業(yè)的標(biāo)準(zhǔn), 為 Grails 提供“對(duì)象 關(guān)系映射”(ORM)的基礎(chǔ);Spring 框架為 Grails 提供“模型視圖控制器”(MVC)的核心,和強(qiáng)大的“ 依賴注入”功能; SiteMesh 給 Grails 帶來(lái)了靈活高效的界面布局管理。當(dāng)然,別忘了Java,由于 Groovy 跟 Java 的完美結(jié)合,使Grails 應(yīng)用程序不僅可以直接使用眾多的 Java 類庫(kù),而且可以使用J2EE 應(yīng)用程序服務(wù)器提供的企業(yè)級(jí)服務(wù)(分布式事務(wù)、通訊等等),這對(duì)很多應(yīng)用程序來(lái)說(shuō)是必不可少的。有了這些牢固的立
19、足點(diǎn),Grails 將會(huì)為 Java 以及企業(yè)級(jí)平臺(tái)上的快速網(wǎng)絡(luò)應(yīng)用開(kāi)發(fā)作出證明。 通過(guò)例子來(lái)學(xué)習(xí)本書(shū)以示例來(lái)介紹 Grails。我們將會(huì)看到如何快速地創(chuàng)建 Grails 應(yīng)用程序,以及如何定制應(yīng)用來(lái)適合不同的需求。我們會(huì)探究我們碰到的每一個(gè)概念的本質(zhì),對(duì)于那些想要深入研究某些主題的讀者,我們會(huì)在最后給出相應(yīng)的注釋來(lái)提供補(bǔ)充信息。 為了更好地跟上進(jìn)度,你需要有面向?qū)ο缶幊毯烷_(kāi)發(fā)MVC網(wǎng)絡(luò)應(yīng)用的基礎(chǔ)知識(shí),并且如果你熟悉Java的話那就更容易上手了(雖然你也可以在完全不懂Java的情況下學(xué)會(huì)Grails)。我們的例子主要使用Groovy。雖然本書(shū)并不是以講解Groovy為目的,但有一定編程基礎(chǔ)的人
20、都應(yīng)該可以看懂例子跟上本書(shū)進(jìn)度。如果你覺(jué)得有必要探究某個(gè)Groovy用法的細(xì)節(jié),可以到Groovy網(wǎng)站查閱更多的信息2。 RaceTrack 應(yīng)用在學(xué)習(xí)本書(shū)的過(guò)程中,我們會(huì)通過(guò)創(chuàng)建一個(gè)叫 RaceTrack 的網(wǎng)絡(luò)應(yīng)用來(lái)探究 Grails 開(kāi)發(fā)的各個(gè)方面。有一個(gè)在比較落后的地區(qū)的賽跑俱樂(lè)部,他們還在用紙面的流程來(lái)跟蹤俱樂(lè)部參與的比賽以及每場(chǎng)比賽注冊(cè)的會(huì)員。他們現(xiàn)在已準(zhǔn)備好跨入到數(shù)字時(shí)代了。作為起點(diǎn),他們想要一個(gè)允許俱樂(lè)部職員管理比賽和注冊(cè)信息的程序。 InfoQ 中文站:關(guān)注企業(yè)軟件開(kāi)發(fā)領(lǐng)域的變化與創(chuàng)新 /cn/簡(jiǎn)介3他們對(duì)我們說(shuō)不需要太絢麗的界面不奇怪,他們現(xiàn)在
21、還在用紙張 。所以,他們會(huì)很高興有這么一個(gè)可以管理比賽數(shù)據(jù)的內(nèi)部程序。我們會(huì)從一個(gè)企業(yè)內(nèi)部網(wǎng)絡(luò)程序開(kāi)始,這個(gè)程序?qū)M足他們的需要。不過(guò)我們聽(tīng)到了一些暗示,如果一切進(jìn)展順利的話,他們想讓賽跑員自己來(lái)注冊(cè)賽跑,所以這就需要我們把程序也暴露給外部用戶使用。 開(kāi)發(fā) RaceTrack 程序給了我們一個(gè)全面的實(shí)際演練 Grails 的機(jī)會(huì)。我們會(huì)創(chuàng)建一個(gè)網(wǎng)絡(luò)用戶界面,管理數(shù)據(jù)庫(kù)表間的關(guān)系,應(yīng)用驗(yàn)證邏輯和開(kāi)發(fā)自定義查詢。隨著我們繼續(xù)擴(kuò)展程序功能,我們將會(huì)探究自定義標(biāo)簽庫(kù)、Java 整合、安全性、頁(yè)面布局以及動(dòng)態(tài)方法的威力。在我們結(jié)束前,我們還將探究一些背后的支持技術(shù),包括單元測(cè)試、日志和部署。 大體上,創(chuàng)
22、建程序所需的信息以及代碼片段都包含在本書(shū)的文本里。在我們結(jié)束時(shí)會(huì)碰到個(gè)例外,不過(guò)我們到時(shí)會(huì)再介紹。別擔(dān)心,所有例子的源代碼你都可以下載得到3 。代碼包中包含了每一章結(jié)束時(shí)程序源代碼的完整快照。 Java .NET Ruby SOA Agile ArchitectureInfoQ 中文站.NET 社區(qū).NET 和微軟的其它企業(yè)軟件開(kāi)發(fā)解決方案/cn/dotnet/2準(zhǔn)備上路安裝 JDKGrails 只要求 JDK 1.4,但在以后幾個(gè)章節(jié)里面的一些例子,我們會(huì)用到 JDK 5 的一些新特性。所以,你需要用到 JDK 5 來(lái)運(yùn)行那些例子(我們會(huì)在介紹時(shí)確切地指
23、出哪些例子要依靠 JDK 5)。 所以,當(dāng)我們謹(jǐn)記Grails能很好的支持JDK 1.4 的同時(shí),你不妨去下載并安裝JDK 5(/javase/downloads/),以便順利學(xué)習(xí)全部例子4 。然后,設(shè)置你的JAVA_HOME環(huán)境變量,把它指向JDK 5 的安裝路徑。 安裝 Grails接著,從/Download 5 下載最新的Grails穩(wěn)定版本 (本書(shū)用Grails 0.3.1寫(xiě)書(shū)的時(shí)候的穩(wěn)定版本)。然后,按照快速安裝步驟(/Installation)安裝好Grails,并配置必要的環(huán)境變量
24、6。 安裝數(shù)據(jù)庫(kù)Grails 周到地附帶了一個(gè)內(nèi)嵌的 HSQLDB 數(shù)據(jù)庫(kù),所以每個(gè)Grails 程序都默認(rèn)有個(gè)內(nèi)存數(shù)據(jù)庫(kù)可用。這個(gè)可選的數(shù)據(jù)庫(kù)對(duì)于快速演示很有用,也方便你跟客戶并排坐在一起快速試驗(yàn)各種功能。當(dāng)然長(zhǎng)期運(yùn)行的話,我們還是需要轉(zhuǎn)移到更傳統(tǒng)的磁盤(pán)數(shù)據(jù)庫(kù)(這樣即使偶爾重啟程序也不會(huì)丟失數(shù)據(jù))。 Grails支持大部分的數(shù)據(jù)庫(kù)(包括Oracle、DB2、PostgreSQL等等 ) ,本書(shū)中我們會(huì)用 MySQL 5.0 來(lái)做例子。 你可以 到/downloads/mysql/5.0.html下載MySQL56Grails 入門(mén)指南 Community
25、版本,按照說(shuō)明安裝好,我們就準(zhǔn)備就緒了7。 InfoQ 中文站:關(guān)注企業(yè)軟件開(kāi)發(fā)領(lǐng)域的變化與創(chuàng)新 /cn/InfoQ 中文站 Ruby 社區(qū)面向 Web 和企業(yè)開(kāi)發(fā)的 Ruby,主要關(guān)注Ruby on Rails /cn/ruby/3你好,Grails!創(chuàng)建你的第一個(gè) Grails 程序現(xiàn)在已經(jīng)安裝好了 Grails,我們還要為我們的 Grails 程序創(chuàng)建個(gè)目錄。你可以任意命名并且放在你喜歡的任何位置。 jason mkdir grails_apps jason cd grails_apps grails_apps接著,在我
26、們剛剛創(chuàng)建的目錄里生成我們的項(xiàng)目結(jié)構(gòu)。輸入grails create-app ,當(dāng) 提示 輸入 程序 名稱 時(shí), 輸入racetrack。 grails_apps grails create-app.create-app:input Enter application name:racetrack.BUILD SUCCESSFULTotal time: 4 seconds啟動(dòng)我們的程序來(lái)檢驗(yàn)一下環(huán)境是否配置無(wú)誤。進(jìn)入到我們新創(chuàng)建的程序目錄里,然后輸入 grails run-app 來(lái)啟動(dòng)程序。 grails_apps cd racetrackracetrack grails run-app.r
27、un-app:watch-context:程 序 正等待 著 我們的 請(qǐng) 求呢, 打 開(kāi)你的 瀏 覽器訪 問(wèn) 78Grails 入門(mén)指南 http:/localhost:8080/racetrack/,你會(huì)看到這個(gè)友好的信息歡迎你來(lái)到Grails的世界。 里面有什么東西呢?一切順利,但在我們更進(jìn)一步之前,我們先靠近一些看看我們的新程序里都有些什么東西。 Grails對(duì)快速程序開(kāi)發(fā)的支持主要來(lái)自于它對(duì)“規(guī)約重于配置” 這個(gè)理念的貫徹( 這是Ruby on Rails所宣揚(yáng)的“ 固執(zhí)軟件 (Opinionated Software)”模式的一個(gè)主要部分)。Grails項(xiàng)目結(jié)構(gòu) (下圖 3-1)仰仗
28、“規(guī)約”,為程序的各個(gè)部分建立了合理的組織結(jié)構(gòu)8。 racetrack+ grails-app+ conf+ controllers+ domain+ i18n+ services+ taglib+ views配置設(shè)置,包括開(kāi)發(fā)、測(cè)試和產(chǎn)品的數(shù)據(jù)源控制器領(lǐng)域類 國(guó)際化資源綁定信息 Service 類(在Grails 里等同于本地 Session Bean) 標(biāo)簽庫(kù) 視圖模板(還有一個(gè)所有控制器共用的而準(zhǔn)備的子目錄) InfoQ 中文站:關(guān)注企業(yè)軟件開(kāi)發(fā)領(lǐng)域的變化與創(chuàng)新 /cn/你好,Grails!9樣式表文件 圖像文件 JavaScript 文件和第三方庫(kù)(例如P
29、rototype、Yahoo 等) 與部署相關(guān)的配置文件 應(yīng)用程序的首頁(yè) + WEB-INF+ index.jspGroovy 源文件(除了控制器、領(lǐng)域類、或者是service 類之外的文件) Java 源文件 + java+ web-app+ css+ images+ js布局模板(所有控制器都可以使用)單元測(cè)試 可選的Hibernate 配置文件應(yīng)用程序中需要的自定義庫(kù)可選的Spring 配置文件 + layouts+ grails-tests+ hibernate+ lib+ spring+ src+ groovy圖 3-1:程序目錄結(jié)構(gòu) 建立你的領(lǐng)域Grails 把領(lǐng)域類(Domain
30、 Class)看作是程序的中心,并且是程序最重要的組件。我們將通過(guò)領(lǐng)域類來(lái)驅(qū)動(dòng)程序中的一切(如果你使用過(guò) Ruby on Rails,你會(huì)發(fā)現(xiàn)這跟 Rails 的做法不同,Rails 的做法是從底層的數(shù)據(jù)庫(kù)定義中引申出領(lǐng)域模型【Domain Model】)。 為了更好地理解我們需要獲取的數(shù)據(jù),我們首先檢查一下賽跑俱樂(lè)部現(xiàn)有的運(yùn)作過(guò)程。一開(kāi)始,他們提供了目前用來(lái)跟蹤賽跑信息的表格。 Java .NET Ruby SOA Agile Architecture10Grails 入門(mén)指南 從這個(gè)表格可以看出,我們基本上需要對(duì)兩種數(shù)據(jù)進(jìn)行處理: 賽跑與注冊(cè)(這兩個(gè)實(shí)體間是一對(duì)多關(guān)系)。這個(gè)信息將是我們領(lǐng)
31、域模型的基本,而表格里的各種數(shù)據(jù)元素將會(huì)是我們領(lǐng)域類的屬性。 那么,讓我們來(lái)創(chuàng)建代表這些元素的領(lǐng)域類。回到命令行窗口,輸入 grails create-domain-class,在提示輸入領(lǐng)域類名稱的時(shí)候,輸入 Race(如果你早前啟動(dòng)的程序還在運(yùn)行,按Control-C 來(lái)停止程序,回到命令提示)。 racetrack grails create-domain-class.create-domain-class:input Enter domain class name:Race.echo Domain class created: grails- app/domain/Race.groov
32、y.echo Created test suite: grails- tests/RaceTests.groovyBUILD SUCCESSFULTotal time: 5 seconds我們會(huì)發(fā)現(xiàn) Grails 不僅為我們創(chuàng)建了領(lǐng)域類,而且還創(chuàng)建了對(duì)應(yīng)的單元測(cè)試類,之后我們會(huì)用到它。 接著,重復(fù)這個(gè)步驟來(lái)創(chuàng)建 Registration 領(lǐng)域類。 現(xiàn)在,讓我們看看自動(dòng)創(chuàng)建的領(lǐng)域類。用你喜歡的編輯器打開(kāi) racetrack/grails-app/domain/Race.groovy。 class Race 誠(chéng)然,現(xiàn)在很難說(shuō)這些給我們留下深刻的印象,但稍忍幾分鐘吧,一切都會(huì)逐步變好的。 從我們?cè)缜?/p>
33、跟客戶的討論以及對(duì)文件表格的分析中,我們知道了每個(gè)賽跑都有哪些屬性,那么讓我們把那些屬性加到領(lǐng)域類里面吧。 InfoQ 中文站:關(guān)注企業(yè)軟件開(kāi)發(fā)領(lǐng)域的變化與創(chuàng)新 /cn/你好,Grails!11class Race String name Date startDateTime String city String state Float distance Float costInteger maxRunners = 100000static hasMany = registrations:Registration好了,上面所做的都相當(dāng)?shù)闹庇^。一場(chǎng)賽跑包括名字、開(kāi)始
34、日期/時(shí)間等等。每場(chǎng)賽跑缺省最多只能有 100,000 個(gè)賽跑運(yùn)動(dòng)員。這再簡(jiǎn)單不過(guò)了, 并且所有的數(shù)據(jù)類型看起來(lái)都相當(dāng)眼熟, 但這“hasMany”是什么意思呢? 從業(yè)務(wù)上看,賽跑跟注冊(cè)是一對(duì)多的關(guān)系,我們的 Race 領(lǐng)域類包括 hasMany 這個(gè)屬性來(lái)支持這種關(guān)系。屬性 hasMany 告訴Grails 一個(gè) Race 跟某個(gè)類有著一對(duì)多的關(guān)系。為了指明這個(gè)關(guān)聯(lián)類,我們把一個(gè)由“屬性名-類名”對(duì)組成的 Map 賦值給 hasMany 屬性。 這樣一來(lái), 我們就聲明了 registrations 屬性是R e g i s t r a t i o n 對(duì)象的一個(gè)集合。 我們并沒(méi)有明確地定義r
35、egistrations 這個(gè)屬性( 這正是Grails程序簡(jiǎn)潔而強(qiáng)表現(xiàn)力的本性的一個(gè)體現(xiàn))。在hasMany這個(gè)Map里面,我們告訴Grails一個(gè)Race對(duì)象的registrations屬性應(yīng)該存儲(chǔ)Registration對(duì)象的集合。既然Grails知道了我們希望Race對(duì)象擁有這個(gè)屬性,那么我們還有必要再次單獨(dú)為它聲明一個(gè)屬性嗎?Grails信奉DRY(不重復(fù)開(kāi)發(fā))原則9 ,這原則讓我們盡量從不必要的冗余中解脫出來(lái)。 既然我們是在一個(gè) Map 中聲明這些信息,要是限制我們只能定義一組一對(duì)多關(guān)系,就太沒(méi)意義了。例如,如果我們想要記錄某場(chǎng)賽跑的贊助商,我們只需往這個(gè) Map 中加入另外一個(gè)集
36、合元素。 static hasMany = registrations : Registration,sponsors : Sponsor 當(dāng)然,你不可能只碰到一對(duì)多這種關(guān)系類型。Grails也支持一 Java .NET Ruby SOA Agile Architecture12Grails 入門(mén)指南 對(duì)一、多對(duì)一、多對(duì)多的關(guān)系10。 現(xiàn)在看看關(guān)系另一邊的 Registraton,用你的編輯器打開(kāi)racetrack/grails-app/domain/Registration.groovy , 讓我們來(lái)定義它的屬性。 class Registration Race race String na
37、me Date dateOfBirthString gender = F String postalAddress String emailAddressDate createdAt = new Date() static belongsTo = Racestatic optionals = postalAddress 大部分的屬性看起來(lái)也都相當(dāng)平常:名字、出生日期等等。只有幾個(gè)地方是需要我們留意的。 用戶告訴我們所有的賽跑屬性都是必要的,同樣,大多數(shù)的注 冊(cè)屬性也都是必要的。然而,用戶覺(jué)得互聯(lián)網(wǎng)應(yīng)該是趨勢(shì),所以他 們決定有一個(gè)電郵地址就足夠了,而郵寄地址則作為一個(gè)可選屬性。你會(huì)發(fā)現(xiàn)我們沒(méi)有在
38、代碼里面聲明哪些屬性是必須的,那是因?yàn)镚rails 默認(rèn)地假定所有屬性都是必須的。如果某一屬性不是必須的, 那么我們需要聲明它是可選的。為了做到這點(diǎn), 我們要定義optionals 屬性,顧名思義這是領(lǐng)域類中可選屬性的一個(gè)列表。如果我們想要定義另一個(gè)可選屬性,例如“性別”,把它加入列表 里面就可以了。 static optionals = postalAddress, gender 在 Race 這個(gè)領(lǐng)域類里面,我們聲明了一個(gè) Race 對(duì)象擁有零個(gè)或者多個(gè) Registration 對(duì)象。你會(huì)發(fā)現(xiàn)我們并沒(méi)有明確地說(shuō)一個(gè) Registration 對(duì)象是否可以單獨(dú)存在(即在沒(méi)有一個(gè)相應(yīng)的 Ra
39、ce 對(duì)象的情況下)。我們當(dāng)然知道不能在不存在的比賽上注冊(cè),所以我們?nèi)绾胃嬖V Grails 注冊(cè)是依附在賽跑上的呢?既然我們知道所有的屬性默認(rèn)上都是必須的,那么除非 race 屬性有一個(gè)非空值,否則無(wú)法保存一個(gè) Registration 對(duì)象。所以,事實(shí)上我 InfoQ 中文站:關(guān)注企業(yè)軟件開(kāi)發(fā)領(lǐng)域的變化與創(chuàng)新 /cn/你好,Grails!13 們的確已經(jīng)聲明了 Registration 對(duì)象不可能單獨(dú)存在。 belongsTo 屬性標(biāo)志了賽跑跟注冊(cè)之間的一對(duì)多關(guān)系的所有方。因?yàn)槲覀兟暶髁艘粋€(gè)注冊(cè)屬于一個(gè)賽跑(由注冊(cè)的 race 屬性確定),Grails 將會(huì)保證
40、刪除一個(gè)注冊(cè)不會(huì)刪除對(duì)應(yīng)的賽跑,但刪除一個(gè)賽跑會(huì)刪除所有相關(guān)的注冊(cè)。 熟悉的世界 現(xiàn)在看過(guò)了領(lǐng)域模型,我們可以看出 Grails 是多么地信奉面向?qū)ο缶幊?。我們的建模手法將與 Java、Ruby 或者其它面向?qū)ο笳Z(yǔ)言類似。事實(shí)上,隨著我們的進(jìn)一步學(xué)習(xí),你會(huì)發(fā)現(xiàn)你所喜歡的OO 和 MVC 概念將會(huì)繼續(xù)在 Grails 里面為你服務(wù)。 聽(tīng)上去不錯(cuò),實(shí)際又如何? 在我們開(kāi)始講述控制器之前,注意一下我們?cè)谶@些類中沒(méi)提到 過(guò)任何“對(duì)象關(guān)系映射”(Object Relational Mapping,ORM)或持久層之類的東西。這些領(lǐng)域類似乎沒(méi)有擴(kuò)展任何提供持久化功能 的類,它們也沒(méi)有實(shí)現(xiàn)任何標(biāo)志這些類需要
41、持久化的接口,它們也 沒(méi)有關(guān)聯(lián)任何提供持久化服務(wù)的類。而我們也沒(méi)編輯任何配置文件。是什么告訴 Grails 這些類需要持久化支持呢? 是“規(guī)約”讓我們省去了這些步驟。通過(guò)規(guī)約,Grails 自動(dòng)地把放在 racetrack/grails-app/domain 里面的類識(shí)別為領(lǐng)域類, 并且它知道領(lǐng)域類需要持久化。簡(jiǎn)單地遵循這個(gè)規(guī)約,Grails 幫我們做了所有的持久化工作,最終呢,它使我們有更多的時(shí)間去解決 更高難度且更有意思的問(wèn)題。 在背后,“Grails 對(duì)象關(guān)系映射”(GORM)擔(dān)負(fù)起必要的持久化功能。當(dāng)在 Grails 程序里用到持久化邏輯時(shí),GORM 就挑起了所有重?fù)?dān)(在底層,GORM
42、 現(xiàn)時(shí)依賴于 Hibernate,但在即將到來(lái)的版本中還會(huì)支持 JPA)。 取得控制萬(wàn)事俱備,只欠東風(fēng)。到目前為止我們所做的都是些沒(méi)法偷懶 Java .NET Ruby SOA Agile Architecture14Grails 入門(mén)指南 的事情(不管你的框架多么的智能,你始終需要說(shuō)明你要處理哪些數(shù)據(jù))。然而,下一步我們要為用戶界面建立一個(gè)良好而有效的出發(fā)點(diǎn),那就不再是體力活了。那么,是時(shí)候加上控制器了。 確 保 你 是 在 項(xiàng) 目 的 根 目 錄 下 ( 在 我 們 的 例 子 中 是r a c e t r a c k ) 。 接 著 , 輸 入 g r a i l screate- co
43、ntroller,并告訴 Grails 為 Race 這個(gè)領(lǐng)域類創(chuàng)建一個(gè)控制器。 racetrack grails create-controller.create-controller:input Enter controller name:Race.echo Created controller:grails-app/controllers/RaceController.groovy.BUILD SUCCESSFULTotal time: 3 seconds現(xiàn)在,讓我們來(lái)打開(kāi)新建的控制器,并看看要從哪里開(kāi)始。找 到 racetrack/grailsapp/controllers/RaceC
44、ontroller.gr oovy,打開(kāi)看一下。 class RaceController def index = 嗯。我們最終目標(biāo)就是通過(guò)用戶界面來(lái)管理賽跑數(shù)據(jù)。所以, 我們需要往控制器里面加入列出、添加、修改和刪除賽跑記錄的功能。讓我們加入必要的代碼來(lái)滿足這些需求。那需要多少行代碼呢? class RaceController def scaffold = Race那是什么啊?!事實(shí)上,那就是我們想要得 CRUD(添加-讀取-修改-刪除)功能。當(dāng) Grails 在控制器中碰到 scaffold 屬性時(shí),它會(huì)動(dòng)態(tài)地為特定的領(lǐng)域類生成控制邏輯以及必要的視圖,而所有的這些都來(lái)自于那一行代碼! I
45、nfoQ 中文站:關(guān)注企業(yè)軟件開(kāi)發(fā)領(lǐng)域的變化與創(chuàng)新 /cn/你好,Grails!15別光聽(tīng)我說(shuō),讓我們來(lái)對(duì)注冊(cè)數(shù)據(jù)重復(fù)應(yīng)用這個(gè)步驟,接著我們就準(zhǔn)備好運(yùn)行程序看看效果了。 跟著前面的步驟來(lái)創(chuàng)建R e g i s t r a t i o n C o n t r o l l e r 類。 class RegistrationController def scaffold = Registration現(xiàn)在,是時(shí)候看一下我們的成果了。在你的程序目錄下 (racetrack),輸入grails run-app。當(dāng)你看到程序成功啟動(dòng)的時(shí)候,打開(kāi)瀏覽器并訪問(wèn)http:/local
46、host:8080/racetrack。 好了。我們已有兩個(gè)控制器。就像歡迎頁(yè)中所說(shuō),我們最終將用定制的歡迎頁(yè)來(lái)取代這個(gè)頁(yè)面。不過(guò)現(xiàn)在呢, 讓我們先進(jìn)入RaceController。 Java .NET Ruby SOA Agile Architecture16Grails 入門(mén)指南 我們所期待的大部分的字段都在這里了,但由于沒(méi)有數(shù)據(jù),所 以還沒(méi)什么意思。點(diǎn)擊新建比賽來(lái)創(chuàng)建一些數(shù)據(jù),然后花些時(shí)間探 索一下目前的這個(gè)程序。當(dāng)你加入一些新數(shù)據(jù)之后,回過(guò)頭去試試 編輯現(xiàn)有的賽跑,刪除賽跑,并且試一下管理注冊(cè)部分的類似特性。在操作時(shí),記下你想要改進(jìn)的地方和需要改進(jìn)的地方。同時(shí), 看看那些已經(jīng)滿足了你的
47、需要的東西,它們都是不費(fèi)吹灰之力就得來(lái) 的! InfoQ 中文站:關(guān)注企業(yè)軟件開(kāi)發(fā)領(lǐng)域的變化與創(chuàng)新 /cn/你好,Grails!17你可能已經(jīng)發(fā)現(xiàn)有幾個(gè)地方顯然還需要改進(jìn),但大部分的程序只需稍微化化妝就可以了。 下面是我覺(jué)得必須具備的功能,至于那些錦上添花的功能當(dāng)然遲點(diǎn)我們也會(huì)談到。 驗(yàn)證我們從沒(méi)告訴 Grails 一場(chǎng)比賽的距離必須大于零米,比賽的名字必須不超過(guò)五十個(gè)字符,或者“松鼠”不是一個(gè)有效的性別。一句話,沒(méi)有驗(yàn)證。但我們很快就能加上去。 字段/數(shù)據(jù)列的排序當(dāng)我們查看比賽數(shù)據(jù)的時(shí)候,為什么城市排在最前面而州則在最后面,中間又夾雜著其它字段?因?yàn)槲覀兾丛嬖V
48、 Grails 該怎么排。其實(shí),解決這個(gè)問(wèn)題的方法很簡(jiǎn)單,我們很快就會(huì)看到。 記錄標(biāo)識(shí)符當(dāng)我們編輯單獨(dú)一條注冊(cè)信息時(shí),看一下在 Race 字段中顯示的是什么。你能記住哪個(gè)比賽是“ Race: 1”,哪個(gè)是“Race: 2”嗎?編輯一個(gè)比賽并查看它的注冊(cè)信息時(shí)也存在同樣的問(wèn)題。我們應(yīng)該讓這個(gè)信息更清晰一點(diǎn)。 就這些了。如果能夠解決這幾個(gè)問(wèn)題,我們就會(huì)有一個(gè)功能完整的網(wǎng)絡(luò)應(yīng)用程序來(lái)管理我們的賽跑跟注冊(cè)數(shù)據(jù)。在此之后,剩下的就只是錦上添花了。(當(dāng)然“添花”對(duì)我們繼續(xù)完成這個(gè)應(yīng)用也是大有裨益的。) 我的數(shù)據(jù)哪去了?是不是有件事情還沒(méi)做?我們從未告訴 Grails 我們安裝的 Java .NET Rub
49、y SOA Agile Architecture18Grails 入門(mén)指南 MySQL 數(shù)據(jù)庫(kù)的任何信息。那個(gè)內(nèi)存數(shù)據(jù)庫(kù)有時(shí)真的很好用,特別是初次實(shí)驗(yàn)的時(shí)候。但一旦我們重啟程序,就會(huì)丟失我們剛剛錄入的所有數(shù)據(jù)。這對(duì)目前來(lái)講沒(méi)什么問(wèn)題,但當(dāng)我們繼續(xù)深入的時(shí)候,我們絕對(duì)不會(huì)想要浪費(fèi)時(shí)間在重新輸入測(cè)試數(shù)據(jù)上。所以,既然我們挺滿意最初的領(lǐng)域模型,就讓 Grails 用 MySQL 數(shù)據(jù)庫(kù)來(lái)支持我們的程序吧。 小提示:如果我們只是單單想避免再次錄入測(cè)試數(shù)據(jù),我們可以考慮用 Grails 的 Bootstrap 類來(lái)幫忙,這樣內(nèi)存數(shù)據(jù)庫(kù)機(jī)還可以再撐一陣子。Bootstrap 類給執(zhí)行各種初始化工作提供了一
50、個(gè)方便的機(jī)制, 包括填充數(shù)據(jù)庫(kù)表在內(nèi)。然而,Bootstrap 類每次都會(huì)用同樣的數(shù)據(jù)來(lái)重新初始化程序,這樣我們重啟程序時(shí)將會(huì)丟失所有修改過(guò)的數(shù)據(jù)。所以我們最好還是連上一個(gè)傳統(tǒng)數(shù)據(jù)庫(kù)。Bootstrap 類我們放到第 6 章再講。 如果你查看 racetrack/grails-app/conf/,會(huì)發(fā)現(xiàn)我們的程序包含了每種常用環(huán)境(開(kāi)發(fā)、測(cè)試以及產(chǎn)品)的配置文件。我們會(huì)為每個(gè)環(huán)境分別創(chuàng)建獨(dú)立的數(shù)據(jù)庫(kù)。 開(kāi)發(fā)環(huán)境我們將定義一個(gè)叫 racetrack_dev 的數(shù)據(jù)庫(kù) 來(lái)支持開(kāi) 發(fā)過(guò)程, 而相應(yīng)的 配置會(huì)放 在racetrack/grailsapp/conf/DevelopmentDataSo u
51、rce.groovy。 調(diào)試環(huán)境 我們的單元測(cè)試和功能測(cè)試將依賴于racetrack_test 數(shù) 據(jù) 庫(kù) , 我 們 會(huì) 在racetrack/grailsapp/conf/TestDataSource.gr oovy 里面引用它。 產(chǎn)品環(huán)境最后,我們會(huì)創(chuàng)建 racetrack_prod 數(shù)據(jù)庫(kù)。在racetrack/grailsapp/conf/ProductionDataSou rce.groovy 的幫助下,我們將用這個(gè)環(huán)境來(lái)讓全世界享用我們的程序并一夜間成為億萬(wàn)富翁! 讓我們開(kāi)始吧 回到命令行窗口,按照下面的步驟創(chuàng)建必要的數(shù)據(jù)庫(kù)并賦以適當(dāng)?shù)脑L問(wèn)權(quán)限(我選擇了用我的個(gè)人 ID 來(lái)訪問(wèn)測(cè)
52、試和開(kāi)發(fā)環(huán)境, InfoQ 中文站:關(guān)注企業(yè)軟件開(kāi)發(fā)領(lǐng)域的變化與創(chuàng)新 /cn/你好,Grails!19用另外一個(gè)高 的 ID 和訪問(wèn)產(chǎn)品環(huán)境。你自己覺(jué)得怎樣合適就怎樣做。) racetrack mysql -u root -pEnter password: *Welcome to the MySQL monitor. Commands end with ; org.mysql create database racetrack_dev;.mysql create database racetrack_test;.mysql create database race
53、track_prod;.mysql grant all on racetrack_dev.* to jasonlocalhost identified by ;.mysql grant all on racetrack_test.* to jasonlocalhost identified by ;.mysql grant all on racetrack_prod.* to prodlocalhost identified by wahoowa;.mysql exit現(xiàn)在,我們已經(jīng)準(zhǔn)備好了把這些數(shù)據(jù)庫(kù)告知 Grails。用你的編輯器打開(kāi) DevelopmentDataSource.groovy,按照下面的配置修改它。你可以在 racetrack/grails-app/conf/里找到這個(gè)文件。(注意:你需要把用戶名和 替換成你自己的 MySQL 帳戶的用戶名和 。) class DevelopmentDataSource boolean pooling = true String dbCreate = updateSt
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年中職植物保護(hù)(農(nóng)藥應(yīng)用)試題及答案
- 2025年高職數(shù)字媒體(VR制作進(jìn)階)試題及答案
- 2025年大學(xué)歷史(世界近現(xiàn)代史)試題及答案
- 2025年大學(xué)化工類(化工安全規(guī)范)試題及答案
- 大學(xué)(藥學(xué))藥物分析技術(shù)2026年綜合測(cè)試題及答案
- 2025年大學(xué)大四(交通運(yùn)輸)交通運(yùn)輸綜合試題及答案
- 2025年大學(xué)攝影(攝影教育心理學(xué))試題及答案
- 2025年中職地質(zhì)工程技術(shù)(地質(zhì)勘探基礎(chǔ))試題及答案
- 2025年大學(xué)大三(會(huì)展經(jīng)濟(jì)與管理)會(huì)展經(jīng)濟(jì)分析階段測(cè)試題及答案
- 2025年大學(xué)大三(生物科學(xué))細(xì)胞生物學(xué)實(shí)驗(yàn)階段測(cè)試題及答案
- 中國(guó)工藝美術(shù)館招聘筆試試卷2021
- 申論范文寶典
- 【一例擴(kuò)張型心肌病合并心力衰竭患者的個(gè)案護(hù)理】5400字【論文】
- 四川橋梁工程系梁專項(xiàng)施工方案
- DB32T 3695-2019房屋面積測(cè)算技術(shù)規(guī)程
- 貴州省納雍縣水東鄉(xiāng)水東鉬鎳礦采礦權(quán)評(píng)估報(bào)告
- GB 8270-2014食品安全國(guó)家標(biāo)準(zhǔn)食品添加劑甜菊糖苷
- 2023年杭州臨平環(huán)境科技有限公司招聘筆試題庫(kù)及答案解析
- 易制毒化學(xué)品日常管理有關(guān)問(wèn)題權(quán)威解釋和答疑
- 湖北省高等教育自學(xué)考試
- 企業(yè)三級(jí)安全生產(chǎn)標(biāo)準(zhǔn)化評(píng)定表(新版)
評(píng)論
0/150
提交評(píng)論