第一篇:手把手教你編寫電視劇本【編劇專業(yè)知識講座】
手把手教你編寫電視劇本【編劇專業(yè)知識講座】
手把手教你編寫電視劇本
中國目前有編制的編劇幾千人,號稱或者自稱是編劇不下10萬人,兩者懸殊近百倍,國產(chǎn)劇超過一大半出自職業(yè)編劇,體制外的編劇寫的劇本能拍攝成影視劇,難于上青天。為什么會(huì)這樣?最近看到一個(gè)號稱是編制內(nèi)的金牌編劇的分析,啞然失笑,對于自稱金牌編劇無恥和肉麻感到震驚。我先講兩個(gè)笑話,看完本文,你也許再也笑不出來。
一顧客:飯店有什么菜可以賣?
老板:除了不能賣的,全部能賣。
顧客:我不關(guān)心那些菜不能賣,我只想知道有那些菜能賣?
老板:本飯店還沒有開業(yè)。
二中國電力:我們供應(yīng)全國99%的電力,還有1%自用。
中國石油:我們供應(yīng)全國99%的石油,還1%援助朝鮮
中國廣電:我們審查200%的影視劇,國產(chǎn)劇100%審查,進(jìn)口劇100%審查。
看到這兩個(gè)笑話后,我們能這樣問嗎?你的產(chǎn)品是優(yōu)質(zhì)產(chǎn)品嗎?價(jià)格合理嗎?經(jīng)過市場充分競爭嗎?你提供的服務(wù)是優(yōu)質(zhì)服務(wù)嗎?是我們必須的嗎?提供之前你有沒有經(jīng)過大家同意?
我們能選擇其他的產(chǎn)品或者服務(wù)嗎?
那位號稱金牌編劇的朋友,你的劇本和影視劇和這些產(chǎn)品比較一下,質(zhì)量如何?
你敢放開市場讓業(yè)余編劇和你同場競技嗎?
這位金牌編劇還在網(wǎng)絡(luò)上教育別人怎么寫作劇本。他這樣說,不能寫的題材就不要寫,不能寫的觀點(diǎn)就不要寫。
我就想問問這位金牌編劇,我不關(guān)心那些題材不能寫,那些觀點(diǎn)不能寫,我只關(guān)心那些題材能寫,那些觀點(diǎn)能寫,你能列舉出來嗎?明文刊登出來嗎?
如果不能,這和沒有開業(yè)的飯店有什么區(qū)別?
這位金牌劇本很自豪,列舉他的很多部作品作為教材和案例教育別人,我只想問一句,你所謂的作品,除了強(qiáng)迫中國人看,還有那個(gè)國家的人民愿意看你的作品,請列舉。
這個(gè)話題就討論到這里,不在深入,敬請?jiān)彙?/p>
下面開始討論一下怎么構(gòu)思和寫作電視劇本。
比如要寫一個(gè)青年創(chuàng)業(yè)的電視劇。
很多沒有編劇經(jīng)驗(yàn)的人,會(huì)這樣回答:寫這個(gè)青年怎么克服資金困難,解決技術(shù)難題,一次又一次失敗,這個(gè)青年堅(jiān)持不懈努力,從失敗中總結(jié)經(jīng)驗(yàn)和教訓(xùn),最后終于取得成功,事業(yè)和愛情雙豐收,得到領(lǐng)導(dǎo)高度贊揚(yáng)和肯定。
這樣的構(gòu)思可以不可以,完全可以,但是只能寫成一篇表揚(yáng)信或者一篇通訊稿,如果要拍攝成影視劇,這樣的結(jié)構(gòu)和故事,只會(huì)貽笑大方。
實(shí)際上,很多職業(yè)編劇就是這樣構(gòu)思和寫作劇本的,他們?yōu)槭裁磿?huì)這樣寫?我不想知道原因,你想知道嗎?
構(gòu)思一個(gè)電視劇本,按照本人的理解,大體可以分解為十一步,按照這些一步一步構(gòu)思,完成一個(gè)幾集的電視劇本大綱和分集故事大約幾天時(shí)間。
1寫出一個(gè)故事,越簡單越好,越精煉越好。
2設(shè)置主要人物。
3寫出人物之間的關(guān)系。
4設(shè)置人物的性格。
5寫出人物之間的關(guān)系變化
6提煉主題
7重新寫這個(gè)故事,按照分集寫故事。
8寫出每集故事的轉(zhuǎn)折點(diǎn)。
9列出各種關(guān)系發(fā)展變化表。比如人物關(guān)系,心理歷程,性格等發(fā)展變化表。
10回頭反復(fù)調(diào)整上面就九個(gè)步驟
11結(jié)合各種關(guān)系表,結(jié)合主題,完成分集劇本。
第一步我構(gòu)思這樣一個(gè)故事(故事是我隨便寫的,因?yàn)殡S意不具備典型性,僅僅當(dāng)作例子參考)
寫故事要遵守一個(gè)最簡單的原理,就是故事越寫越大,不能顛倒。
一個(gè)小偷,第一天偷針,第二天偷書,第三天偷錢,第四天調(diào)戲婦女,第五天搶劫,第六天強(qiáng)奸,第七天殺人。
這個(gè)故事雖然簡單,但是很典型,完全具備劇本的要求。完全可以擴(kuò)展成一個(gè)劇本,只要添加幾個(gè)女人,添加他扶老人過馬路,救起落水兒童,就可以寫成一個(gè)很長的電視劇。
回到青年創(chuàng)業(yè)故事
我就隨便舉一個(gè)例子:
小寶是一個(gè)剛參加工作的大學(xué)生,馬上要訂婚,在訂婚儀式上,被人罵養(yǎng)不起老婆,他決心先創(chuàng)業(yè)在結(jié)婚,他去蓋大樓,大樓馬上要竣工,忽然倒塌,他欠下巨債,為了還債,他開始地下賭博,并且抽老千,想依靠賭博還債,越陷越深,一次抽老千失手,被賭場追殺,他逃避追殺時(shí),失手打死一個(gè)賭徒,他想私了,對方開價(jià)1000萬,他被逼無奈,只能奮起反抗,最后徹底打掉整個(gè)地下黑賭場。
第一步就完成了,非常簡單的一個(gè)套路故事,回頭檢查一遍這是一個(gè)創(chuàng)業(yè)故事嗎?回答是肯定的,他雖然沒有積累物質(zhì)財(cái)富,沒有創(chuàng)辦公司,但是他學(xué)會(huì)兩樣技能,殺人和賭博,這是非常高超的專業(yè)技能,他依靠自己的專業(yè)技能成功消滅一個(gè)黑惡勢力,這是一個(gè)很大很壯舉的事業(yè)。
第二步設(shè)置角色
我一共設(shè)置了六個(gè)角色
小寶(男),小寶父母,小美(女),大雄(男),小麗(女)。
第三步人物關(guān)系
小寶,小寶的父母,小美是小寶的大學(xué)同學(xué),也是他一直追求的對象。大雄是小寶的大學(xué)同學(xué),也是他同事,也是他最好的朋友。小麗一直在暗戀小寶。
第四步設(shè)置人物性格。
小寶聰明好學(xué),上進(jìn)青年,順境盲目樂觀,自大自狂,逆境孤注一擲,不計(jì)后果。
大雄,富家子弟,心狠手辣,放蕩淫蕩,估計(jì)多端。
小美雖然是女主角,女主角只是名字而已,其實(shí)還是配角。她的性格我先設(shè)置兩種可能,根據(jù)劇情發(fā)展再取舍。
1妓女性格,小寶有錢時(shí)笑臉相迎,小寶落魄時(shí)一腳踢開。
2淑女慢慢變化為俗女。天真浪漫的少女一步步世俗化。
小麗性格含蓄羞澀,但是意志力頑強(qiáng),鍥而不舍。
第五步
小寶的歷程:無知青年,上進(jìn),失意,磨練,學(xué)會(huì)殺人和賭博,成熟青年。
小美心理歷程:天真爛漫少女-搖擺青年-勢利女人-庸俗女人【 熱戀-搖擺-分裂-失望-絕望-分手】
大雄:胡鬧青年,惡霸青年,殺人青年,懦夫。
小麗:浪漫少女,堅(jiān)持浪漫,相信愛情純潔的熟女。
第六步提煉主題。
我提煉的主題是:
人生悲劇往往是順境盲目冒進(jìn),逆境瘋狂冒險(xiǎn)造成的。
提煉主題有兩個(gè)原則,1符合本故事的情節(jié)。2和大多數(shù)人的體驗(yàn)接近或者相似。
第七步重新寫故事。
我暫時(shí)把這個(gè)電視劇分成五集。
1集
小寶,小美,小麗,大雄是大學(xué)同學(xué),畢業(yè)后進(jìn)了同一家大公司,小寶家庭一般,勤奮上進(jìn),深受上司喜歡。大雄是富家子弟,他和小寶是最好的兄弟,兩人無話不談,大雄喜歡惹花拈草,上班經(jīng)常遲到,他們兩都在追求小美,小美搖擺不定,直到有一天一個(gè)妓女追到公司大罵大雄,小美才決心嫁給小寶,小寶和小美準(zhǔn)備訂婚,在訂婚儀式上,大雄毆打小寶,并且罵小寶沒有能力養(yǎng)活老婆,小寶咽不下這口氣,決定辭職,自己蓋大樓。小麗一直暗戀這小寶,準(zhǔn)備出國。
2集
小寶蓋大樓遇到資金困難,小美自己去找大雄借錢,大雄提出只要和他睡一覺,并且離開小寶,他就借錢。小美猶豫不決。
小寶借很多錢,把自己的家房產(chǎn)也抵押出去,還借入高利貸,大樓終于開工,房價(jià)一直在飆升,小寶和小美整天住進(jìn)酒店里,花天酒地,長期不回家,父母非常想念他們。
突降暴雨,大樓整體垮塌,小寶陷入危機(jī)中。
3集
走投無路的小寶決心冒險(xiǎn),參加地下賭場,父母和小美反對。小寶向小麗借錢,依靠自己超強(qiáng)的計(jì)算能力和抽老千,他贏了很多錢,小美勸他收手,小寶相信自己能贏更多錢。
終于有一天,被大雄抓住他在抽老千,賭場開始追殺他。
4集
小寶被追殺,自衛(wèi),失手打死一個(gè)賭徒。開始東躲西藏,小美受不了驚嚇,提出分手。
小寶想通過賠償私了,大雄開價(jià)1000萬,小寶徹底絕望,大雄友開始追殺他。
5集
陷入絕境的小寶,在小麗幫助下,開始反擊,他將賭場一網(wǎng)打盡,并且控制住大雄,大雄求情,小寶念在多年朋友的情面上,放走大雄,大雄移居美國。
小麗和小寶訂婚。
第八步列出每集的轉(zhuǎn)折點(diǎn)
1訂婚儀式上大雄辱罵小寶
2大樓倒塌
3小寶抽老千被發(fā)現(xiàn)
4小寶殺人
5談判破裂
1集喜劇 2集悲劇 3集喜劇 4集悲劇 5集大結(jié)局也是高潮。
第九步
劇中人和主角的關(guān)系發(fā)展變化表。
小美 大雄 小麗
1集 朋友---戀人 朋友----開始開裂 暗戀小寶
2集 親密---動(dòng)搖 分裂-----反目
3集 動(dòng)搖---裂痕 成仇
4集 失望---絕望 追殺 挑明
5集 分手 相互追殺 戀人
線索 : 主線-------小寶創(chuàng)業(yè)的興衰。
副線1----小寶和小美的戀情。
副線2----小寶和大雄從朋友到敵人。
副線3----小寶和小麗的戀情。
第十步,反復(fù)修正上面的結(jié)構(gòu)和故事。
第十一步寫出大綱和分集劇本。
由于有人物關(guān)系的限制,情感的限制,以及主題制約,分集故事其實(shí)并沒很大的回旋余地,按照套路故事填充即可。到這里一個(gè)鬧劇故事完成一大半。
文學(xué)藝術(shù)和影視藝術(shù)都是講故事,解剖人性,揭示人性中的善惡,揭示社會(huì)運(yùn)動(dòng)和人物命運(yùn)的藝術(shù)。
本劇只是愛情事業(yè)交織的故事,人物的命運(yùn)和自己行為以及他的親人朋友形成互動(dòng)關(guān)系,社會(huì)作為大背景或者大平臺(tái),沒有參與人物命運(yùn)的互動(dòng),所以本劇只是一個(gè)鬧劇。還不能作為真正藝術(shù)作品。
第二篇:廈大無機(jī)化學(xué)專業(yè)考研人,手把手教你復(fù)習(xí)范文
廈大無機(jī)化學(xué)專業(yè)考研人,手把手教你復(fù)習(xí)
首先做個(gè)自我介紹,本人于2012年報(bào)考廈大無機(jī)化學(xué)專業(yè)研究生,初試成績還算不錯(cuò),總分372,無機(jī)化學(xué)135,單科分?jǐn)?shù)在當(dāng)年也算前兩名了。然后順利的通過復(fù)試,如今在廈大化學(xué)系的某個(gè)角落默默奮斗著。
對于一個(gè)考研人來說,了解自己所考學(xué)科排名很重要,研究生不同于本科生,本科生可能更注重學(xué)校的綜合實(shí)力,但是研究生應(yīng)該更需看重報(bào)考專業(yè)的排名。廈大的化學(xué)實(shí)力確實(shí)不俗,個(gè)人認(rèn)為比北大差不了多少,至少在師資力量和硬件設(shè)施方面不會(huì)遜色多少,有些地方還有過之。廈大的化學(xué)考研試題,側(cè)重于學(xué)生所學(xué)知識的深度,一般都是擇兩門專業(yè)課選考,比如考無機(jī)化學(xué)專業(yè),無機(jī)和物理化學(xué)必考;考有機(jī)化學(xué)專業(yè),有機(jī)和物化必考;考物理化學(xué)專業(yè),物理化學(xué)是必考的,但另一門專業(yè)課就可以根據(jù)考生的自我評估選擇考無機(jī)化學(xué)或是有機(jī)化學(xué)。我很喜歡廈大這種考試方式,因?yàn)樗苓m合我。我本科的化學(xué)基礎(chǔ),個(gè)人感覺只有物理化學(xué)相對來說還學(xué)的不錯(cuò),大學(xué)四年,只有兩門課我是認(rèn)真聽講,認(rèn)真完成老師所布置的任務(wù),其中之一就是物理化學(xué)。廈大的物理化學(xué)確實(shí)有點(diǎn)難度,注重考生對知識的掌握深度和實(shí)際應(yīng)用。但我認(rèn)為無論其多么難,那是相對于所有人的,只要自己能夠?qū)W懂,考試能得100多分就行了。廈大的無機(jī)化學(xué)考研難度算一般,不是特別難,除卻2013年,聽說難的讓人抓狂。個(gè)人認(rèn)為無機(jī)化學(xué)就兩本書,只要肯花點(diǎn)時(shí)間,反復(fù)的看書,問題也不會(huì)有多大。
現(xiàn)在說說我的考研復(fù)習(xí)時(shí)間安排吧,我是從2011年4月份開始復(fù)習(xí)無機(jī)化學(xué)上冊,整個(gè)四月份都只看無機(jī)化學(xué)上冊,只看書,每天花半天時(shí)間(3小時(shí))去圖書館。我看書比較注重效率,也感覺自己那段時(shí)間效率比較高,所以就抓緊時(shí)間看(考研復(fù)習(xí)都有疲勞期,所以趁狀態(tài)好的時(shí)候多復(fù)習(xí)點(diǎn))。每次看書的時(shí)候只帶課本和筆,本人不習(xí)慣用筆記本,看書期間遇到的問題或是重點(diǎn)我喜歡直接標(biāo)注在書本上,我那本無機(jī)化學(xué)課本在最后反正是找不到一頁沒有注解的空白地方。我還有個(gè)習(xí)慣就是喜歡將書本上的重要公式或是非常重要的定義寫在那一頁的頂端或是下端,這樣有助于復(fù)習(xí)時(shí)加深印象,翻到那一頁就知道主要講了什么內(nèi)容。整個(gè)四月份我將無機(jī)化學(xué)上冊看了一遍,當(dāng)然有些難以理解的地方就多花了時(shí)間??唇滩牡耐瑫r(shí)我也獲得了一本相當(dāng)不錯(cuò)的課外輔導(dǎo)書,即思睿廈大考研網(wǎng)出的《廈門大學(xué)617無機(jī)化學(xué)考研復(fù)習(xí)精編》,此書包含章節(jié)知識點(diǎn)歸納,考題考點(diǎn)解析、知識框架圖及歷年真題及答案解析等內(nèi)容,用起來很方便。我看書也是主要是以章節(jié)為單位,爭取看一章能將那一章的知識有個(gè)了解,爭取看懂。
看完這本書就給自己放了一個(gè)五一長假,然后就開始復(fù)習(xí)物理化學(xué)了,物理化學(xué)也注重看書,最好是復(fù)習(xí)廈大孫世剛那兩本書,很全面,跟考試結(jié)合很緊密。物理化學(xué)是一項(xiàng)艱苦的工程,不僅難懂,還很難記住,感覺就是看不懂,看了后面就忘了前面,做題幾乎沒把握。不過這時(shí)不要灰心,始終要堅(jiān)信難是對于所有人的,只要自己努力了,結(jié)果肯定不會(huì)差。物理化學(xué)需要一章節(jié)一章節(jié)的復(fù)習(xí),然后做課后習(xí)題,這樣有助于理解,重復(fù)看書,重復(fù)做題,吃透每章節(jié)的內(nèi)容,只有這樣才會(huì)在看后續(xù)章節(jié)時(shí)不會(huì)不知所云。復(fù)習(xí)物理化學(xué)花的時(shí)間就多了,兩本物理化學(xué)書我是從5月份看到了八月底,當(dāng)然這期間也有一些耽誤,比如復(fù)習(xí)期末考試,暑假休息半個(gè)月,總的算來花了三個(gè)月把書本拉通看了一遍。最重要的是在這期間無機(jī)化學(xué)不能丟下,雖然不像四月份那樣每天看,但是需要時(shí)常翻翻書,看一看比較難理解的章節(jié),如原子結(jié)構(gòu)和元素周期律,化學(xué)鍵理論和配位化學(xué)那幾章,順帶做做題。這樣到九
月開學(xué)時(shí)幾乎就把無機(jī)化學(xué)上冊搞定了,物理化學(xué)也有了個(gè)大概的了解。對于這期間花在專業(yè)課上的時(shí)間應(yīng)該每天不少于三小時(shí)吧,而且是連續(xù)的三小時(shí),這樣有助于系統(tǒng)復(fù)習(xí)。
九月開學(xué)后就要安排全程復(fù)習(xí)了,無論是公共課還是專業(yè)課,具體時(shí)間安排因人而異,自己感覺難的科目可以多安排點(diǎn)時(shí)間,復(fù)習(xí)順利的科目少花點(diǎn)時(shí)間,盡量是各科考試平衡,偏科很讓人受傷啊。我當(dāng)時(shí)的復(fù)習(xí)就是晚上的時(shí)間都留給專業(yè)課,物化和無機(jī),白天安排政治和英語。晚上的時(shí)間相對來說較多,差不多可以連續(xù)學(xué)習(xí)四個(gè)小時(shí)。此段時(shí)間的專業(yè)課就主要集中在物理化學(xué)了,看書加習(xí)題練習(xí),兩本教材上的習(xí)題必須全部解決,同時(shí)可以做點(diǎn)其他資料上的題,畢竟物理化學(xué)注重解題思路及技巧。無機(jī)化學(xué)上冊在前幾個(gè)月差不多復(fù)習(xí)的可以放手了,所以從九月開始就需要復(fù)習(xí)無機(jī)元素化學(xué)了。無機(jī)元素化學(xué)的復(fù)習(xí)雖然內(nèi)容多,但是只要把無機(jī)化學(xué)上冊理解透了,搞定它也不是問題。無機(jī)化學(xué)的章節(jié)都是按照元素周期表族來劃分,各章聯(lián)系不是很大,有些章節(jié)會(huì)熟悉點(diǎn),有些章節(jié)會(huì)陌生點(diǎn),所以復(fù)習(xí)此部分需要按章復(fù)習(xí),爭取把每章節(jié)知識記住。此外,在此期間我還開始琢磨《廈門大學(xué)617無機(jī)化學(xué)考研復(fù)習(xí)精編》這本書里的一些典型題目,這樣有助于加深記憶。
十月國慶可以休息幾天,貌似我當(dāng)年休息了七天,當(dāng)時(shí)確實(shí)感覺累了,所以給自己找了很多理由輕松了一段時(shí)間。國慶假結(jié)束后,我給自己制定了一個(gè)復(fù)習(xí)計(jì)劃——最后三個(gè)月考研復(fù)習(xí)時(shí)間安排,主要是根據(jù)自己前段時(shí)間復(fù)習(xí)情況安排后面時(shí)間的分配。上午政治(3h),下午英語(3h),晚上專業(yè)課(4h),專業(yè)課就是看書加做真題,此時(shí)做真題很有效果,可以指導(dǎo)自己再看書,如此三個(gè)月下來專業(yè)課就差不多符合考試要求了。到了考前一個(gè)星期,可以自己試著羅列一下專業(yè)課各章節(jié)重點(diǎn),讓各知識點(diǎn)在自己腦海中形成一個(gè)框架圖,這樣有助于考試做題時(shí)提取信息。
對于復(fù)試,本人強(qiáng)烈感覺廈大的無機(jī)化學(xué)復(fù)試很簡單,只要你考研成績在前面,基本不可能淘汰你,所以我的建議就是盡量使自己的初試成績高。其實(shí)很多年份廈大的無機(jī)化學(xué)都需要相應(yīng)專業(yè)調(diào)劑,所以只要你分?jǐn)?shù)能上線,復(fù)試基本沒有問題。
此次只是給大家一個(gè)簡略的復(fù)習(xí)建議,在后續(xù)各個(gè)階段我會(huì)給大家更加詳細(xì)的復(fù)習(xí)建議,如果覺得有所幫助,請留心此網(wǎng)站。
以上只是本人拙見,望各位同仁選擇看之,也希望能夠?qū)τ延褌冇兴鶐椭?/p>
第三篇:play手把手教你創(chuàng)建一個(gè)博客項(xiàng)目-02.迭代編寫數(shù)據(jù)模型代碼
02.迭代編寫數(shù)據(jù)模型代碼
下面,我們將開始為我們的博客引擎寫一個(gè)數(shù)據(jù)模型。
JPA介紹
在play應(yīng)用程序(事實(shí)上也包括所有設(shè)計(jì)良好的應(yīng)用程序)里,模型層是最為核心的地方。play是一個(gè)域驅(qū)動(dòng)類型的數(shù)據(jù)表現(xiàn)框架,既然我們想要?jiǎng)?chuàng)建一個(gè)博客引擎,那么模型層所需要的類(比如User/Post和Comment)就應(yīng)當(dāng)首先考慮。
因?yàn)榇蠖鄶?shù)模型對象都需要在應(yīng)用程序重新啟動(dòng)后能夠繼續(xù)保存數(shù)據(jù),因此,我們就必須把它們保存在一個(gè)可持久化的存儲(chǔ)器里。通常,我們會(huì)選擇一個(gè)關(guān)系數(shù)據(jù)庫來保存數(shù)據(jù)。但是,由于java是面向?qū)ο蟮恼Z言,因此,我們將使用對象關(guān)系映射來減少匹配阻抗。
Java Persistence API(JPA)是一個(gè)Java規(guī)范,它定義了一個(gè)標(biāo)準(zhǔn)的對象關(guān)系映射API集。作為JPA規(guī)范的實(shí)現(xiàn),play使用眾所周知的Hibernate框架來實(shí)現(xiàn)JPA。使用基于Hibernate API的JPA的一個(gè)優(yōu)勢就是所有映射都是在java對象里進(jìn)行聲明的。
如果在此之前你曾經(jīng)用過Hibernate或JPA,那么在play里使用JPA你會(huì)感到非常驚訝,因?yàn)樵赑lay里使用Hibernate或JPA實(shí)在是太簡單了,它不需要進(jìn)行任何配置即可正常工作~!
如果你不知道什么是JPA,哈哈,請?jiān)诶^續(xù)下面的課程之前先補(bǔ)補(bǔ)課some of these simple presentations。
創(chuàng)建第一個(gè)模型類User 接下來我們將開始為博客引擎編寫代碼,首先是創(chuàng)建User類,接下來讓我們創(chuàng)建/yabe/app/models/User.java類: package models;
import java.util.*;import javax.persistence.*;
import play.db.jpa.*;
@Entity public class User extends Model {
public String email;public String password;public String fullname;public boolean isAdmin;
public User(String email, String password, String fullname){ this.email = email;this.password = password;this.fullname = fullname;} } @Entity注釋使User類成為一個(gè)可被管理的JPA實(shí)體,其繼承的Model超類自動(dòng)為其提供了一系列非常有用的JPA幫助方法(后面我們會(huì)作介紹)。所有User類的fields(以下均稱為字段,不再提示)都會(huì)自動(dòng)持久化到數(shù)據(jù)庫里。默認(rèn)情況下,數(shù)據(jù)庫表的名稱為 ‘User’。在某些情況下,默認(rèn)的表名可能會(huì)與數(shù)據(jù)庫的保留關(guān)鍵字沖突,這時(shí)就需要對數(shù)據(jù)庫表名進(jìn)行定制,比如針對User類,可以注釋為@Table(name=“blog_user”)。
繼承play.db.jpa.Model類并不是必須的,你可以繼續(xù)使用原始的JPA。但繼承Model類是一個(gè)好的選擇,通過繼承Model類,你可以通過它提供的幫助方法很方便的對實(shí)體類進(jìn)行操作。
如果之前你用過JPA,那么你應(yīng)該知道每個(gè)JPA實(shí)體都必須提供一個(gè)@Id屬性。在這里,Model超類提供了一個(gè)自動(dòng)生成數(shù)字型ID的功能,在很多情況下已經(jīng)足夠了。
注意,請不要把Model自動(dòng)提供的ID當(dāng)作功能性標(biāo)識符使用,只能把它當(dāng)成是技術(shù)性標(biāo)識符使用。通常情況下,自動(dòng)生成的數(shù)字ID作為一個(gè)技術(shù)標(biāo)識符是個(gè)較好的主意。
如果你是一個(gè)經(jīng)驗(yàn)豐富的java開發(fā)者,那么你就會(huì)知道在模型對象里的字段應(yīng)該是private的,訪問這些字段的方式是為這些字段創(chuàng)建getter/setter方法。但是,在play里,字段是用public修飾的,其目的是為了編寫代碼的量,請別擔(dān)心,事實(shí)上play會(huì)小心照顧好這些字段,自動(dòng)為其生成getter/setter。刷新一下應(yīng)用程序主頁,看看有些什么變化沒。事實(shí)上,除非代碼有錯(cuò)誤,你應(yīng)該看不到任何變化。play已經(jīng)自動(dòng)編譯和加載了User類,但是這并沒有為應(yīng)用程序添加任何新的特征。
編寫第一個(gè)測試程序 在play里,測試新創(chuàng)建的User類的好方法就是編寫一個(gè)JUnit單元測試。這個(gè)測試將允許你對User進(jìn)行測試。
要想進(jìn)行測試,你得把play切換到test模式下。首先停止當(dāng)前正在運(yùn)行的應(yīng)用程序,在命令行輸入如下命令,以切換到測試模式: ~$ play test 除了加載了一個(gè)test runner模塊,以允許你在瀏覽器直接運(yùn)行測試組件外,play test命令和play run很相似。
當(dāng)play運(yùn)行與測試模式時(shí),Play將自動(dòng)切換到測試框架ID,并加載相應(yīng)的application.conf配置文件,參考framework ID documentation了解更多信息。在瀏覽器打開http://localhost:9000/@tests URL地址,就可以看到test runner了。試著選擇所有默認(rèn)的測試并運(yùn)行它們,所有的結(jié)果都應(yīng)該是綠色的?其實(shí)這些測試并沒有進(jìn)行任何實(shí)質(zhì)性的測試。為了測試User模型(適用于所有的模型類),我們打算使用JUnit測試。正如你所看到的一樣,play已經(jīng)提供了一個(gè)默認(rèn)的BasicTests.java文件,讓我們打開看看(/yabe/test/BasicTest.java): import org.junit.*;import play.test.*;import models.*;
public class BasicTest extends UnitTest { @Test public void aVeryImportantThingToTest(){ assertEquals(2, 1 + 1);} } 刪除默認(rèn)的無用的測試(aVeryImportantThingToTest),并創(chuàng)建一個(gè)新的測試,在其中將試著創(chuàng)建一個(gè)新的user,并得到它:
@Test public void createAndRetrieveUser(){ // Create a new user and save it new User(“bob@gmail.com”, “secret”, “Bob”).save();
// Retrieve the user with e-mail address bob@gmail.com User bob = User.find(“byEmail”, “bob@gmail.com”).first();
// Test assertNotNull(bob);assertEquals(“Bob”, bob.fullname);} 正如你所看到的一樣Model超類提供了兩個(gè)非常有用的方法save()and find()。在play管理手冊的JPA support節(jié),你可了解更多Model類的方法。在test runner里選擇BasicTests.java,單擊start進(jìn)行測試,可以看到結(jié)果全是綠色。
接下來,我們需要在User里創(chuàng)建一個(gè)驗(yàn)證user的username和password是否正確的方法(通過username和password來找到user)。打開User.java源文件,添加connect()方法:
public static User connect(String email, String password){ return find(“byEmailAndPassword”, email, password).first();} 在BasicTests.java里添加測試代碼:
@Test public void tryConnectAsUser(){ // Create a new user and save it new User(“bob@gmail.com”, “secret”, “Bob”).save();
// Test assertNotNull(User.connect(“bob@gmail.com”, “secret”));assertNull(User.connect(“bob@gmail.com”, “badpassword”));assertNull(User.connect(“tom@gmail.com”, “secret”));} 每次修改后,你都可以直接在test runner里運(yùn)行所有的測試。
創(chuàng)建Post類
Post類用展現(xiàn)發(fā)表的博客:
package models;
import java.util.*;import javax.persistence.*;
import play.db.jpa.*;
@Entity public class Post extends Model {
public String title;public Date postedAt;
@Lob public String content;
@ManyToOne public User author;
public Post(User author, String title, String content){ this.author = author;this.title = title;this.content = content;this.postedAt = new Date();} } 在這里,我們使用@Lob注釋來告訴JPA這個(gè)字段是一個(gè)超大文本數(shù)據(jù)庫類型,用是存儲(chǔ)發(fā)表的內(nèi)容。我們同時(shí)用@ManyToOne來聲明Post與User是多對一的關(guān)系。意思是每篇博客都是單個(gè)用戶寫的,每個(gè)用戶可是發(fā)表多篇博客?,F(xiàn)在的PostgreSQL版本還不能存儲(chǔ)用@Lob注釋的String類型字段,解決方法是使用@Type(type = “org.hibernate.type.TextType”)進(jìn)行注釋。接下來,我們將編寫新的測試代碼用于測試Post類。但是在寫更多測試代碼之前,我們需要在JUnit測試類里做一些工作,比如在當(dāng)前的測試代碼里,數(shù)據(jù)庫內(nèi)容并不會(huì)刪除,因此,我們每運(yùn)行一次,play就會(huì)增加一個(gè)新創(chuàng)建的對象,這些對象會(huì)越來越多,當(dāng)進(jìn)行更高級的測試時(shí),這或許會(huì)成為問題。
因此,讓我們在運(yùn)行每個(gè)測試之前寫一個(gè)JUnit setup()方法來刪除數(shù)據(jù)庫: public class BasicTest extends UnitTest {
@Before public void setup(){ Fixtures.deleteDatabase();}
? } @Before是JUnit測試工具最核心的概念。
正如你所看到的,F(xiàn)ixtures類幫助我們在測試期間管理數(shù)據(jù)庫。接下來,我們將編寫下一個(gè)測試:
@Test public void createPost(){ //創(chuàng)建一個(gè)新的user,并保存
User bob = new User(“bob@gmail.com”, “secret”, “Bob”).save();
// 創(chuàng)建一個(gè)新post new Post(bob, “My first post”, “Hello world”).save();
// 測試上一步是否創(chuàng)建了新的post assertEquals(1, Post.count());
// 獲取所有“Bob”發(fā)表的posts List
bobPosts = Post.find(“byAuthor”, bob).fetch();
// Tests assertEquals(1, bobPosts.size());Post firstPost = bobPosts.get(0);assertNotNull(firstPost);assertEquals(bob, firstPost.author);assertEquals(“My first post”, firstPost.title);assertEquals(“Hello world”, firstPost.content);assertNotNull(firstPost.postedAt);} 千萬不要忘記了導(dǎo)入java.util.List,否則會(huì)出現(xiàn)編譯錯(cuò)誤。
編寫Comment類
最后一件事就是創(chuàng)建Comment類,為發(fā)表的博客提供評論的能力。package models;
import java.util.*;import javax.persistence.*;
import play.db.jpa.*;
@Entity public class Comment extends Model {
public String author;public Date postedAt;@Lob public String content;
@ManyToOne public Post post;
public Comment(Post post, String author, String content){ this.post = post;this.author = author;this.content = content;this.postedAt = new Date();} } Comment的測試代碼: @Test public void postComments(){ // Create a new user and save it User bob = new User(“bob@gmail.com”, “secret”, “Bob”).save();
// Create a new post Post bobPost = new Post(bob, “My first post”, “Hello world”).save();
// Post a first comment new Comment(bobPost, “Jeff”, “Nice post”).save();new Comment(bobPost, “Tom”, “I knew that!”).save();
// Retrieve all comments List
// Tests assertEquals(2, bobPostComments.size());
Comment firstComment = bobPostComments.get(0);assertNotNull(firstComment);assertEquals(“Jeff”, firstComment.author);assertEquals(“Nice post”, firstComment.content);assertNotNull(firstComment.postedAt);
Comment secondComment = bobPostComments.get(1);assertNotNull(secondComment);assertEquals(“Tom”, secondComment.author);assertEquals(“I knew that!”, secondComment.content);assertNotNull(secondComment.postedAt);} 這里,你可以看到在Post和Comment之間進(jìn)行導(dǎo)航并不容易:我們需要使用查詢來找到一個(gè)博文的所有評論。在這里我們還有更好的方法,方法就是在Post類里定義它與Comment之間的一多對關(guān)系。在Post類里添加一個(gè)comments域:
...@OneToMany(mappedBy=“post”, cascade=CascadeType.ALL)public List
public Post(User author, String title, String content){ this.comments = new ArrayList
定義好上述關(guān)系后,我們需要在Post類里添加一個(gè)幫助方法用于添加評論: public Post addComment(String author, String content){ Comment newComment = new Comment(this, author, content).save();this.comments.add(newComment);this.save();return this;} 其測試代碼為:
@Test public void useTheCommentsRelation(){ // Create a new user and save it User bob = new User(“bob@gmail.com”, “secret”, “Bob”).save();
// Create a new post Post bobPost = new Post(bob, “My first post”, “Hello world”).save();
// Post a first comment bobPost.addComment(“Jeff”, “Nice post”);bobPost.addComment(“Tom”, “I knew that!”);
// Count things assertEquals(1, User.count());assertEquals(1, Post.count());assertEquals(2, Comment.count());
// Retrieve Bob's post bobPost = Post.find(“byAuthor”, bob).first();assertNotNull(bobPost);
// Navigate to comments assertEquals(2, bobPost.comments.size());assertEquals(“Jeff”, bobPost.comments.get(0).author);
// Delete the post bobPost.delete();
// Check that all comments have been deleted assertEquals(1, User.count());assertEquals(0, Post.count());assertEquals(0, Comment.count());} 測試下看看:
使用Fixtures來編寫更復(fù)雜的測試 在開發(fā)編寫更復(fù)雜的測試之前,我們通常需要提前準(zhǔn)備一系列的測試數(shù)據(jù),F(xiàn)ixtures類允許我們在一個(gè)YAML文件里描述需要準(zhǔn)備數(shù)據(jù)的模型,它允許我們在進(jìn)行任何測試之前加載這個(gè)yaml文件。
編輯/yabe/test/data.yml文件,對User模型的數(shù)據(jù)進(jìn)行描述:
User(bob): email: bob@gmail.com password: secret fullname: Bob...OK,這個(gè)data.yml文件有點(diǎn)大,我們已經(jīng)提前準(zhǔn)備好了,還是下載吧download it here。
接下來,我們將在測試代碼里加載這個(gè)文件里描述的數(shù)據(jù),并對它進(jìn)行測試: @Test public void fullTest(){ Fixtures.loadModels(“data.yml”);
// Count things assertEquals(2, User.count());assertEquals(3, Post.count());assertEquals(3, Comment.count());
// Try to connect as users assertNotNull(User.connect(“bob@gmail.com”, “secret”));assertNotNull(User.connect(“jeff@gmail.com”, “secret”));assertNull(User.connect(“jeff@gmail.com”, “badpassword”));assertNull(User.connect(“tom@gmail.com”, “secret”));
// Find all of Bob's posts List
bobPosts = Post.find(“author.email”, “bob@gmail.com”).fetch();assertEquals(2, bobPosts.size());
// Find all comments related to Bob's posts List
// Check that this post has two comments assertEquals(2, frontPost.comments.size());
// Post a new comment frontPost.addComment(“Jim”, “Hello guys”);assertEquals(3, frontPost.comments.size());assertEquals(4, Comment.count());} 更多關(guān)于YAML的內(nèi)容,請閱讀YAML manual page。