自从GAE支持java以来,一些其他语言就可以通过java来间接实现了。其中PHP语言就是其中的重中之重,通过quercus,我们可以在GAE上运行100%的php程序。
PHP是网页语言中应用比较广泛的,比如著名的wordpress,而且他们是免费的且随时在更新。现在很多人都在呼吁要GAE支持php。
不幸的是,GAE不支持MYsql,以及其他关系数据库,我们限制于Google Datastore,所以现在大多数PHP程序都不能运行在GAE上面,因为他们大多要基于LAMP框架(注:Liunx+Apache+Mysql+PHP)
但是修改现有的PHP程序让他们能够在GAE上运行有多难呢?我通过让WordPress在GAE上深入研究了这个有趣的问题。目前,wordpress已经可以运行在Quercus上面了,我所需要做的就是用GAE的JPA来转换Mysql查询。最后,花了大概一个星期,终于可以看到现在这个在GAE上运行的Demo了。

转换wordpress的数据库查询
我要做的第一步是转移数据库到JPA。要做到这一点,我为每一个数据表建立了一个JPA类(class),数据表到JPA的关系是非常简单的。JPA的数据类型及名称完全是和Mysql相同的。每个字段也是这样。例如,wo_user表就要转换成下面的JPA类:
package com.caucho.gae.wordpress271;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
/*
CREATE TABLE `wp_users` (
`ID` bigint(20) unsigned NOT NULL auto_increment,
`user_login` varchar(60) NOT NULL default ”,
`user_pass` varchar(64) NOT NULL default ”,
`user_nicename` varchar(50) NOT NULL default ”,
`user_email` varchar(100) NOT NULL default ”,
`user_url` varchar(100) NOT NULL default ”,
`user_registered` datetime NOT NULL default ‘0000-00-00 00:00:00′,
`user_activation_key` varchar(60) NOT NULL default ”,
`user_status` int(11) NOT NULL default ‘0′,
`display_name` varchar(250) NOT NULL default ”,
PRIMARY KEY (`ID`),
KEY `user_login_key` (`user_login`),
KEY `user_nicename` (`user_nicename`)
);
*/
@Entity
public class User
{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long _ID;
private String _userLogin;
private String _userPass;
private String _userNicename;
private String _userEmail;
private String _userUrl;
private String _userRegistered;
private String _userActivationKey;
private Long _userStatus;
private String _displayName;
}
Varchar和int类型分别匹配的是JAva的string和long类型。我可以用JAVA的日期和时间数据类型,但是这还没有结束,因为在wordpress的所有日期/时间不是这样的(翻译水平有限,这句话没明白,但该是对于日期时间数据类型的转换不是直接可以完成的,详见原文“I could have used Java Date for datetime but didn’t in the end because WordPress does all the date/time processing on its end on strings anyway”),简单起见,我省略了Java的Getters和setters。
然后我创建了一个script来创建JPA重的每一个表。
下一步,也是最后一步是转换MYsql的查询为JPA查询。这是最好时间的一步了,因为wordpress没有把数据库操作的代码封装在一个文件(意译哈,不要骂我哦,呵呵),换句话说就是程序直接是用的MYsql语言查询(所有代码都有select之类的语句,没有写一个数据库操作的类,不知道是不是这样哈,错了请指正,谢谢)。我的工作是容易一些的是JPA的查询使用几乎相同的语法SQL查询。看看下面检索的评论一个特定帖子的代码:
function get_comments($post_id)
{
//SELECT * FROM $wpdb->comments WHERE comment_post_ID = %d AND comment_approved = ‘1′ ORDER BY comment_date
$query = $this->pm->createQuery(”SELECT FROM ” . GAE_COMMENT_CLASS . ‘ WHERE _commentPostID = :id AND _commentApproved = “1″ ORDER BY _commentDate’);
$query->setParameter(”id”, $post_id);
$results = $query->getResultList();
$array = array();
foreach ($results as $comment) {
$obj = new stdClass();
$obj->comment_ID = $comment->getCommentID();
$obj->comment_post_ID = $comment->getCommentPostID();
$obj->comment_author = $comment->getCommentAuthor();
$obj->comment_author_email = $comment->getCommentAuthorEmail();
$obj->comment_author_url = $comment->getCommentAuthorUrl();
$obj->comment_author_IP = $comment->getCommentAuthorIP();
$obj->comment_date = $comment->getCommentDate();
$obj->comment_date_gmt = $comment->getCommentDateGmt();
$obj->comment_content = $comment->getCommentContent();
$obj->comment_karma = $comment->getCommentKarma();
$obj->comment_approved = $comment->getCommentApproved();
$obj->comment_agent = $comment->getCommentAgent();
$obj->comment_type = $comment->getCommentType();
$obj->comment_parent = $comment->getCommentParent();
$obj->user_id = $comment->getUserId();
$array[] = $obj;
}
return $array;
}
正如你所看到的,这是一个一对一转换为特定的查询。最关键的部分是确保返回wordpress期望的正确返回类型。在这个情况下我需要返回一个数组对象。
wordpress大量使用了更复杂的查询,比如joins,这些GAE现在都还没有支持(目前为止)但是对于我来说,很容易通过嵌套或者多次JPA查询仿制一个类似的功能。Joins are evil according to Google so I do not want to bore you with the details.(不明白这一句,但是好象是说这个功能是被google限制的,所以最好不要在Google上使用~?)
大概重写了大概50个查询,现在的Wordpress运行令人满意,我可以创建修改评论和文章(虽然我不能保证出现意外)。现在这个demo运行在GAE上面:http://wordpress-on-quercus.appspot.com/wordpress-2.7.1/以及http://java.fly7.cn。源代码:here!!
总之这是一个有趣的学习GAE的经验。我不敢说这是非常适合Google数据库JPA的,但作为一个演示目的,展示无缝集成PHP和JAVA。
未来,我们可以让现在的PHP程序完美的运行在GAE上面,我们已经有了文件为基础的关系数据库用于我们的缓存和记录。我们可以用JNDI数据库代替MYSQL数据库查询。虽然GAE不允许文件写入,但我们可以在数据库中存放文件,这样,我们就可以在安装有Quercus的GAE中运行任何基于LAMP的应用程序了。那一切将非常cool~~
翻译原文:http://blog.caucho.com/?p=196
这里个上几个链接:
http://blog.herbert.groot.jebbink.nl/2009/05/rom-relational-object-mapping.html
http://www.caucho.com/resin/doc/quercus.xtp#datasource
这个的安装方法我就不多说了,大家先安装JavawithPhp这个东西在你的GAE账户上,然后把上面说的那个war包替换到到javawithphp的那个war文件夹,顺便说一下作者给的那个war目录下需要改两个地方insert.php打开,大家可以适当改一下,然后就是warWEB-INFappengine-web.xml这个文件把你的Gae名字替换掉
http://appengine.google.com/ns/1.0″>
shenmao1989
3
转载请注明来源:www.fly7.cn