As your second snippet shows, yup, you can do that.
You can create a preparedstatement, then wait ages and ages, then set each 'parameter' (call e.g. .setInt(1, ...), for every question mark in the SQL string you passed), and call one of the execute methods, and then... wait some more ages and do that again, as many times as you like.
A preparedstatement lives as long as the connection lives, or until you close it, which you should. The real rub lies there: Closing them. You do have to close them explicitly. They are like files and net sockets that way.
I you mess that up, your app won't immediately crash and no tests will fail. However, the connection is permanently 'damaged', as it has only room for a limited amount of prepared statements. As you keep making more and never closing them, eventually you run out, and bizarre SQL Exceptions will occur. Your app is a ticking time bomb. This is the worst class of bugs: Hard to test for, will inevitably explode your app, exactly as things get busy. When bossman starts asking the legal team if they can sue you for gross negligence, that's when you go: Oof, maybe I shouldn't toy with code styles that lead to bugs that cannot easily be tested for, are hard to spot, and will only cause issues riight when things are busy.
So, follow (rigidly) protocols to avoid such things:
- Any resource that is created (via either
new SomeResource(), or via a method that is crystal clear that it is a creator, such as Files.newInputStream, must be closed by the same code, OR, that code must in turn be a closable resource.
- Sharpening up #1, unless you are a closable entity yourself, you can only open resources in a try-with block.
In other words, either you do this:
try (PreparedStatement ps = ....) {
// use ps here, as often as you want....
} // ps is closed here
or you do this:
class WhateverTool implements AutoClosable {
private PreparedStatement ps; // long-lived
@Override public void close() throws SQLException {
if (ps != null) ps.close();
}
}
and your only interaction with this class is, itself, in the form of:
try (WhateverTool t = new WhateverTool()) {
// do whatever you want here...
} // but this is where it ends
And there are no other options allowed in your code base to interact with resources.
Java doesn't enforce this, but you are definitely going to have a buggy mess if you don't follow these rules.