JDBC Tutorial建议使用DataSource
对象来获取数据库连接,而不是使用DriverManager
类。引用Connecting with DataSource Objects页面:
DataSource
个对象...获取数据源连接的首选方法。
如何获得与Postgres JDBC连接的此类对象?我有一个JDBC驱动程序。
我可以在Java应用程序中以编程方式实例化DataSource
吗?或者我必须自己实现DataSource
界面吗?
答案 0 :(得分:10)
您的JDBC driver可能会为您提供DataSource
界面的实现。
此实现的对象包含建立和配置与数据库的连接所需的信息,例如:
最多可提供三种实施方式:
DriverManager
的薄包装器。每次在这种实现的对象上调用DataSource::getConnection
时,都会得到一个全新的数据库连接。来自jdbc.postgresql.org的开源免费驱动程序提供了所有三种类型的DataSource
实现。但作者不建议在生产中实际使用connection pool type;如果要池化,请使用第三方连接池库。我们忽略了the XA type。
让我们看一下DataSource
:org.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
实际上是生成/访问数据库连接的源。在我看来,这是一个用词不当,因为我认为它是ConnectionSource
。 DataSource
与您的数据库通信的时间足够长,可以使用用户名和密码登录。登录后,您可以使用Connection
对象与数据库进行交互。
DataSource
配置完成后,您希望保留DataSource
对象,缓存。无需重复重新配置。 Servlet。Vaadin。您可以随时随地致电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上的答案。