如何將liquibase部署到tomcat伺服器上(使用postgresql資料庫)
Liquidbase作為一個數據庫的自動更新軟體,可以更好的在不同的工作者之間同步資料庫的變化。在這裡,以postgresql和tomcat作為例子,展示如何如何將liquibase部署到伺服器上
安裝tomcat, postgresql, liquibae
本人使用的是:
apache-tomcat-8.0.28。安裝路徑:c:\apache-tomcat-8.0.28
PostgreSQL-9.3。安裝路徑是:c:\PostgreSQL\9.3\
liquibase-3.4.1。 安裝路徑是:c:\liquibase-3.4.1-bin\
設定好各種環境變數:
LIQUIBASE_HOME=c:\liquibase-3.4.1-bin
export PATH=%PATH%;%LIQUIBASE_HOME%;
將postgresql的jdbc的jar包拷貝到tomcat的lib目錄
下載postgresql對應版本的jdbc。將jdbc拷貝到tomcat的lib目錄下:
c:\apache-tomcat-8.0.28\lib\postgresql-9.3-1104-jdbc4.jar
配置tomcat的server.xml, context.xml和web.xml(啟動Liquibase的服務)
這部分內容需要同學們自己去腦補JDNI。
首先,需要在server.xml裡面配置postgresql資料庫的連線池。
- 開啟c:\apache-tomcat-8.0.28\conf\server.xml,找到GlobalNamingResources標籤,在該標籤下新增Resouce
<GlobalNamingResources>
...
<Resource
name="jdbc/postgres"
scope="Shareable"
type="javax.sql.DataSource"
url="jdbc:postgresql://127.0.0.1:5432/postgres"
driverClassName ="org.postgresql.Driver"
username="postgres"
password ="postgres"
/>
</GlobalNamingResources>
resource中的Name,代表的是這個resource在JDNI中的資源位置。其他的標籤則用於表明伺服器如何建立jdbc連結時的引數
–開啟c:\apache-tomcat-8.0.28\conf\context.xml,新增resourceLink
<Context>
<WatchedResource>WEB-INF/web.xml</WatchedResource>
<WatchedResource>${catalina.base}/conf/web.xml</WatchedResource>
<ResourceLink name="jdbc/postgres" global="jdbc/postgres" type="javax.sql.DataSource"/>
</Context>
- 開啟工程目錄下的web.xml或者tomcat/conf目錄下web.xml, 增加以下內容
<resource-ref>
<description>DB Connection</description>
<res-ref-name>jdbc/postgres</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
<context-param>
<param-name>liquibase.changelog</param-name>
<param-value>${catalina.base}\conf\db.changelog.xml</param-value>
</context-param>
<context-param>
<param-name>liquibase.datasource</param-name>
<param-value>java:comp/env/jdbc/postgres</param-value>
</context-param>
<context-param>
<param-name>liquibase.contexts</param-name>
<param-value>jdbc/postgres</param-value>
</context-param>
<context-param>
<param-name>liquibase.onerror.fail</param-name>
<param-value>true</param-value>
</context-param>
<listener>
<listener-class>liquibase.integration.servlet.LiquibaseServletListener</listener-class>
</listener>
resource-ref標籤,表明是對server.xml中定義的resource的引用。
res-ref-name標籤,必須是server.xml中定義的Resource::name。
liquibase.changelog引數,對應的是liquibase的changelog file的位置。在這裡,我把該檔案部署在tomcat的conf目錄中。
liquibase.datasource引數,對應的是資料庫的JDNI連結地址。格式是:“java:comp/env/”加上dataresource name -> java:comp/env/jdbc/postgres
liquibase.contexts引數,對應的是liquibase需要的context,對應為context.xml中的resoucelink
建立db.changelog.xml,並部署到tomcat伺服器
現在我們可以開始用liquibase管理資料庫了。新建一個changelog, 這裡,我把檔案命名為db.changelog.xml (必須和web.xml中的liquibase.changelog引數一樣)
<databaseChangeLog xmlns="http://www.liquibase.org/xml/ns/dbchangelog/1.9"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog/1.9
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-1.9.xsd">
<changeSet id="1" author="LEX">
<createTable tableName="useraccount">
<column name="userid" type="varchar(20)">
<constraints primaryKey="true" />
</column>
<column name="accountstate" type="varchar(255)" />
</createTable>
</changeSet>
</databaseChangeLog>
然後執行tomcat. 我們可以看到liquibase通過changelog更新了postgres資料庫
table already exist錯誤
如果你在使用liquibase更新資料庫的時候碰到table already exist的錯誤提示,那極有可能是因為如下原因:
The table tracks each changeSet as a row, identified by a combination of the “id”, “author” and a “filename” column which stores the path to the changelog file.
Just adding new, more direct info on why the issue happens.
Liquibase DATABASECHANGELOG Documentation
Liquibase uses the DATABASECHANGELOG table to track which changeSets have been ran.
The table tracks each changeSet as a row, identified by a combination of the “id”, “author” and a “filename” column which stores the path to the changelog file.
Please note that the filename column stores the path to the changelog. This may be an absolute path or a relative path depending on how the changelog was passed to Liquibase. For best results, it should be a relative path.
If you move the database, as in the case of migrating, and the filename column contains full paths, Liquibase may not recognize the changeset from the DATABASECHANGELOG table.
如果你遇到錯誤:
table already exists
就證明其他程式用了同樣的檔名(changelog),id名,author名,在同一個資料庫上做過liquibase update操作。
解決這個問題的方法,是改變上面3個名字中的一個。或者新建一個數據庫!