以编程方式为Postgres JDBC生成一个`DataSource`对象

时间:2017-07-13 22:40:04

标签: postgresql jdbc database-connection datasource

JDBC Tutorial建议使用DataSource对象来获取数据库连接,而不是使用DriverManager类。引用Connecting with DataSource Objects页面:

  

DataSource个对象...获取数据源连接的首选方法。

如何获得与Postgres JDBC连接的此类对象?我有一个JDBC驱动程序。

现在,我不想像thisthis那样使用JNDI。

我可以在Java应用程序中以编程方式实例化DataSource吗?或者我必须自己实现DataSource界面吗?

1 个答案:

答案 0 :(得分:10)

JDBC驱动程序的实现

您的JDBC driver可能会为您提供DataSource界面的实现。

此实现的对象包含建立和配置与数据库的连接所需的信息,例如:

  • 姓名&数据库用户的密码
  • IP地址&数据库服务器的端口号

最多可提供三种实施方式:

  • 这种实现通常是围绕DriverManager的薄包装器。每次在这种实现的对象上调用DataSource::getConnection时,都会得到一个全新的数据库连接。
  • 或者,实现可能正在使用下面的connection pool来提供已存在的连接。这些连接被分发并重新检入,如图书馆中的书籍,以便重复使用。
  • 实现可以支持Java Transaction API,支持X/Open XA,以满足复杂的需求,例如协调跨多个资源(如数据库和消息队列)的事务。不常用,所以我在这里忽略这种类型。
来自jdbc.postgresql.org的

驱动程序

来自jdbc.postgresql.org的开源免费驱动程序提供了所有三种类型的DataSource实现。但作者不建议在生产中实际使用connection pool type;如果要池化,请使用第三方连接池库。我们忽略了the XA type

让我们看一下DataSourceorg.postgresql.ds.PGSimpleDataSource

的每次简单的全新连接实现

配置数据源对象

实例化一个空对象,然后调用一系列setter methods来配置您的特定数据库方案。 setter方法继承自org.postgresql.ds.common.BaseDataSource

我们尚未向界面DataSource转发,因此我们可以调用various setter methods。请参阅Data Sources and JNDI页面上的示例代码和讨论。

PGSimpleDataSource ds = new PGSimpleDataSource() ;  // Empty instance.
ds.setServerName( "localhost" );  // The value `localhost` means the Postgres cluster running locally on the same machine.
ds.setDatabaseName( "testdb" );   // A connection to Postgres must be made to a specific database rather than to the server as a whole. You likely have an initial database created named `public`.
ds.setUser( "testuser" );         // Or use the super-user 'postgres' for user name if you installed Postgres with defaults and have not yet created user(s) for your application.
ds.setPassword( "password" );     // You would not really use 'password' as a password, would you?

通常我会使用这些单独的setter方法。或者,您构造一个String,一个URL,其中包含要在DataSource中一次设置的各种信息。如果你想走那条路,请拨打setUrl

这涵盖了基础知识。但是你可能想要或需要一些其他的制定者。其中大多数是在服务器上设置Postgres property值。这些属性都具有智能默认值,但您可能希望覆盖特殊情况。

ds.setPortNumber( 6787 ) ;  // If not using the default '5432'.
ds.setApplicationName( "whatever" ) ;   // Identify the application making this connection to the database. Also a clever way to back-door some information to the Postgres server, as you can encode small values into this string for later parsing. 
ds.setConnectTimeout( … ) ;  // The timeout value used for socket connect operations, in whole seconds. If connecting to the server takes longer than this value, the connection is broken.
ds.setSocketTimeout( … ) ;  // The timeout value used for socket read operations. If reading from the server takes longer than this value, the connection is closed. This can be used as both a brute force global query timeout and a method of detecting network problems.
ds.setReadOnly( boolean ) ;  // Puts this connection in read-only mode.

如果使用TLS(以前称为SSL)加密数据库连接以防止窃听或恶意操纵,请使用多个setter。

对于没有特定setter方法的任何Postgres属性,您可以致电setProperty( PGProperty property, String value )

您可以通过调用任何一种getter方法来检查或验证此数据源的设置。

配置好PGSimpleDataSource后,您可以将DataSource对象作为another JDBC driver对象传递给代码库的其余部分。这可以使您的代码库免受更改为另一个DataSource实施或更改为getConnection的冲击。

DataSource dataSource = ds ;  // Upcasting from concrete class to interface.
return dataSource ; 

使用数据源

使用DataSource非常简单,因为它只提供了两种方法,Connection上的一对变体可以为数据库工作提供try-with-resources syntax对象。

Connection conn = dataSource.getConnection() ; 

完成Connection后,最佳做法是确保将其关闭。使用implementation should be written to be thread-safe自动关闭连接,或明确关闭连接。

conn.close() ;

请记住,DataSource实际上不是数据源。 DataSource实际上是生成/访问数据库连接的源。在我看来,这是一个用词不当,因为我认为它是ConnectionSourceDataSource与您的数据库通信的时间足够长,可以使用用户名和密码登录。登录后,您可以使用Connection对象与数据库进行交互。

存储您的DataSource

配置完成后,您希望保留DataSource对象,缓存。无需重复重新配置。 ServletVaadin。您可以随时随地致电getConnection

对于一个简单的小型Java应用程序,您可能希望将其作为字段存储在单例或静态全局变量中。

对于基于ServletContext的应用,例如setAttribute应用,您可以创建一个实现ServletContextListener接口的类。在该类中,您将在启动Web应用程序时建立DataSource对象。从那里你可以通过传递给JNDI将对象存储在Servlet containers对象中。 Context是“网络应用”的技术术语。通过调用getAttribute并转换为DataSource进行检索。

在企业方案中,DataSource可以存储在符合Apache Tomcat的实现中。某些LDAP server(例如{{3}})可能会提供JNDI实现。有些组织使用{{3}}等服务器。注册&使用JNDI检索DataSource对象包含在许多其他问题中。 Stack Overflow上的答案。