-
Notifications
You must be signed in to change notification settings - Fork 37.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use JDBC driver-provided named prepared statements if available #32798
Comments
It would be nice if the driver auto detect named or positional parameters since mixing them is forbidden, like JPA does. |
Based on my current understanding, "auto detect" is likely not an option as it might create subtle parsing issues. Imagine somebody wants executing SQL that has no parameters yet they want including |
If there is any named parameter like |
The query might contain no placeholders at all in which case you won't be able to tell if it is "positional or named". PostgreSQL has |
Then use positional as default because it's JDBC standard.
The user should know it's named parameter query because they write sql to include |
Please, this is getting off-topic. The key question for this issue is whether spring-framework is willing to use non-standard extensions to JDBC provided by the drivers |
Thanks for the suggestion but |
@vlsi I don't know what the confused emoji means but we're not restricting things in any way for those who are willing to use the |
Consider the following:
In other words, leveraging driver API would improve performance and reduce CPU/memory utilization.
Do you have Spring-specific SQL syntax there? If the only difference is "parameters should be |
@snicoll , I understand For instance, Java provides |
@vlsi we appreciate the intention there but unless this becomes a standard JDBC feature - and there ideally even in our JDBC baseline version -, we would effectively introduce separate code paths for processing a named parameter query against new-enough versions of the Postgres and Oracle drivers, with unwrapping the PreparedStatement from the connection pool handle down to the native driver first, and potentially with subtle differences in parsing/encoding/etc next to our regular code path where we parse a named parameter query into positional parameters ourselves. For the time being, the maintenance impact of such an arrangement is not desirable for us at all. We would only really embrace such driver-level parsing if we could revise our entire arrangement towards standard driver support there, getting rid of our own named parameter parsing completely. |
This is to discuss an enhancement.
Problem
PostgreSQL JDBC driver team discusses an enhancement so the driver could support named parameters via non-standard API.
By default, JDBC provides positional arguments only, so people can't use queries like
name = :name or :name is null
, and they have to pass:name
twice.In fact, PostgreSQL does support "reusing placeholder value several times", so PostgreSQL-native query could be like
name = $1 or $1 is null
where$1
would be a single parameter. In that case, JDBC driver would pass the value for$1
just once, and the database would reuse it at both positions.So here's my question: what do you think of using pgjdbc-specific extensions within spring-framework?
For instance, what if
NamedParameterJdbcTemplate
(or the relevant bit) would use special API so it could defer named parameter transformation to the JDBC driver?Here's pgjdbc PR: pgjdbc/pgjdbc#1946
Examples
Here's a draft API:
An alternative option could be driver-specific API to prepare statements like:
Note: JDBC specifies 6
prepareStatement
methods (e.g. autogeneratedKeys, resultsettype, holdability, and so on), so if we go with addingPlaceholderStyle
parameter, we would have to add 6 newprepareStatement
methods.The native PostgreSQL syntax is to use
$1
, ...$99
variable names, so an alternative option forNamedParameterJdbcTemplate
could be replacing its names with$n
names. I am not sure it makes a huge difference though.WDYT?
Oracle DB JDBC does have the similar API for quite some time now (I guess 10+ years):
OraclePreparedStatement.setIntAtName(String, int)
The text was updated successfully, but these errors were encountered: