Also, if you want to avoid case-insensitive differences, you might consider "lower(userID) = lower(?)". Granted, some databases can be configured to always perform case insensitive matching.
One issue with unique usernames is that even if you check ahead of time, a race condition could have two users creating the same record at the same time. It doesn't mean you shouldn't check ahead of time,
you should always avoid throwing exceptions if they can be solved through application logic, but you should always have a pathway that handles when the database throws a uniqueness violation even after checking ahead of time.