I tried researching about this but couldn’t find any answer probably because I don’t really know how to tell what I’m looking for properly.
I am using JDBC driver of Java to create a PreparedStatement for Postgresql.
I have a table listings
with columns like listing_title
, listing_desription
, listing_location
etc.
I am working on a findListings() method that will work with varied filters, declared with variables like String title
, String description
etc. Those variables might be null
and in those cases I don’t want to use filter for those rows in the sql statement.
For this, I right now have a very long spagetti of if-else statements that check for filters continously to put WHERE .... = ...
and AND
statements and concatenate strings to get a statement.
I wonder if there is an easier way, a way like putting all possible filters to the statement beforehand and not using them with a keyword like ANY
(I know ANY keyword doesnt help, just using it as an example in this case)
A possible statement would be: SELECT * FROM listings WHERE listing_title = 'title', listing description = ANY, ORDER BY ANY
Is there a keyword for this? Thanks a lot
I used many if else statements to concatenate strings to make the statement, I am looking for an easier to do way.
2
Answers
String concatenation to build SQL query is not a good solution. You are correct. Instead you can use IS NULL check for every of your filtering attribute in SQL call.
This SQL call will check if filter parameters values provided (title_param, description_param) and if they not (they are null in this case) then it will not use them as a filtering condition.
Java code would look something like:
Note PreparedStatement used here, but not popular-used Statement. This makes the code to be safe against SQL injection attacks. Also note building SQL queries with String concatenation is usually bad practice as it leads to bloated code, which way harder to test.
As I said in the comments, ‘filter some db rows’ is way more complicated than exact string matches. You may want to filter on specifically ‘anything in the year X’, matching X against a TIMESTAMP column. Or ‘anything where the name STARTS WITH "foo"’, and so on.
So, first, we abstract the notion of ‘the nature of the value I want to filter on’:
You can think of tens of other ones – regexp match, string-starts-with,
and so on. Writing these should be fairly simple here.
Next, we write a system that turns a map of column-to-filtervalue and makes a query out of it:
You’re now writing a little library which will soon balloon into a much bigger library, and at some point you’re going to regret not just going with an existing solution that did all this – look into JOOQ or JDBI which do lots of this stuff for you and more.