Liferay 7.0 修改service.xml後如何讓portal從新執行tables.sql

1、問題
 若是你開發了service-builder類型的項目(我確定你必定會開發這種類型的項目),其中所使用的業務實體的數據庫表結構就在service.xml中配置,而後執行build-service生成相關dao層的代碼(不清楚dao的概念的參考 這篇文章),而後部署項目,portal就會自動執行建立數據庫表的sql語句。在62開發中,修改service.xml後,執行build-service,部署項目,portal會根據表結構的變化幫你自動修改數據裏面的表,而且儘量保留數據(我試過,增長字段沒問題,其餘忘了)。
    以上是一些背景知識,可是在dxp開發中,根據所謂的數據庫保護機制,即便咱們在service.xml中修改了表結構,從新部署項目時,portal不會幫咱們修改數據庫表結構,即便在開發階段也是如此。若是你想讓portal修改表結構,你就要按照 這篇文章的方式來作,即:每次修改表結構,就要寫對應的數據庫升級語句,因爲過程比較複雜,我一直沒按照文章操做,看着就頭暈,不過是爲了修改數據庫表結構,爲什麼要我寫額外的代碼?因而我研究了lifeay執行tables.sql的過程,發現了強制讓portal執行tables.sql的方法。
 
二 、解決方案
    首先我只是說出方法,讓着急使用的人直接使用,而後我再分享研究過程。
    前提:portal是鏈接mysql啓動的
    方法:
    1. 修改service.xml,運行build-service
    2. 鏈接mysql數據庫,找到servicecomponent表,刪除裏面namespace的值和你的service.xml中namespace值相同的全部數據
    3. 同時刪除service.xml對對應的已經建立的全部表
    4. 在Server Administrator裏面執行Verify database tables of all plugins
    5. 部署項目,portal會從新執行tables.sql,表就從新創建了
    (補充:部署項目後,看到輸出了"Running   xxxx  SQL scripts",可是數據庫中仍是沒有表,這時再次執行Verify database tables of all plugins就能夠在數據庫看到表了)
 
3、研究過程
接下來我分享一下研究過程:
    咱們可能注意到了,部署一個新service-builder類型的項目時,控制檯會輸出一個語句 "Running   xxxx  SQL scripts",在portal源碼中搜索「SQL scripts」,找到了在 ServiceComponentLocalServiceImpl.java類裏面,
若是是已經部署過的項目,再次部署,只會看到「Upgrading xxxx database to build number ?」之類的信息,說明數據庫中必定有表記錄着哪些項目部署過,buildnumber是多少,因而咱們找到了servicecomponent表,查看數據,正好有咱們用過的namespace,刪除這些數據,從新部署項目,發現並不能執行tables.sql文件,咱們猜想可能內存中存在某些緩存記錄這些數據,因而執行了Verify database tables of all plugins,再次部署,終於能執行tables.sql了。ServiceComponentLocalServiceImpl.java是比較核心的類,若是仔細研究這個類的代碼會有其餘收穫,這裏只列舉一個例子:
 
 
你們能夠看到這個類其實支持升級數據庫的操做,只要以前的tablesql和新的tablesql不一致時,會執行升級數據庫操做,按照咱們的思路,咱們兩次部署的tables.sql是不一致的,爲何不執行這段代碼呢?調試發現tablessql變量始終爲空字符串(不是null,是值爲「」的字符串),因此永遠不會執行升級數據庫操做,servicecomponent表的CDATA字段也能看出,dxp不會記錄tables.sql語句。至於爲何執行Verify database tables of all plugins,才能從新執行,我沒有再往下研究了,參考 EditServerMVCActionCommand.java中的verifyPluginTables()方法。
 
分析到此結束,個人分析可能不全面,也可能有錯誤,請你們批評指正哈。
相關文章
相關標籤/搜索