sql >> Base de Datos >  >> RDS >> PostgreSQL

Producir un objeto `DataSource` para Postgres JDBC, programáticamente

tl;dr

El PGSimpleDataSource La clase incluida con el controlador JDBC de jdbc.postgresql.org implementa DataSource interfaz. Configure los detalles de conexión de su base de datos en un PGSimpleDataSource objeto, y pasarlo como un DataSource objeto.

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

Utilice ese objeto para establecer una conexión con la base de datos según sea necesario. Utilice la sintaxis práctica de prueba con recursos.

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

Implementación del controlador JDBC

Su controlador JDBC puede proporcionarle una implementación de DataSource interfaz.

Un objeto de esta implementación contiene la información necesaria para realizar y configurar una conexión a la base de datos, como:

  • Nombre y contraseña del usuario de la base de datos
  • Dirección IP y número de puerto del servidor de la base de datos

Pueden estar disponibles hasta tres tipos de implementación proporcionados:

  • A menudo, dicha implementación es una envoltura delgada alrededor del DriverManager . Cada vez que llame a DataSource::getConnection en el objeto de dicha implementación, obtiene una nueva conexión de base de datos.
  • Alternativamente, una implementación puede usar un conjunto de conexiones debajo para proporcionar conexiones ya existentes. Estas conexiones se entregan y se devuelven, como libros en una biblioteca, para reciclarlos y usarlos repetidamente.
  • Una implementación puede admitir la API de transacciones de Java, compatible con X/Open XA, para necesidades sofisticadas, como la coordinación de transacciones en varios recursos, como bases de datos y colas de mensajes. No se usa con tanta frecuencia, así que ignoro este tipo aquí.

Controlador de jdbc.postgresql.org

El controlador gratuito de código abierto de jdbc.postgresql.org proporciona los tres tipos de DataSource implementación. Pero los autores no recomiendan usar realmente su tipo de grupo de conexiones en producción; si desea agrupar, use una biblioteca de agrupación de conexiones de terceros. Y estamos ignorando el tipo XA.

Así que echemos un vistazo a la implementación simple de nueva conexión cada vez de DataSource :org.postgresql.ds.PGSimpleDataSource

Configuración del objeto de fuente de datos

Cree una instancia de un objeto vacío, luego llame a una serie de métodos de establecimiento para configurar su escenario de base de datos particular. Los métodos setter se heredan de org.postgresql.ds.common.BaseDataSource .

Todavía no estamos actualizando a la interfaz DataSource , de modo que podamos llamar a los diversos métodos setter. Vea el código de ejemplo y la discusión en la página Fuentes de datos y 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?

En general, usaría estos métodos de establecimiento separados. Alternativamente, construye una cadena, una URL, con las diversas piezas de información que se establecerán en el DataSource de un solo golpe Si quieres seguir esa ruta, llama a setUrl .

Eso cubre lo básico. Pero es posible que desee o necesite algunos de los otros setters. La mayoría de estos están configurando valores de propiedad de Postgres en el servidor. Todas las propiedades tienen valores predeterminados inteligentes, pero es posible que desee anularlos para situaciones especiales.

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.

Si usa TLS (anteriormente conocido como SSL) para cifrar la conexión de la base de datos para protegerse contra escuchas ilegales o manipulación malévola, use varios configuradores para eso.

Para cualquier propiedad de Postgres sin un método de establecimiento específico, puede llamar a setProperty( PGProperty property, String value ) .

Puede inspeccionar o verificar la configuración en esta fuente de datos llamando a cualquiera de los muchos métodos getter.

Después de configurar su PGSimpleDataSource , puede pasar al resto de su base de código simplemente como un DataSource objeto. Esto aísla su código base del impacto de cambiar a otro DataSource implementación o cambio a otro controlador JDBC.

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

Uso de la fuente de datos

Usando una DataSource es absolutamente simple ya que proporciona solo dos métodos, un par de variaciones en getConnection para obtener una Connection objeto para el trabajo de su base de datos.

Connection conn = dataSource.getConnection() ; 

Cuando haya terminado con su Connection , la mejor práctica es asegurarse de cerrarlo. Utilice una sintaxis de prueba con recursos para cerrar automáticamente la conexión o ciérrela explícitamente.

conn.close() ;

Tenga claro que una DataSource no es en realidad una fuente de datos. Una DataSource es realmente una fuente para generar/acceder a conexiones a la base de datos. En mi opinión, este es un nombre inapropiado, ya que lo considero ConnectionSource . El DataSource habla con su base de datos solo el tiempo suficiente para iniciar sesión con nombre de usuario y contraseña. Después de ese inicio de sesión, utiliza la Connection objeto para interactuar con la base de datos.

Almacenamiento de su DataSource

Una vez configurado, desea mantener ese DataSource objeto alrededor, en caché. No es necesario reconfigurar repetidamente. La implementación debe escribirse para que sea segura para subprocesos. Puede llamar a getConnection en cualquier momento desde cualquier lugar.

Para una pequeña aplicación Java simple, es posible que desee almacenarla como un campo en un singleton o en una variable global estática.

Para una aplicación basada en Servlet como Vaadin app, crearía una clase implementando ServletContextListener interfaz. En esa clase establecería su DataSource objeto cuando se inicia su aplicación web. A partir de ahí, almacenaría el objeto en el ServletContext objeto pasando a setAttribute . Context es el término técnico para 'aplicación web'. Recupera llamando a getAttribute y envío a DataSource .

En un escenario empresarial, el DataSource puede almacenarse en una implementación compatible con JNDI. Algunos contenedores de Servlet, como Apache Tomcat, pueden proporcionar una implementación JNDI. Algunas organizaciones utilizan un servidor como un servidor LDAP. Registro y recuperación de su DataSource El objeto con JNDI está cubierto en muchas otras preguntas y respuestas sobre el desbordamiento de pila.