在Heroku上部署Java应用-连接数据库

发表于:2013-03-26 22:03:22,已有3543次阅读

原文:https://devcenter.heroku.com/articles/connecting-to-relational-databases-on-heroku-with-java

部署在Heroku上的应用程序可以使用多种关系数据库服务,包括Heroku提供的Postgres数据库和AWS(亚马逊)提供的MySQL数据库。

数据库的提供是通过使用add-on系统实现的。默认情况下,应用将会被提供一个小的并且免费的Postgres数据库,你可以通过如下的命令来检查提供的数据库:

$ heroku info
=== sparkling-wine-2003
Web URL:        http://sparkling-wine-2003.herokuapp.com/
Git Repo:       git@heroku.com:sparkling-wine-2003.git
Repo size:      21M
Slug size:      916k
Stack:          cedar
Data size:      (empty)
Addons:         Heroku Postgresql Dev
Owner:          jesper@heroku.com

可以看到Addons项中的“Heroku Postgresql Dev”。这个是根据应用构建默认添加的,你还可以手动使用如下命令添加:

$ heroku addons:add heroku-postgresql

这里的dev 数据库意味着,此数据库仅是为了测试而用。对于要发部的应用应该使用Heroku Postgres数据库或SQLadd-ons.

注解:这里说明的是使用系统默认提供的数据库仅为了满足测试而用,要想获得更高的数据库性能,必须使用那些Add-ons收费的数据库服务,但对于小打小闹的我来说,免费的Heroku PostgreSQL dev提供的10,000行数据,已经足够了。

当你的应用添加了一个关系型数据库时,你就可以通过读取DATABASE_URL配置变量来获取数据库的连接信息,对应它的格式如下:

[database type]://[username]:[password]@[host]:[port]/[database name]

例如:

postgres://foo:foo@heroku.com:5432/hellodb

你可以通过如下命令来获取Heroku提供给你的DATABASE_URL变量:

$ heroku config
DATABASE_URL            => postgres://foo:foo@heroku.com:5432/hellodb

在这里不推荐将如上的DATABASE_URL环境变量复制到一个静态的文件中通过程序解析。因为这样不方便应用环境的变更。对于一个实例应用来说,可以直接通过读取系统的环境变量来获取DATABASE_URL,从而解析获取数据库的连接信息。

直接通过DATEBASE_URL获取JDBC连接

如下通过JDBC直接访问数据库,代码如下:

private Connection getConnection() throws URISyntaxException, SQLException {
    URI dbUri = new URI(System.getenv("DATABASE_URL"));

    String username = dbUri.getUserInfo().split(":")[0];
    String password = dbUri.getUserInfo().split(":")[1];
    String dbUrl = "jdbc:postgresql://" + dbUri.getHost() + dbUri.getPath();

    return DriverManager.getConnection(dbUrl, username, password);
}

在Spring的XML配置文件中使用DATEBASE_URL

本段Spring XML配置文件中将通过DATEBASE_URL配置一个BasicDataSource Bean,这样方便与Hibernate,JPA等进行整合,如下:

<bean class="java.net.URI" id="dbUrl">
    <constructor-arg value="#{systemEnvironment['DATABASE_URL']}"/>
</bean>

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
    <property name="url" value="#{ 'jdbc:postgresql://' + @dbUrl.getHost() + ':' + @dbUrl.getPort() + '/' + @dbUrl.getPath() }"/>
    <property name="username" value="#{ @dbUrl.getUserInfo().split(':')[0] }"/>
    <property name="password" value="#{ @dbUrl.getUserInfo().split(':')[1] }"/>
</bean>

直接使用DATABASE_URL在Spring代码中配置

另外,还可以直接在Spring的代码中通过DATABASE_URL来获取一个BasicDataSource对象,如下:

@Configuration
public class MainConfig {

    @Bean
    public BasicDataSource dataSource() throws URISyntaxException {
        URI dbUri = new URI(System.getenv("DATABASE_URL"));

        String username = dbUri.getUserInfo().split(":")[0];
        String password = dbUri.getUserInfo().split(":")[1];
        String dbUrl = "jdbc:postgresql://" + dbUri.getHost() + ':' + dbUri.getPort() + "/" + dbUri.getPath();

        BasicDataSource basicDataSource = new BasicDataSource();
        basicDataSource.setUrl(dbUrl);
        basicDataSource.setUsername(username);
        basicDataSource.setPassword(password);

        return basicDataSource;
    }
}

注意:

 在Heroku Postgres的DATABASE_URL使用的是如下形式:

postgres://<username>:<password>@<host>/<dbname>

而在PostgresSQL中JDBC的URL应该使用的是如下形式:

jdbc:postgresql://<host>:<port>/<dbname>?username=<username>&password=<password>

注意这里的两个URL是不同的,因此在使用时,需要手动的处理一下,使其符合PostgresSQL的JDBC标准。

远程连接数据库

如果使用的是Heroku Postgres数据库,你可以通过远程连接来管理和调试它。如果实现这,需要建立一个SSL连接:在你的JDBC连接的URL中,需要加上如下参数:

ssl=true&sslfactory=org.postgresql.ssl.NonValidatingFactory

如果ssl为false,将会得到一个连接错误,同时如果不设置sslfactory=org.postgresql.ssl.NonValidatingFactory,你将可能得到如下错误:

unable to find valid certification path to requested target
点击这里,可获取更多关于Postgres JDBC 驱动的SSL支持。而对于其实的SQL数据库,请参考相应的JDBC文档。

注解:关于PostgresSQL的远程连接本人未试过,上面的只是照搬过来的。

示例项目

在这里有Heroku官网提供的一个以三种方式(包括使用Java的Play框架,由于我没学过,因此上面的关于Play的处理我忽略了,详情见原文)连接数据库的示例项目:https://github.com/heroku/devcenter-java-database

关于示例项目的运行,先要根据Heroku给你分配的DATABASE_URL,在本地也要仿造设置一个DATABASE_URL环境变量:

在Linux/Mac平台下,使用如下命令:

export DATABASE_URL=postgres://foo:foo@localhost/hellodb

在Windows平台下,使用如下命令:

set DATABASE_URL=postgres://foo:foo@localhost/hellodb

注意:在设置好变量后,不要关闭命令行或终端,需要继续在其中运行命令才行。

设置好环境变量后,接着就是运行了,由于上面的示例项目都使用Maven生成了相应的批处理或Shell脚本文件,因此运行这些程序直接运行这些脚本就行,如下:

在Linux/Mac平台下:

sh devcenter-java-database-plain-jdbc/target/bin/main
sh devcenter-java-database-spring-xml/target/bin/main
sh devcenter-java-database-spring-java/target/bin/main

在Windows平台下:

devcenter-java-database-plain-jdbc/target/bin/main.bat
devcenter-java-database-spring-xml/target/bin/main.bat
devcenter-java-database-spring-java/target/bin/main.bat

如果一切顺利,你将会看到如下的提示信息:

Read from DB: 2011-11-23 11:37:03.886016

接着就是将其部署到Heroku上了,这与部署普通的Java应用是一样,在本地运行通过后,直接使用Git Pushing上传代码于Heroku就行了。

关于部置Java应用到Heroku上,请参考我的上篇文章:http://lzqwebsoft.herokuapp.com/show/20130218050850.html

关于上面的示例项目Pushing上传后的运行,需要额外的使用如下命令:

$ heroku run "sh devcenter-java-database-plain-jdbc/target/bin/main"
Running sh devcenter-java-database-plain-jdbc/target/bin/main attached to terminal... up, run.1
Read from DB: 2011-11-29 20:36:25.001468

注解:由上面的信息可知Heroku上的运行环境,应该是LINUX,呵呵。关于原文中设置环境变量后在本地运行,我的是测试失败了,原因是数据库连接不上,可以是在国内,访问Heroku国外的数据库,网络跟不上吧。

运行heroku run "Shell脚本"命令可以在heroku端执行shell脚本命令。

注意:这里执行的所有Heroku命令需要在你的项目的根目录下执行。

分享到:

扫一扫,用手机观看!

用微信扫描还可以

分享至好友和朋友圈

二维码分享
评论

暂无评论

您还可输入120个字