Google App Engine的Java支持已于今年4月发布,对于Java开发者而言这是极大的好处:App Engine具有伸缩性强,管理界面强大等特点,而且对于小型应用来说是完全免费的。本文演示了如何在App Engine上编写实现文档的存储和搜索功能。

【51CTO技能译文】为什么Java程序员要考虑运用Google的Java App Engine呢,首要有以下几点原因:只需你的页面访问量每月不超越500万,Google就免费向你供给空间。假如访问量超越了这一限额,你也能够随时经过晋级为付费用户撤销这一约束。

◆Google的App Engine 渠道(包括Java和Python版别)让你不必做什么额定作业就有很强的伸缩性

◆App Engine 供给了一个功用很强的办理界面,你能够经过它检查过错日志,阅读你所保存的数据,剖析程序的功用(例如恳求呼应时刻等),还能够实时监控你所布置的运用。即便是和Amazon的EC2这样优异的Web操控台比起来,Google的Web运用程序办理功用也毫不逊色。

◆只需你乐意,你也能够经过App Engine SDK 把App Engine 上的运用搬迁到你自己的服务器上,当然,这样就会丢失一些伸缩性(scalability)了。

◆由于在App Engine上开发程序时运用的都是规范的 API,所以当你要把运用移植布置到其它渠道上时,就只需求对程序作十分小的改动了。不过反过来做就不是这么简略了。比如说假如你的程序调用很多的J2EE API函数,或者说依赖于联系型数据库等等,那么把这些程序移植到App Engine上就十分费事。

◆那些用J2EE写Web程序的开发者们或许一开端会觉得App Engine 的种种约束让人觉得很不适应,可是这样做的优点也是很明显的,服务器的花费将大大削减。假如你想要更大的自由度和伸缩性,那么你还能够考虑Amazon的EC2服务(我是既用App Engine,也用EC2)。

本文接下来将介绍Java开发者怎么运用Google运用程序引擎。它演示了怎么在App Engine上编写完结文档的存储和查找功用。本文还评论了Java App Engine文档里的一些有用技能和运用程序示例。

你需求作的预备

◆Eclipse或IntelliJ IDEA开发环境

◆一个App Engine 帐号,假如还没有的话,在这里请求(没有App Engine 帐号的开发者能够经过在你自己电脑上装置App Engine SDK体会它)

◆下载App Engine SDK 供本地开发时运用

◆装置Eclipse的或IntelliJ 的Java App Engine 插件。

示例工程里的文件

在Google Java App Engine上完成文档存储和查找(Google APP Engine 使用的数据库是( ))  文档存储 文档搜索 第1张

图1 示例工程里的文件

许多Java开发人员运用 Lucene (或根据Lucene的结构)来完结查找功用。可是,在App Engine环境下运用Lucene的内存索引形式没有什么优点。咱们的这个示例工程另辟蹊径在App Engine渠道上完结了查找功用。

App Engine的耐久性数据存储功率是十分高的,但它不运用联系模型,也没有Hibernate这样的目标联系映射(Object Relational MApping ,ORM)结构。不过,App Engine仍是供给了对一些规范的耐久性API,如JDO,JPA,以及JCache。咱们的示例程序运用JDO完结数据耐久(data persistence)。

这个程序布置在这里。每个运用这个演示程序的人都能够把数据清空从头再来,所以你这次增加的信息下次能够就会看不到了。

作者注:这个程序演示了JDO的运用以及怎么用JDO完结查找,为了突出重点,程序没有增加对多用户这些功用的支撑。

图1显现了这个Java App Engine项目所包括的文件。后续的章节将具体介绍packagecom.kbsportal.model 里的模型类和 com.kbsportal.persistence 里的耐久类PMF。由于packagecom.kbsportal.util这个包里的各品种和App Engine里的不同较大,咱们就不在这里作过多评论了。假如要具体了解这些,你能够看看咱们的源代码以及JSP文件(在 war/WEB-INF目录里)。咱们也会对JSP文件里某些Java代码片段加以解说。

运用JDO完结数据耐久化

JDO是一个用于耐久化Java目标的陈旧API。起先,为了完结耐久化存储,JDO要求开发者有必要编写和保护XML文件,以供给Java类的数据映射特点。Google运用 DataNucleus 东西主动完结这一进程。你只需求在你的Java模型类里边加以注解,DataNucleus东西就会主动为你保护正确的数据映射联系。假如运用了Eclipse的或IntelliJ IDEA的App Engine插件,当你编写耐久类时,DataNucleus东西就会主动在后台效果。

正告:JDO和App Engine放到一同有时候会发生兼容性问题。假如你是在本地用Eclipse开发,只需删去目录 WEBAPP /war/WEB-INF/ appEngine-generated/ local_db.bin里的文件。 假如你的Web运用现已布置上去了并且要修正模型类,那么你只需在App Engine操控台中把已有的索引文件删去即可

以下各节将介绍两个耐久类的完结并评论这些根据JDO完结的代码。

#p#

文档模型类

Eclipse或IntelliJ IDEA的App Engine插件与JDO以及DataNucleus东西的组合十分好用。运用这个组合规划和完结你自己的模型文件,并增加有必要的注解,这些对你来说应该不成问题。不过你仍是要留意DataNucleus东西在后台运行时所提示的过错信息。

在开端规划完结自己的耐久类前,无妨先看看下面这个模型类,它是用来反映一个文件模型的。这个类在界说时会引进所需的JDO 类(实际上你的编辑器会主动帮你填写这些包括句子)。榜首行注释声明晰这个类是耐久的。这个类被标识为APPLICATION,这样你就能够为那些创立后就将耐久存在的目标分配ID。假如你要为数据存储目标分配ID,那么你能够把类型指定为DATASTORE。

  1. packagecom.kbsportal.model;
  2. importjavax.jdo.annotations.IdentityType;
  3. importjavax.jdo.annotations.PersistenceCapable;
  4. importjavax.jdo.annotations.Persistent;
  5. importjavax.jdo.annotations.PrimaryKey;
  6. @PersistenceCapable(identityType=IdentityType.APPLICATION)
  7. publicclassDocument{

这段代码声明晰把成员变量uri作为在数据存储里查找Document目标时的主键。JDO的索引主键也被设为URI。本文的示例文本存储在IndexToken这个类里边运用了这个主键(IndexToken类将在下一节进一步评论)。这段代码还特别阐明晰title, content以及numWords这几个成员变量要耐久保存。

  1. @PrimaryKeyprivateStringuri;
  2. @PersistentprivateStringtitle;
  3. @PersistentprivateStringcontent;
  4. @PersistentprivateintnumWords;

类声明里的其它部分则不包括JDO具体阐明。

  1. publicDocument(Stringuri,Stringtitle,Stringcontent){
  2. super();
  3. setContent(content);
  4. this.title=title;
  5. this.key=uri;
  6. }
  7. publicStringgetUri(){returnkey;}
  8. publicStringgetTitle(){returntitle;}
  9. publicvoidsetTitle(Stringtitle){this.title=title;}
  10. publicStringgetContent(){returncontent;}
  11. publicvoidsetContent(Stringcontent){
  12. this.content=content;
  13. this.numWords=content.split("[\\\\.\\,\\:\\;!]").length;
  14. System.out.println("**numWords="+numWords+"content:"+content);
  15. }
  16. publicintgetNumWords(){returnnumWords;}
  17. }

留意在内容字符串上所作的长度约束;GoogleApp Engine的数据存储约束字符串不得超越500个字符。(运用com.google.appengine.api.datastore.Textfors能够取得没有长度约束的字串。 )

#p#

IndexToken模型类

该IndexToken类根据JDO完结了查找功用。这个类有两种作业形式:整词索引、整词及词前缀索引。在源文件的头部你能够经过一个常量指定它的作业形式:

  1. packagecom.kbsportal.model;
  2. importjava.util.ArrayList;
  3. importjava.util.Collections;
  4. importjava.util.Comparator;
  5. importjava.util.HashMap;
  6. importjava.util.List;
  7. importjavax.jdo.PersistenceManager;
  8. importjavax.jdo.annotations.IdGeneratorStrategy;
  9. importjavax.jdo.annotations.IdentityType;
  10. importjavax.jdo.annotations.Index;
  11. importjavax.jdo.annotations.PersistenceCapable;
  12. importjavax.jdo.annotations.Persistent;
  13. importjavax.jdo.annotations.PrimaryKey;
  14. importcom.kbsportal.persistence.PMF;
  15. importcom.kbsportal.util.NoiseWords;
  16. importcom.kbsportal.util.Pair;
  17. importcom.kbsportal.util.SearchResult;
  18. @PersistenceCapable(identityType=IdentityType.APPLICATION)
  19. publicclassIndexToken{
  20. staticbooleanMATCH_PARTIAL_WORDS=true;//packagevisibility

把这个标志设置为true,就会敞开单词的前缀匹配功用,类似于查找关键字主动校对功用。

现在咱们该看看怎么树立索引片段(或许还包括单词前缀的索引片段)以及怎么确认每个索引片段的匹配度。以下是具体的代码(来自IndexToken.java包里的源文件,它是作为一个独自的局部类完结的,以方便在其他项目重复运用) :

  1. classStringPrefix{
  2. publicListgetPrefixes(Stringstr){
  3. Listret=newArrayList();
  4. String[]toks=str.toLowerCase().split("[\\\\.\\,\\:\\;\\(\\)\\-\\[\\]!]");
  5. for(Strings:toks){
  6. if(!(NoiseWords.checkFor(s))){
  7. if(!IndexToken.MATCH_PARTIAL_WORDS){//exactwordsonly
  8. ret.add(newPair(s,1f));
  9. }else{//or,alsomatchwordprefixes
  10. intlen=s.length();
  11. if(len>2){
  12. ret.add(newPair(s,1f));
  13. if(len>3){
  14. intstart_index=1+(len/2);
  15. for(inti=start_index;i0&&!Character.isDigit(p.str.charAt(0))){
  16. pm.makePersistent(newIndexToken(document_id,p.str,p.f));
  17. }
  18. }
  19. }

这段代码用到了StringPrefix 类。别的还运用了东西类PMF(等下咱们就会更具体地去了解它)来取得一个App Engine耐久办理器(persistence manager)的实例。这类似于一个JDBC 衔接目标。

在IndexToken里还有一个值得一提的当地便是search这个静态办法.

  1. publicstaticListsearch(Stringquery){
  2. Listret=newArrayList();
  3. PersistenceManagerpm=PMF.get().getPersistenceManager();
  4. String[]tokens=query.toLowerCase().split("");
  5. HashMapmatches=newHashMap();

此办法回来SearchResult类的实例。查询字符串被转换为小写并被切割。关于每一个片段,你都将再次用StringPrefix核算前缀(以及原始单词) ,核算结果将用于查找包括这些关键词的文件:

  1. for(Stringtoken:tokens){
  2. Listlp=newStringPrefix().getPrefixes(token);
  3. for
转载请说明出处
知优网 » 在Google Java App Engine上完成文档存储和查找(Google APP Engine 使用的数据库是( ))

发表评论

您需要后才能发表评论