I have the following SQL string:
SELECT fm.*,
u.username AS friend_username
FROM friend_messages fm
JOIN users u ON
(u.id = fm.sender_id AND fm.sender_id = :friendId)
OR
(u.id = fm.receiver_id AND fm.receiver_id = :friendId)
WHERE
(fm.sender_id = :userId AND fm.receiver_id = :friendId)
OR
(fm.sender_id = :friendId AND fm.receiver_id = :userId)
ORDER BY fm.created_at ASC
As you can see, I need to replace :userId
and :friendId
with ?
before I execute the SQL string using JdbcTemplate
. Usually when I do that, I do something like this:
String serverQuery = "SELECT sm.id AS message_id, sm.server_id, sm.sender_id, u.username AS sender_username, sm.content, sm.created_at FROM server_messages sm JOIN users u ON sm.sender_id = u.id WHERE sm.server_id = ? ORDER BY sm.created_at ASC";
List<ServerMessageDTO> collection = this.db.query(serverQuery, new ServerMessageRowMapper(), serverId);
The issue here is that the SQL string is more complicated and I am not sure how am I supposed to pass the userId once and apply it to 2 places.
I have variables int friendId = 2
and int userId = 4
. I tried doing something like this:
SELECT fm.*,
u.username AS friend_username
FROM friend_messages fm
JOIN users u ON
(u.id = fm.sender_id AND fm.sender_id = ?)
OR
(u.id = fm.receiver_id AND fm.receiver_id = ?)
WHERE
(fm.sender_id = ? AND fm.receiver_id = ?)
OR
(fm.sender_id = ? AND fm.receiver_id = ?)
ORDER BY fm.created_at ASC
List<FriendMessageDTO> collection = this.db.query(serverQuery, new FriendMessageRowMapper(), friendId, friendId , userId, friendId, friendId, userId);
Is there a more intuitive way to achieve this?
This is exactly what the NamedParameterJdbcTemplate
was created for:
String sql = ...;
NamedParameterJdbcTemplate template = new NamedParameterJdbcTemplate(dataSource);
Map<String, String> params = Map.of("friendId", "2", "userId", "4");
List<FriendMessageDTO> collection =
template.query(sql, params, new FriendMessageRowMapper());