查询用户
问题描述:
寻找上进行身份验证时查询用户的一些反馈时JPA潜在的性能问题。我在编写下面的代码时首先想到的是通过查询数据库中的所有用户名并检查提供的用户名是否属于用户列表来获取用户名。当用户表增长时,这种类型的检查会成为性能问题吗?查询用户
EntityManager entityManager = factory.createEntityManager();
/*Create a data structure to hold a list of users in our database*/
List<String> allUsernames = new ArrayList<String>();
allUsernames = entityManager.createQuery("SELECT user.username FROM Users user").getResultList();
/*Loop through each user in our available usernames checking if the username passed exists*/
for (String user : allUsernames) {
if (user.equals(username)) {
System.out.println("Found real user\n");
userFoundFLAG = 1; // set the flag equal to 1 when this user is found
}
}
答
为什么不按名称查询用户?如果返回非零列表,则用户存在,否则不存在。更好的是,为什么不直接阅读整个用户对象呢?可以想象,您将需要它来获得额外的认证/授权逻辑?
final TypedQuery<String> query = entityManager
.createQuery("SELECT u.username FROM Users u WHERE u.username = :username", String.class);
query.setParameter("username", "BillyBob");
if (query.getResultList().size() > 0) {
// ...
}
或者:
final TypedQuery<User> query = entityManager
.createQuery("SELECT u FROM Users u WHERE u.username = :username");
query.setParameter("username", "BillyBob");
final User user = query.getFirstResult();
答
是的,这将是一个性能问题,成长为更大的问题,随着用户数量的增加。绝对不要这样做。
你应该这样做:
try {
User user = (User)entityManager.createQuery("SELECT user FROM Users user where user.username = :username")
.setParameter ("username", username);
.getSingleResult();
userFoundFLAG = 1;
} catch (NoResultException e) {
//There is no user with this username - do something
} catch (NonUniqueResultException e) {
//There is more than one user with this username - do something
}
+0
完美的达摩,我想在这里你的代码,它做它什么它应该。然而,我不得不改变你所捕捉的例外,因为它一直在失败。如果您使用Spring框架,您还必须捕获EmptyResultDataAccessException – Warz 2012-04-18 00:30:09
当我修改这个方法来查询用户名作为参数传递的用户对象,如果用户名不存在,它失败。查询结束返回一个空对象 – Warz 2012-04-18 00:00:06
你的第一个建议要求类型TypedQuery,因为它retruns您使用哪种方法查询 –
Warz
2012-04-18 00:06:47
的投?如果第二个则需要准备处理EntityNotFoundException(如果数据库中没有相应的记录,则会发生这种情况)。 – Perception 2012-04-18 00:07:14