第一篇:手把手教你编写电视剧本【编剧专业知识讲座】
手把手教你编写电视剧本【编剧专业知识讲座】
手把手教你编写电视剧本
中国目前有编制的编剧几千人,号称或者自称是编剧不下10万人,两者悬殊近百倍,国产剧超过一大半出自职业编剧,体制外的编剧写的剧本能拍摄成影视剧,难于上青天。为什么会这样?最近看到一个号称是编制内的金牌编剧的分析,哑然失笑,对于自称金牌编剧无耻和肉麻感到震惊。我先讲两个笑话,看完本文,你也许再也笑不出来。
一顾客:饭店有什么菜可以卖?
老板:除了不能卖的,全部能卖。
顾客:我不关心那些菜不能卖,我只想知道有那些菜能卖?
老板:本饭店还没有开业。
二中国电力:我们供应全国99%的电力,还有1%自用。
中国石油:我们供应全国99%的石油,还1%援助朝鲜
中国广电:我们审查200%的影视剧,国产剧100%审查,进口剧100%审查。
看到这两个笑话后,我们能这样问吗?你的产品是优质产品吗?价格合理吗?经过市场充分竞争吗?你提供的服务是优质服务吗?是我们必须的吗?提供之前你有没有经过大家同意?
我们能选择其他的产品或者服务吗?
那位号称金牌编剧的朋友,你的剧本和影视剧和这些产品比较一下,质量如何?
你敢放开市场让业余编剧和你同场竞技吗?
这位金牌编剧还在网络上教育别人怎么写作剧本。他这样说,不能写的题材就不要写,不能写的观点就不要写。
我就想问问这位金牌编剧,我不关心那些题材不能写,那些观点不能写,我只关心那些题材能写,那些观点能写,你能列举出来吗?明文刊登出来吗?
如果不能,这和没有开业的饭店有什么区别?
这位金牌剧本很自豪,列举他的很多部作品作为教材和案例教育别人,我只想问一句,你所谓的作品,除了强迫中国人看,还有那个国家的人民愿意看你的作品,请列举。
这个话题就讨论到这里,不在深入,敬请原谅。
下面开始讨论一下怎么构思和写作电视剧本。
比如要写一个青年创业的电视剧。
很多没有编剧经验的人,会这样回答:写这个青年怎么克服资金困难,解决技术难题,一次又一次失败,这个青年坚持不懈努力,从失败中总结经验和教训,最后终于取得成功,事业和爱情双丰收,得到领导高度赞扬和肯定。
这样的构思可以不可以,完全可以,但是只能写成一篇表扬信或者一篇通讯稿,如果要拍摄成影视剧,这样的结构和故事,只会贻笑大方。
实际上,很多职业编剧就是这样构思和写作剧本的,他们为什么会这样写?我不想知道原因,你想知道吗?
构思一个电视剧本,按照本人的理解,大体可以分解为十一步,按照这些一步一步构思,完成一个几集的电视剧本大纲和分集故事大约几天时间。
1写出一个故事,越简单越好,越精炼越好。
2设置主要人物。
3写出人物之间的关系。
4设置人物的性格。
5写出人物之间的关系变化
6提炼主题
7重新写这个故事,按照分集写故事。
8写出每集故事的转折点。
9列出各种关系发展变化表。比如人物关系,心理历程,性格等发展变化表。
10回头反复调整上面就九个步骤
11结合各种关系表,结合主题,完成分集剧本。
第一步我构思这样一个故事(故事是我随便写的,因为随意不具备典型性,仅仅当作例子参考)
写故事要遵守一个最简单的原理,就是故事越写越大,不能颠倒。
一个小偷,第一天偷针,第二天偷书,第三天偷钱,第四天调戏妇女,第五天抢劫,第六天强奸,第七天杀人。
这个故事虽然简单,但是很典型,完全具备剧本的要求。完全可以扩展成一个剧本,只要添加几个女人,添加他扶老人过马路,救起落水儿童,就可以写成一个很长的电视剧。
回到青年创业故事
我就随便举一个例子:
小宝是一个刚参加工作的大学生,马上要订婚,在订婚仪式上,被人骂养不起老婆,他决心先创业在结婚,他去盖大楼,大楼马上要竣工,忽然倒塌,他欠下巨债,为了还债,他开始地下赌博,并且抽老千,想依靠赌博还债,越陷越深,一次抽老千失手,被赌场追杀,他逃避追杀时,失手打死一个赌徒,他想私了,对方开价1000万,他被逼无奈,只能奋起反抗,最后彻底打掉整个地下黑赌场。
第一步就完成了,非常简单的一个套路故事,回头检查一遍这是一个创业故事吗?回答是肯定的,他虽然没有积累物质财富,没有创办公司,但是他学会两样技能,杀人和赌博,这是非常高超的专业技能,他依靠自己的专业技能成功消灭一个黑恶势力,这是一个很大很壮举的事业。
第二步设置角色
我一共设置了六个角色
小宝(男),小宝父母,小美(女),大雄(男),小丽(女)。
第三步人物关系
小宝,小宝的父母,小美是小宝的大学同学,也是他一直追求的对象。大雄是小宝的大学同学,也是他同事,也是他最好的朋友。小丽一直在暗恋小宝。
第四步设置人物性格。
小宝聪明好学,上进青年,顺境盲目乐观,自大自狂,逆境孤注一掷,不计后果。
大雄,富家子弟,心狠手辣,放荡淫荡,估计多端。
小美虽然是女主角,女主角只是名字而已,其实还是配角。她的性格我先设置两种可能,根据剧情发展再取舍。
1妓女性格,小宝有钱时笑脸相迎,小宝落魄时一脚踢开。
2淑女慢慢变化为俗女。天真浪漫的少女一步步世俗化。
小丽性格含蓄羞涩,但是意志力顽强,锲而不舍。
第五步
小宝的历程:无知青年,上进,失意,磨练,学会杀人和赌博,成熟青年。
小美心理历程:天真烂漫少女-摇摆青年-势利女人-庸俗女人【 热恋-摇摆-分裂-失望-绝望-分手】
大雄:胡闹青年,恶霸青年,杀人青年,懦夫。
小丽:浪漫少女,坚持浪漫,相信爱情纯洁的熟女。
第六步提炼主题。
我提炼的主题是:
人生悲剧往往是顺境盲目冒进,逆境疯狂冒险造成的。
提炼主题有两个原则,1符合本故事的情节。2和大多数人的体验接近或者相似。
第七步重新写故事。
我暂时把这个电视剧分成五集。
1集
小宝,小美,小丽,大雄是大学同学,毕业后进了同一家大公司,小宝家庭一般,勤奋上进,深受上司喜欢。大雄是富家子弟,他和小宝是最好的兄弟,两人无话不谈,大雄喜欢惹花拈草,上班经常迟到,他们两都在追求小美,小美摇摆不定,直到有一天一个妓女追到公司大骂大雄,小美才决心嫁给小宝,小宝和小美准备订婚,在订婚仪式上,大雄殴打小宝,并且骂小宝没有能力养活老婆,小宝咽不下这口气,决定辞职,自己盖大楼。小丽一直暗恋这小宝,准备出国。
2集
小宝盖大楼遇到资金困难,小美自己去找大雄借钱,大雄提出只要和他睡一觉,并且离开小宝,他就借钱。小美犹豫不决。
小宝借很多钱,把自己的家房产也抵押出去,还借入高利贷,大楼终于开工,房价一直在飙升,小宝和小美整天住进酒店里,花天酒地,长期不回家,父母非常想念他们。
突降暴雨,大楼整体垮塌,小宝陷入危机中。
3集
走投无路的小宝决心冒险,参加地下赌场,父母和小美反对。小宝向小丽借钱,依靠自己超强的计算能力和抽老千,他赢了很多钱,小美劝他收手,小宝相信自己能赢更多钱。
终于有一天,被大雄抓住他在抽老千,赌场开始追杀他。
4集
小宝被追杀,自卫,失手打死一个赌徒。开始东躲西藏,小美受不了惊吓,提出分手。
小宝想通过赔偿私了,大雄开价1000万,小宝彻底绝望,大雄友开始追杀他。
5集
陷入绝境的小宝,在小丽帮助下,开始反击,他将赌场一网打尽,并且控制住大雄,大雄求情,小宝念在多年朋友的情面上,放走大雄,大雄移居美国。
小丽和小宝订婚。
第八步列出每集的转折点
1订婚仪式上大雄辱骂小宝
2大楼倒塌
3小宝抽老千被发现
4小宝杀人
5谈判破裂
1集喜剧 2集悲剧 3集喜剧 4集悲剧 5集大结局也是高潮。
第九步
剧中人和主角的关系发展变化表。
小美 大雄 小丽
1集 朋友---恋人 朋友----开始开裂 暗恋小宝
2集 亲密---动摇 分裂-----反目
3集 动摇---裂痕 成仇
4集 失望---绝望 追杀 挑明
5集 分手 相互追杀 恋人
线索 : 主线-------小宝创业的兴衰。
副线1----小宝和小美的恋情。
副线2----小宝和大雄从朋友到敌人。
副线3----小宝和小丽的恋情。
第十步,反复修正上面的结构和故事。
第十一步写出大纲和分集剧本。
由于有人物关系的限制,情感的限制,以及主题制约,分集故事其实并没很大的回旋余地,按照套路故事填充即可。到这里一个闹剧故事完成一大半。
文学艺术和影视艺术都是讲故事,解剖人性,揭示人性中的善恶,揭示社会运动和人物命运的艺术。
本剧只是爱情事业交织的故事,人物的命运和自己行为以及他的亲人朋友形成互动关系,社会作为大背景或者大平台,没有参与人物命运的互动,所以本剧只是一个闹剧。还不能作为真正艺术作品。
第二篇:厦大无机化学专业考研人,手把手教你复习范文
厦大无机化学专业考研人,手把手教你复习
首先做个自我介绍,本人于2012年报考厦大无机化学专业研究生,初试成绩还算不错,总分372,无机化学135,单科分数在当年也算前两名了。然后顺利的通过复试,如今在厦大化学系的某个角落默默奋斗着。
对于一个考研人来说,了解自己所考学科排名很重要,研究生不同于本科生,本科生可能更注重学校的综合实力,但是研究生应该更需看重报考专业的排名。厦大的化学实力确实不俗,个人认为比北大差不了多少,至少在师资力量和硬件设施方面不会逊色多少,有些地方还有过之。厦大的化学考研试题,侧重于学生所学知识的深度,一般都是择两门专业课选考,比如考无机化学专业,无机和物理化学必考;考有机化学专业,有机和物化必考;考物理化学专业,物理化学是必考的,但另一门专业课就可以根据考生的自我评估选择考无机化学或是有机化学。我很喜欢厦大这种考试方式,因为它很适合我。我本科的化学基础,个人感觉只有物理化学相对来说还学的不错,大学四年,只有两门课我是认真听讲,认真完成老师所布置的任务,其中之一就是物理化学。厦大的物理化学确实有点难度,注重考生对知识的掌握深度和实际应用。但我认为无论其多么难,那是相对于所有人的,只要自己能够学懂,考试能得100多分就行了。厦大的无机化学考研难度算一般,不是特别难,除却2013年,听说难的让人抓狂。个人认为无机化学就两本书,只要肯花点时间,反复的看书,问题也不会有多大。
现在说说我的考研复习时间安排吧,我是从2011年4月份开始复习无机化学上册,整个四月份都只看无机化学上册,只看书,每天花半天时间(3小时)去图书馆。我看书比较注重效率,也感觉自己那段时间效率比较高,所以就抓紧时间看(考研复习都有疲劳期,所以趁状态好的时候多复习点)。每次看书的时候只带课本和笔,本人不习惯用笔记本,看书期间遇到的问题或是重点我喜欢直接标注在书本上,我那本无机化学课本在最后反正是找不到一页没有注解的空白地方。我还有个习惯就是喜欢将书本上的重要公式或是非常重要的定义写在那一页的顶端或是下端,这样有助于复习时加深印象,翻到那一页就知道主要讲了什么内容。整个四月份我将无机化学上册看了一遍,当然有些难以理解的地方就多花了时间。看教材的同时我也获得了一本相当不错的课外辅导书,即思睿厦大考研网出的《厦门大学617无机化学考研复习精编》,此书包含章节知识点归纳,考题考点解析、知识框架图及历年真题及答案解析等内容,用起来很方便。我看书也是主要是以章节为单位,争取看一章能将那一章的知识有个了解,争取看懂。
看完这本书就给自己放了一个五一长假,然后就开始复习物理化学了,物理化学也注重看书,最好是复习厦大孙世刚那两本书,很全面,跟考试结合很紧密。物理化学是一项艰苦的工程,不仅难懂,还很难记住,感觉就是看不懂,看了后面就忘了前面,做题几乎没把握。不过这时不要灰心,始终要坚信难是对于所有人的,只要自己努力了,结果肯定不会差。物理化学需要一章节一章节的复习,然后做课后习题,这样有助于理解,重复看书,重复做题,吃透每章节的内容,只有这样才会在看后续章节时不会不知所云。复习物理化学花的时间就多了,两本物理化学书我是从5月份看到了八月底,当然这期间也有一些耽误,比如复习期末考试,暑假休息半个月,总的算来花了三个月把书本拉通看了一遍。最重要的是在这期间无机化学不能丢下,虽然不像四月份那样每天看,但是需要时常翻翻书,看一看比较难理解的章节,如原子结构和元素周期律,化学键理论和配位化学那几章,顺带做做题。这样到九
月开学时几乎就把无机化学上册搞定了,物理化学也有了个大概的了解。对于这期间花在专业课上的时间应该每天不少于三小时吧,而且是连续的三小时,这样有助于系统复习。
九月开学后就要安排全程复习了,无论是公共课还是专业课,具体时间安排因人而异,自己感觉难的科目可以多安排点时间,复习顺利的科目少花点时间,尽量是各科考试平衡,偏科很让人受伤啊。我当时的复习就是晚上的时间都留给专业课,物化和无机,白天安排政治和英语。晚上的时间相对来说较多,差不多可以连续学习四个小时。此段时间的专业课就主要集中在物理化学了,看书加习题练习,两本教材上的习题必须全部解决,同时可以做点其他资料上的题,毕竟物理化学注重解题思路及技巧。无机化学上册在前几个月差不多复习的可以放手了,所以从九月开始就需要复习无机元素化学了。无机元素化学的复习虽然内容多,但是只要把无机化学上册理解透了,搞定它也不是问题。无机化学的章节都是按照元素周期表族来划分,各章联系不是很大,有些章节会熟悉点,有些章节会陌生点,所以复习此部分需要按章复习,争取把每章节知识记住。此外,在此期间我还开始琢磨《厦门大学617无机化学考研复习精编》这本书里的一些典型题目,这样有助于加深记忆。
十月国庆可以休息几天,貌似我当年休息了七天,当时确实感觉累了,所以给自己找了很多理由轻松了一段时间。国庆假结束后,我给自己制定了一个复习计划——最后三个月考研复习时间安排,主要是根据自己前段时间复习情况安排后面时间的分配。上午政治(3h),下午英语(3h),晚上专业课(4h),专业课就是看书加做真题,此时做真题很有效果,可以指导自己再看书,如此三个月下来专业课就差不多符合考试要求了。到了考前一个星期,可以自己试着罗列一下专业课各章节重点,让各知识点在自己脑海中形成一个框架图,这样有助于考试做题时提取信息。
对于复试,本人强烈感觉厦大的无机化学复试很简单,只要你考研成绩在前面,基本不可能淘汰你,所以我的建议就是尽量使自己的初试成绩高。其实很多年份厦大的无机化学都需要相应专业调剂,所以只要你分数能上线,复试基本没有问题。
此次只是给大家一个简略的复习建议,在后续各个阶段我会给大家更加详细的复习建议,如果觉得有所帮助,请留心此网站。
以上只是本人拙见,望各位同仁选择看之,也希望能够对友友们有所帮助!
第三篇:play手把手教你创建一个博客项目-02.迭代编写数据模型代码
02.迭代编写数据模型代码
下面,我们将开始为我们的博客引擎写一个数据模型。
JPA介绍
在play应用程序(事实上也包括所有设计良好的应用程序)里,模型层是最为核心的地方。play是一个域驱动类型的数据表现框架,既然我们想要创建一个博客引擎,那么模型层所需要的类(比如User/Post和Comment)就应当首先考虑。
因为大多数模型对象都需要在应用程序重新启动后能够继续保存数据,因此,我们就必须把它们保存在一个可持久化的存储器里。通常,我们会选择一个关系数据库来保存数据。但是,由于java是面向对象的语言,因此,我们将使用对象关系映射来减少匹配阻抗。
Java Persistence API(JPA)是一个Java规范,它定义了一个标准的对象关系映射API集。作为JPA规范的实现,play使用众所周知的Hibernate框架来实现JPA。使用基于Hibernate API的JPA的一个优势就是所有映射都是在java对象里进行声明的。
如果在此之前你曾经用过Hibernate或JPA,那么在play里使用JPA你会感到非常惊讶,因为在Play里使用Hibernate或JPA实在是太简单了,它不需要进行任何配置即可正常工作~!
如果你不知道什么是JPA,哈哈,请在继续下面的课程之前先补补课some of these simple presentations。
创建第一个模型类User 接下来我们将开始为博客引擎编写代码,首先是创建User类,接下来让我们创建/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类成为一个可被管理的JPA实体,其继承的Model超类自动为其提供了一系列非常有用的JPA帮助方法(后面我们会作介绍)。所有User类的fields(以下均称为字段,不再提示)都会自动持久化到数据库里。默认情况下,数据库表的名称为 ‘User’。在某些情况下,默认的表名可能会与数据库的保留关键字冲突,这时就需要对数据库表名进行定制,比如针对User类,可以注释为@Table(name=“blog_user”)。
继承play.db.jpa.Model类并不是必须的,你可以继续使用原始的JPA。但继承Model类是一个好的选择,通过继承Model类,你可以通过它提供的帮助方法很方便的对实体类进行操作。
如果之前你用过JPA,那么你应该知道每个JPA实体都必须提供一个@Id属性。在这里,Model超类提供了一个自动生成数字型ID的功能,在很多情况下已经足够了。
注意,请不要把Model自动提供的ID当作功能性标识符使用,只能把它当成是技术性标识符使用。通常情况下,自动生成的数字ID作为一个技术标识符是个较好的主意。
如果你是一个经验丰富的java开发者,那么你就会知道在模型对象里的字段应该是private的,访问这些字段的方式是为这些字段创建getter/setter方法。但是,在play里,字段是用public修饰的,其目的是为了编写代码的量,请别担心,事实上play会小心照顾好这些字段,自动为其生成getter/setter。刷新一下应用程序主页,看看有些什么变化没。事实上,除非代码有错误,你应该看不到任何变化。play已经自动编译和加载了User类,但是这并没有为应用程序添加任何新的特征。
编写第一个测试程序 在play里,测试新创建的User类的好方法就是编写一个JUnit单元测试。这个测试将允许你对User进行测试。
要想进行测试,你得把play切换到test模式下。首先停止当前正在运行的应用程序,在命令行输入如下命令,以切换到测试模式: ~$ play test 除了加载了一个test runner模块,以允许你在浏览器直接运行测试组件外,play test命令和play run很相似。
当play运行与测试模式时,Play将自动切换到测试框架ID,并加载相应的application.conf配置文件,参考framework ID documentation了解更多信息。在浏览器打开http://localhost:9000/@tests URL地址,就可以看到test runner了。试着选择所有默认的测试并运行它们,所有的结果都应该是绿色的„其实这些测试并没有进行任何实质性的测试。为了测试User模型(适用于所有的模型类),我们打算使用JUnit测试。正如你所看到的一样,play已经提供了一个默认的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);} } 删除默认的无用的测试(aVeryImportantThingToTest),并创建一个新的测试,在其中将试着创建一个新的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超类提供了两个非常有用的方法save()and find()。在play管理手册的JPA support节,你可了解更多Model类的方法。在test runner里选择BasicTests.java,单击start进行测试,可以看到结果全是绿色。
接下来,我们需要在User里创建一个验证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里运行所有的测试。
创建Post类
Post类用展现发表的博客:
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这个字段是一个超大文本数据库类型,用是存储发表的内容。我们同时用@ManyToOne来声明Post与User是多对一的关系。意思是每篇博客都是单个用户写的,每个用户可是发表多篇博客。现在的PostgreSQL版本还不能存储用@Lob注释的String类型字段,解决方法是使用@Type(type = “org.hibernate.type.TextType”)进行注释。接下来,我们将编写新的测试代码用于测试Post类。但是在写更多测试代码之前,我们需要在JUnit测试类里做一些工作,比如在当前的测试代码里,数据库内容并不会删除,因此,我们每运行一次,play就会增加一个新创建的对象,这些对象会越来越多,当进行更高级的测试时,这或许会成为问题。
因此,让我们在运行每个测试之前写一个JUnit setup()方法来删除数据库: public class BasicTest extends UnitTest {
@Before public void setup(){ Fixtures.deleteDatabase();}
„ } @Before是JUnit测试工具最核心的概念。
正如你所看到的,Fixtures类帮助我们在测试期间管理数据库。接下来,我们将编写下一个测试:
@Test public void createPost(){ //创建一个新的user,并保存
User bob = new User(“bob@gmail.com”, “secret”, “Bob”).save();
// 创建一个新post new Post(bob, “My first post”, “Hello world”).save();
// 测试上一步是否创建了新的post assertEquals(1, Post.count());
// 获取所有“Bob”发表的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);} 千万不要忘记了导入java.util.List,否则会出现编译错误。
编写Comment类
最后一件事就是创建Comment类,为发表的博客提供评论的能力。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之间进行导航并不容易:我们需要使用查询来找到一个博文的所有评论。在这里我们还有更好的方法,方法就是在Post类里定义它与Comment之间的一多对关系。在Post类里添加一个comments域:
...@OneToMany(mappedBy=“post”, cascade=CascadeType.ALL)public List
public Post(User author, String title, String content){ this.comments = new ArrayList
定义好上述关系后,我们需要在Post类里添加一个帮助方法用于添加评论: 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来编写更复杂的测试 在开发编写更复杂的测试之前,我们通常需要提前准备一系列的测试数据,Fixtures类允许我们在一个YAML文件里描述需要准备数据的模型,它允许我们在进行任何测试之前加载这个yaml文件。
编辑/yabe/test/data.yml文件,对User模型的数据进行描述:
User(bob): email: bob@gmail.com password: secret fullname: Bob...OK,这个data.yml文件有点大,我们已经提前准备好了,还是下载吧download it here。
接下来,我们将在测试代码里加载这个文件里描述的数据,并对它进行测试: @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());} 更多关于YAML的内容,请阅读YAML manual page。