I'm trying to idiomatically add some new query parameters to a JDBC URL, yet the URI builders that are at my disposal don't work correctly with URLs like
jdbc:postgres://localhost:6542/db
It seems they don't correctly recognize the scheme (in this case jdbc:postgres) and wrongfully assume the scheme is jdbc.
Is there any idiomatic way to add query parameters to a JDBC URL?
There is no such mechanism, because those URL builders are generally intended for RFC 3986 compliant URLs (maybe even only designed for use with scheme http and https), and JDBC URLs are not compliant.
In fact, JDBC 4.3 only specifies the following:
The format of a JDBC URL is :
- jdbc:<subprotocol>:<subname>
where
subprotocoldefines the kind of database connectivity mechanism that may be supported by one or more drivers. The contents and syntax of thesubnamewill depend on the subprotocol.
Note – A JDBC URL is not required to fully adhere to the URI syntax as defined in RFC 3986, Uniform Resource Identifier (URI): Generic Syntax.
As a result of this definition, essentially anything is valid for subname. Some drivers will seem to mimic RFC 3986, but may not require or support escapes. Some drivers support parameters (properties) in the URL, while others do not. Some may use ? and & to separate properties, while others may use ;, etc.
For PostgreSQL, you might get away with using a URL builder on postgres://localhost:6542/db, and adding the jdbc: prefix after building, but I'm not sure if PostgreSQL supports all features of a RFC 3986 URL, so you might still end up with an URL that cannot be properly parsed by the driver.
As suggested in the comments by Laurenz Albe, consider using a Properties object (when using DriverManager directly), or use mechanisms of your data source to set properties, instead of relying on passing those properties through the URL.
For example, when using DriverManager, you'd use:
String url = "jdbc:postgres://localhost:6542/db";
Properties props = new Properties();
props.setProperty("user", username);
props.setProperty("password", password);
props.setProperty("property1", "value1");
// ...
try (Connection connection = DriverManager.getConnection(url, props)) {
// use connection
}