tl;dr
O
PGSimpleDataSource
classe empacotada com o driver JDBC de jdbc.postgresql.org implementa DataSource
interface. Configure seus detalhes de conexão de banco de dados em um PGSimpleDataSource
objeto e passar como um DataSource
objeto. PGSimpleDataSource ds = new PGSimpleDataSource() ;
ds.setServerName( "localhost" );
ds.setDatabaseName( "your_db_name_here" );
ds.setUser( "scott" );
ds.setPassword( "tiger" );
Use esse objeto para fazer uma conexão com o banco de dados conforme necessário. Use a sintaxe conveniente de try-with-resources.
try
(
Connection conn = ds.getConnection() ;
)
{ … }
Implementação do driver JDBC
Seu driver JDBC pode fornecer a você uma implementação do
DataSource
interface. Um objeto desta implementação contém as informações necessárias para fazer e configurar uma conexão com o banco de dados, como:
- Nome e senha do usuário do banco de dados
- Endereço IP e número da porta do servidor de banco de dados
Até três tipos de implementação fornecidos podem estar disponíveis:
- Muitas vezes, essa implementação é um wrapper fino em torno do
DriverManager
. Cada vez que você chamaDataSource::getConnection
no objeto de tal implementação, você obtém uma nova conexão de banco de dados. - Como alternativa, uma implementação pode usar um pool de conexões abaixo para fornecer conexões já existentes. Essas conexões são entregues e devolvidas, como livros em uma biblioteca, para serem recicladas para uso repetido.
- Uma implementação pode suportar a API de transações Java, suportando X/Open XA, para necessidades sofisticadas, como coordenar as transações em vários recursos, como bancos de dados e filas de mensagens. Não é tão comumente usado, então eu ignoro esse tipo aqui.
Driver de jdbc.postgresql.org
O driver gratuito de código aberto de jdbc.postgresql.org fornece todos os três tipos de
DataSource
implementação. Mas os autores não recomendam realmente usar seu tipo de pool de conexão na produção; se você quiser fazer um pool, use uma biblioteca de pool de conexões de terceiros. E estamos ignorando o tipo XA. Então, vamos ver a implementação simples de conexão sempre atualizada de
DataSource
:org.postgresql.ds.PGSimpleDataSource
Configurando o objeto de fonte de dados
Instancie um objeto vazio e chame uma série de métodos setter para configurar para seu cenário de banco de dados específico. Os métodos setter são herdados de
org.postgresql.ds.common.BaseDataSource
. Ainda não estamos fazendo upcast para a interface
DataSource
, para que possamos chamar os vários métodos setter. Consulte o código de exemplo e a discussão na página Fontes de dados e 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?
Geralmente eu usaria esses métodos separados de setter. Como alternativa, você constrói uma String, uma URL, com as várias informações a serem definidas no
DataSource
em um golpe. Se você quiser seguir esse caminho, chame setUrl
. Isso cobre o básico. Mas você pode querer ou precisar de alguns dos outros setters. A maioria deles está configurando valores de propriedade Postgres no servidor. Todas as propriedades têm padrões inteligentes, mas você pode desejar substituir para situações especiais.
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.
Se estiver usando TLS (anteriormente conhecido como SSL) para criptografar a conexão do banco de dados para proteger contra espionagem ou manipulação malévola, use vários setters para isso.
Para qualquer propriedade do Postgres sem um método setter específico, você pode chamar
setProperty( PGProperty property, String value )
. Você pode inspecionar ou verificar as configurações dessa fonte de dados chamando qualquer um dos muitos métodos getter.
Depois de configurar seu
PGSimpleDataSource
, você pode passar para o resto de sua base de código simplesmente como um DataSource
objeto. Isso isola sua base de código do choque de mudar para outro DataSource
implementação ou mudar para outro driver JDBC. DataSource dataSource = ds ; // Upcasting from concrete class to interface.
return dataSource ;
Usando a fonte de dados
Usando um
DataSource
é totalmente simples, pois fornece apenas dois métodos, um par de variações em getConnection
para obter uma Connection
objeto para seu trabalho de banco de dados. Connection conn = dataSource.getConnection() ;
Quando terminar com sua
Connection
, a melhor prática é fechá-lo. Use uma sintaxe try-with-resources para fechar automaticamente a conexão ou feche-a explicitamente. conn.close() ;
Tenha em mente que um
DataSource
não é realmente uma fonte de dados. Uma DataSource
é realmente uma fonte para gerar/acessar conexões com o banco de dados. Na minha opinião, este é um nome impróprio, pois penso nele como ConnectionSource
. O DataSource
conversa com seu banco de dados apenas o tempo suficiente para entrar com nome de usuário e senha. Após esse login, você usa a Connection
objeto para interagir com o banco de dados. Armazenando seu DataSource
Uma vez configurado, você deseja manter esse
DataSource
objeto ao redor, em cache. Não há necessidade de reconfigurar repetidamente. A implementação deve ser escrita para ser thread-safe. Você pode chamar getConnection
a qualquer hora de qualquer lugar. Para um pequeno aplicativo Java simples, você pode armazená-lo como um campo em um singleton ou em uma variável global estática.
Para um aplicativo baseado em Servlet, como um Vaadin app, você criaria uma classe implementando
ServletContextListener
interface. Nessa classe, você estabeleceria seu DataSource
objeto quando seu aplicativo da web está sendo iniciado. A partir daí você armazenaria o objeto no ServletContext
objeto passando para setAttribute
. Context
é o termo técnico para 'aplicativo web'. Recupere chamando getAttribute
e transmitindo para DataSource
. Em um cenário corporativo, o
DataSource
podem ser armazenados em uma implementação compatível com JNDI. Alguns contêineres Servlet, como o Apache Tomcat, podem fornecer uma implementação JNDI. Algumas organizações usam um servidor como um servidor LDAP. Registrando e recuperando seu DataSource
objeto com JNDI é abordado em muitas outras perguntas e respostas no Stack Overflow.