The answer of my answer to the question in the second paragraph is that it is usually a bad idea to consider one aspect “sufficient” for such problems - at least if you do it to such an extent that you stop thinking about the principles of participation.
Using PreparedStatements makes a big way to stop SQL injection, just like using slapping down synchronized around the world is a long way to stop data races. And in many individual situations, they will be enough. But in both cases they are not magic bullets - you need to know the reasons why you use them, and when and where they are not enough. For example, if you think PreparedStatements is a magical wrapper that prevents SQL injection, you will be very disappointed the first time you need to create a dynamic statement (as opposed to just parameterized) based on user input.
So the thing that is “enough” is education. Understand how and why the threat works; as soon as you feel this, you will be able to take appropriate action for the situation (which sometimes just uses PreparedStatement, but not always). I don’t know about any particularly good resources for SQL injection (above and above what you can get from Google), so hopefully other answers might point to One True Tutorial!
source share