Liferay的插件体系是:模型-视图-控制器的portlet MVC框架。
MVC是一个伟大的用于Web应用程序的设计模式,在实际应用中还应处理持久化,它可以用于检索、处理或显示。为此你需要添加更多的层:一个持久层和服务层。
持久层负责保存和检索模型数据。服务层就像你的应用程序和持久层之间的缓冲区:在将来,它会给你自由的自由,即在不修改任何内容的情况下,使用不同的实现方式来交换你的持久层。这种松耦合是良好的应用程序设计,并在Liferay框架中支持。它通过Service Builder(服务生成器)生成。
Service Builder的特性:
- 自动生成模型,持久性和服务层
- 自动生成本地和远程服务
- 自动生成Hibernate和Spring的配置
- 根据帐户的权限生成查找方法的实体和查找方法
- 内置实体缓存(entity caching)支持
- 自定义的SQL查询和动态查询的支持
- 节省开发时间
服务生成器是通过完全消除编写和维护数据库访问代码来节省开发时间的。你只需要生成一个 service.xml 文件,再运行 Service Builder ,这将生成一个新的service .jar文件,新文件包括模型层、持久层、服务层和相关基础设施。通过服务生成器生成的远程服务包括SOAP或JSON访问。
另一种节省开发时间的方式是通过Spring和Hibernate的配置你的项目。业务生成器使用Spring的依赖注入使服务实现类可在运行时使用Spring AOP的数据库事务管理。使用Hibernate对象关系映射的持久化框架。作为一个方便的开发人员,服务的建设者隐藏了使用这些技术的复杂性。开发人员可以利用依赖注入(DI)、面向方面的编程(AOP),和对象关系映射(ORM)
生成方法。点击当前Liferay项目》 New → Liferay Service Builder
服务生成器的界面
配置文件的格式:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE service-builder PUBLIC "-//Liferay//DTD Service Builder 6.2.0//EN" "http://www.liferay.com/dtd/liferay-service-builder_6_2_0.dtd"> <service-builder package-path="com.liferay.docs.guestbook"> <author>wangxin</author> <namespace>GB</namespace> <entity name="Guestbook" local-service="true"> <!-- PK fields --> <column name="guestbookId" type="long" primary="true"></column> <!-- Group instance --> <column name="groupId" type="long"></column> <!-- Audit fields --> <column name="companyId" type="long"></column> <column name="userId" type="long"></column> <column name="userName" type="String"></column> <column name="createDate" type="Date"></column> <column name="modifiedDate" type="Date"></column> <column name="name" type="String"></column> </entity> <entity name="Entry"> <!-- PK fields --> <column name="entryId" type="long" primary="true"></column> <!-- Group instance --> <column name="groupId" type="long"></column> <!-- Audit fields --> <column name="companyId" type="long"></column> <column name="userId" type="long"></column> <column name="userName" type="String"></column> <column name="createDate" type="Date"></column> <column name="modifiedDate" type="Date"></column> <column name="name" type="String"></column> <column name="email" type="String"></column> <column name="message" type="String"></column> <column filter-primary="false" name="guestbookId" primary="false" type="long"></column> </entity> <exceptions> <exception>GuestbookName</exception> <exception>EntryName</exception> <exception>EntryMessage</exception> <exception>EntryEmail</exception> </exceptions> </service-builder>
当你写一个系统应用,例如,如果你为两个不同的站点添加一个Wiki,每个wiki的数据是根据每个站点而不同。换句话说,一个网站没有访问另一个网站的数据,但应用程序都相同。这是数据范围的概念。
在Liferay Portal的数据范围有一个层次,在下图描述。
在这里,你可以看到2个门户实例。每一个都是完全独立的门户,不同的用户、网站。在左边的门户实例中描述了2个用户:一个用户是一个独立站点的成员,而另一个用户是一个组织的成员,它本身有一个站点。
默认字段 Company ID,Group ID,User ID 就是提供了数据范围的支持。
然后创建Finders
创建后的代码:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE service-builder PUBLIC "-//Liferay//DTD Service Builder 6.2.0//EN" "http://www.liferay.com/dtd/liferay-service-builder_6_2_0.dtd"> <service-builder package-path="com.liferay.docs.guestbook"> <author>wangxin</author> <namespace>GB</namespace> <entity name="Guestbook" local-service="true"> <!-- PK fields --> <column name="guestbookId" type="long" primary="true"></column> <!-- Group instance --> <column name="groupId" type="long"></column> <!-- Audit fields --> <column name="companyId" type="long"></column> <column name="userId" type="long"></column> <column name="userName" type="String"></column> <column name="createDate" type="Date"></column> <column name="modifiedDate" type="Date"></column> <column name="name" type="String"></column> <finder name="GroupId" return-type="Collection"> <finder-column name="groupId"></finder-column> </finder> </entity> <entity name="Entry"> <!-- PK fields --> <column name="entryId" type="long" primary="true"></column> <!-- Group instance --> <column name="groupId" type="long"></column> <!-- Audit fields --> <column name="companyId" type="long"></column> <column name="userId" type="long"></column> <column name="userName" type="String"></column> <column name="createDate" type="Date"></column> <column name="modifiedDate" type="Date"></column> <column name="name" type="String"></column> <column name="email" type="String"></column> <column name="message" type="String"></column> <column filter-primary="false" name="guestbookId" primary="false" type="long"></column> <finder name="G_G" return-type="Collection"> <finder-column name="groupId"></finder-column> <finder-column name="guestbookId"></finder-column> </finder> </entity> <exceptions> <exception>GuestbookName</exception> <exception>EntryName</exception> <exception>EntryMessage</exception> <exception>EntryEmail</exception> </exceptions> </service-builder>
并且编译: