以编程方式为Postgres JDBC生成“数据源”对象tl;博士JDBC 驱动程序的实现存储您的DataSource

JDBC 教程建议使用 DataSource 对象来获取数据库连接,而不是使用类。引用“使用数据源对象连接”页:DriverManager

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

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

现在,我不想像这样那样摆弄JNDI。

我可以在 Java 应用程序中以编程方式实例化一个吗?还是我必须自己实现该接口?DataSourceDataSource


答案 1

tl;博士

PGSimpleDataSource 类与来自 jdbc.postgresql.org 实现接口的 JDBC 驱动程序捆绑在一起。在对象中配置数据库连接详细信息,并作为对象进行传递。DataSourcePGSimpleDataSourceDataSource

PGSimpleDataSource ds = new PGSimpleDataSource() ;  
ds.setServerName( "localhost" );  
ds.setDatabaseName( "your_db_name_here" );   
ds.setUser( "scott" );       
ds.setPassword( "tiger" );   

根据需要使用该对象与数据库建立连接。使用方便的资源试用语法。

try
(
    Connection conn = ds.getConnection() ;
) 
{ … }

JDBC 驱动程序的实现

您的 JDBC 驱动程序可能会为您提供数据源接口的实现。

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

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

最多可以提供三种实现方式:

  • 通常,这样的实现是驱动程序管理器周围的薄包装器。每次在这样的实现对象上调用 DataSource::getConnection 时,你都会获得一个新的数据库连接。
  • 或者,实现可以使用下面的连接池来提供已存在的连接。这些连接被分发并签回,就像图书馆里的书籍一样,被回收利用以重复使用。
  • 实现可能支持 Java 事务 API,支持 X/Open XA,以满足复杂的需求,例如跨多个资源(如数据库和消息队列)协调事务。不那么常用,所以我在这里忽略了这种类型。

jdbc.postgresql.org 的司机

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

因此,让我们看一下:org.postgresql.ds.PGSimpleDataSource的简单fresh-connection-each-time实现。DataSource

配置数据源对象

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

我们还没有向上转换到接口,以便我们可以调用各种 setter 方法。请参阅数据源和 JNDI 页面上的示例代码和讨论。DataSource

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 方法。或者,您可以构造一个字符串,一个URL,并在上一笔设置各种信息。如果你想走这条路,请调用 setUrlDataSource

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

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 属性,String value )。

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

配置完 之后,您可以简单地将代码库的其余部分作为 DataSource 对象传递到。这将使您的代码库免受更改为另一个实现或更改为另一个 JDBC 驱动程序的冲击。PGSimpleDataSourceDataSource

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

使用数据源

使用 a 非常简单,因为它只提供了两种方法,即 getConnection 上的一对变体,用于获取数据库工作的 Connection 对象。DataSource

Connection conn = dataSource.getConnection() ; 

完成后,最佳做法是确保将其关闭。使用资源试用语法自动关闭连接,或显式关闭连接。Connection

conn.close() ;

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

存储您的DataSource

配置完成后,您希望保留该对象并进行缓存。无需重复重新配置。应将实现编写为线程安全。您可以随时随地致电。DataSourcegetConnection

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

对于基于 Servlet 的应用程序(如 Vaadin 应用程序),您将创建一个类实现接口。在该类中,您将在 Web 应用启动时建立对象。从那里,您可以通过传递给setAttribute将对象存储在ServletContext对象中。 是“Web 应用程序”的技术术语。通过调用和强制转换为 来检索 。ServletContextListenerDataSourceContextgetAttributeDataSource

在企业场景中,可以存储在符合 JNDI 的实现中。一些Servlet容器(如Apache Tomcat)可能会提供JNDI实现。某些组织使用 LDAP 服务器等服务器。使用 JNDI 注册和检索对象在 Stack Overflow 上的许多其他问答中都有介绍。DataSourceDataSource


答案 2

推荐