Reputation: 3632
I have a Spring Mvc application, in registration form i have an area for email and name
Before registering i check that all fields are unique in the DB with the following code in service layer (I'm using spring data
)
@Override
public Optional<String> isUnuque(final Users user) {
if (this.repository.findByEmail(user.getEmail()) != null) {
return Optional.of("Your email is not unique");
} else if (this.repository.findByName(user.getName()) != null) {
return Optional.of("Your name is not unique");
}
return Optional.empty();
}
Then in controller i check if Optional is present. But with this code i make 2 requests to the DB, i can use native query like this to make only one request:
select * from users where name = 'dd' or email = '[email protected]'
But how would i know which parameter is not unique name or email?
Thank in advance
BTW i solved this problem with the following code
@Override
public Optional<String> isUnuque(final Users user) {
final Users dbUser = this.repository.findByEmailOrName(user.getEmail(), user.getName());
if (dbUser != null) {
if (user.getEmail().equals(dbUser.getEmail())) {
return Optional.of("Not unique email");
} else {
return Optional.of("Not unique name");
}
}
return Optional.empty();
}
But if there are any sql query that can do exactly what i want without double checking in service layer please write it below
Upvotes: 0
Views: 74
Reputation: 31676
I'm not a java expert but as a database guy, I would say a better way would be to enforce the UNIQUE
constraint on name
and email
in the table and handle the exception, which maintains the data integrity regardless of the application.
Another option is to get the count of emails and names with the given arguments.
SELECT count(CASE
WHEN name = :p_name
THEN 1
END) AS name_count
,count(CASE
WHEN email = :p_email
THEN 1
END) AS email_count
FROM users;
The COUNT
function does not count nulls, so when condition in CASE
is false( by default NULL
), it adds 0 to the count. So, effectively the query would return name_count
and email_count
as 0 or 1 depending on the existing value, which you should be able to use in your code.
Upvotes: 1
Reputation: 767
Union All can do this.
select 'name' from users where name = 'dd'
union all
select 'email' from users where name = 'ddd'@mail.ru
Upvotes: 0