Liferay開發實戰(2):Service Builder生成持久化層,及開發服務層


本文Liferay適用版本:v6.2.ce-ga6版

 

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的事務管理。

 

生成方法。點擊當前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>
View Code

 

並且編譯:

 

Liferay的代碼生成器生成了持久化層代碼,但控制器、服務層、視圖層的具體實現需要開發人員自己做,這樣保證了極大的靈活性。

ServiceContext 是Liferay提供上下文訪問的核心類,真的是非常強大:

 

視圖層的一些代碼,AUI是YUI的擴展。

<%@include file = "/html/init.jsp" %>

<portlet:renderURL var="viewURL">
    <portlet:param name="mvcPath" value="/html/guestbook/view.jsp"></portlet:param>
</portlet:renderURL>

<portlet:actionURL name="addGuestbook" var="addGuestbookURL"></portlet:actionURL>

<aui:form action="<%= addGuestbookURL %>" name="<portlet:namespace />fm">

        <aui:fieldset>

            <aui:input name="name" />

        </aui:fieldset>

        <aui:button-row>

            <aui:button type="submit"></aui:button>
            <aui:button type="cancel" onClick="<%= viewURL %>"></aui:button>

        </aui:button-row>
</aui:form>

 

前端界面

 

 

控制器代碼

package com.liferay.docs.guestbook.portlet;

import com.liferay.docs.guestbook.model.Entry;
import com.liferay.docs.guestbook.model.Guestbook;
import com.liferay.docs.guestbook.service.EntryLocalServiceUtil;
import com.liferay.docs.guestbook.service.GuestbookLocalServiceUtil;
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.portal.kernel.servlet.SessionErrors;
import com.liferay.portal.kernel.servlet.SessionMessages;
import com.liferay.portal.kernel.util.ParamUtil;
import com.liferay.portal.service.ServiceContext;
import com.liferay.portal.service.ServiceContextFactory;
import com.liferay.portal.util.PortalUtil;
import com.liferay.util.bridges.mvc.MVCPortlet;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.PortletException;
import javax.portlet.PortletPreferences;
import javax.portlet.ReadOnlyException;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.portlet.ValidatorException;

import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * Portlet implementation class GuestbookPortlet
 */
public class GuestbookPortlet extends MVCPortlet {
    
 
    public void addGuestbook(ActionRequest request, ActionResponse response)
            throws PortalException, SystemException {

        ServiceContext serviceContext = ServiceContextFactory.getInstance(
            Guestbook.class.getName(), request);

        String name = ParamUtil.getString(request, "name");

        try {
            GuestbookLocalServiceUtil.addGuestbook(serviceContext.getUserId(),
                    name, serviceContext);

            SessionMessages.add(request, "guestbookAdded");

        } catch (Exception e) {
            SessionErrors.add(request, e.getClass().getName());

            response.setRenderParameter("mvcPath",
                "/html/guestbook/edit_guestbook.jsp");
        }

    }
    
    public void addEntry(ActionRequest request, ActionResponse response)
            throws PortalException, SystemException {

        ServiceContext serviceContext = ServiceContextFactory.getInstance(
                Entry.class.getName(), request);

        String userName = ParamUtil.getString(request, "name");
        String email = ParamUtil.getString(request, "email");
        String message = ParamUtil.getString(request, "message");
        long guestbookId = ParamUtil.getLong(request, "guestbookId");

        try {
            EntryLocalServiceUtil.addEntry(serviceContext.getUserId(),
                    guestbookId, userName, email, message, serviceContext);

            SessionMessages.add(request, "entryAdded");

            response.setRenderParameter("guestbookId",
                    Long.toString(guestbookId));

        } catch (Exception e) {
            SessionErrors.add(request, e.getClass().getName());

            PortalUtil.copyRequestParameters(request, response);

            response.setRenderParameter("mvcPath",
                    "/html/guestbook/edit_entry.jsp");
        }

    }

    @Override
    public void render(RenderRequest renderRequest,
            RenderResponse renderResponse) throws PortletException, IOException {

        try {
            ServiceContext serviceContext = ServiceContextFactory.getInstance(
                    Guestbook.class.getName(), renderRequest);

            long groupId = serviceContext.getScopeGroupId();

            long guestbookId = ParamUtil.getLong(renderRequest, "guestbookId");

            List<Guestbook> guestbooks = GuestbookLocalServiceUtil
                    .getGuestbooks(groupId);

            if (guestbooks.size() == 0) {
                Guestbook guestbook = GuestbookLocalServiceUtil.addGuestbook(
                        serviceContext.getUserId(), "Main", serviceContext);

                guestbookId = guestbook.getGuestbookId();

            }

            if (!(guestbookId > 0)) {
                guestbookId = guestbooks.get(0).getGuestbookId();
            }

            renderRequest.setAttribute("guestbookId", guestbookId);

        } catch (Exception e) {

            throw new PortletException(e);
        }

        super.render(renderRequest, renderResponse);

    }
    

}
View Code

 

 

完整代碼下載 Source Code

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM