按ID以外的属性获取实体

时间:2014-07-09 00:10:13

标签: java google-app-engine google-cloud-datastore google-cloud-endpoints

我是Endpoints的新手,我正在尝试通过id以外的属性查询实体。具体来说,我有一个User.java和一个UserEndpoints.java类,并希望能够根据'email'属性返回单个记录。当我传入特定记录的ID时,我能够将结果返回给调用异步任务的Activity,所以我知道数据流正常。我是否需要创建一个名为getUserByEmail的端点?我是否需要以某种方式修改getUser函数?

UserEndpoint.java

@Api(name = "userendpoint")
public class UserEndpoint {
/**
 * This method lists all the entities inserted in datastore. It uses HTTP
 * GET method and paging support.
 * 
 * @return A CollectionResponse class containing the list of all entities
 *         persisted and a cursor to the next page.
 */
@SuppressWarnings({ "unchecked", "unused" })
@ApiMethod(name = "listUser")
public CollectionResponse<User> listUser(
        @Nullable @Named("cursor") String cursorString,
        @Nullable @Named("limit") Integer limit) {

    EntityManager mgr = null;
    Cursor cursor = null;
    List<User> execute = null;

    try {
        mgr = getEntityManager();
        Query query = mgr.createQuery("select from User as User");
        if (cursorString != null && cursorString != "") {
            cursor = Cursor.fromWebSafeString(cursorString);
            query.setHint(JPACursorHelper.CURSOR_HINT, cursor);
        }

        if (limit != null) {
            query.setFirstResult(0);
            query.setMaxResults(limit);
        }

        execute = (List<User>) query.getResultList();
        cursor = JPACursorHelper.getCursor(execute);
        if (cursor != null)
            cursorString = cursor.toWebSafeString();

        // Tight loop for fetching all entities from datastore and
        // accomodate
        // for lazy fetch.
        for (User obj : execute)
            ;
    } finally {
        mgr.close();
    }

    return CollectionResponse.<User> builder().setItems(execute)
            .setNextPageToken(cursorString).build();
}

/**
 * This method gets the entity having primary key id. It uses HTTP GET
 * method.
 * 
 * @param id
 *            the primary key of the java bean.
 * @return The entity with primary key id.
 */
@ApiMethod(name = "getUser")
public User getUser(@Named("id") Long id) {
    EntityManager mgr = getEntityManager();
    User user = null;
    try {
        user = mgr.find(User.class, id);
    } finally {
        mgr.close();
    }
    return user;
}

/**
 * This inserts a new entity into App Engine datastore. If the entity
 * already exists in the datastore, an exception is thrown. It uses HTTP
 * POST method.
 * 
 * @param user
 *            the entity to be inserted.
 * @return The inserted entity.
 */
@ApiMethod(name = "insertUser")
public User insertUser(User user) {
    EntityManager mgr = getEntityManager();
    try {
        if (containsUser(user)) {
            throw new EntityExistsException("Object already exists");
        }
        mgr.persist(user);
    } finally {
        mgr.close();
    }
    return user;
}

/**
 * This method is used for updating an existing entity. If the entity does
 * not exist in the datastore, an exception is thrown. It uses HTTP PUT
 * method.
 * 
 * @param user
 *            the entity to be updated.
 * @return The updated entity.
 */
@ApiMethod(name = "updateUser")
public User updateUser(User user) {
    EntityManager mgr = getEntityManager();
    try {
        if (!containsUser(user)) {
            throw new EntityNotFoundException("Object does not exist");
        }
        mgr.persist(user);
    } finally {
        mgr.close();
    }
    return user;
}

/**
 * This method removes the entity with primary key id. It uses HTTP DELETE
 * method.
 * 
 * @param id
 *            the primary key of the entity to be deleted.
 */
@ApiMethod(name = "removeUser")
public void removeUser(@Named("id") Long id) {
    EntityManager mgr = getEntityManager();
    try {
        User user = mgr.find(User.class, id);
        mgr.remove(user);
    } finally {
        mgr.close();
    }
}

private boolean containsUser(User user) {
    EntityManager mgr = getEntityManager();
    boolean contains = true;
    if (user.getKey() == null)
        return false;
    try {
        User item = mgr.find(User.class, user.getKey());
        if (item == null) {
            contains = false;
        }
    } finally {
        mgr.close();
    }
    return contains;
}

private static EntityManager getEntityManager() {
    return EMF.get().createEntityManager();
}
}

User.java

@Entity
public class User {
/*
 * Autogenerated primary key
 */
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Key key;
private String email;
private String password;
private String gender;
private Date birthdate;

public Key getKey() {
    return key;
}

public void setKey(Key key) {
    this.key = key;
}

public String getEmail() {
    return email;
}

public void setEmail(String email) {
    this.email = email;
}

public String getPassword() {
    return password;
}

public void setPassword(String password) {
    this.password = password;
}

public String getGender() {
    return gender;
}

public void setGender(String gender) {
    this.gender = gender;
}

public Date getBirthdate() {
    return birthdate;
}

public void setBirthdate(Date birthdate) {
    this.birthdate = birthdate;
}
}

2 个答案:

答案 0 :(得分:0)

由于数据存储区为您创建单索引,因此这样的事情应该起作用

User user = mgr.findFirst(User.class, ,"email", email);

提示:如果您还想确保电子邮件是唯一的,并且不会为用户更改,请将其设为ID。

答案 1 :(得分:0)

这就是我最终解决这个问题的方法:

/**
 * This method gets the first entity having email. It uses HTTP GET
 * method.
 * 
 * @param email
 *            
 * @return The entity with email.
 */
@ApiMethod(name = "getUserByEmail", path="getUserByEmail")
public User getUserByEmail(@Named("email") String email) {
    EntityManager mgr = getEntityManager();
    User user = null;
    try {
        //Query query = mgr.createQuery("SELECT u FROM User u WHERE u.email = '" + email + "'");
        Query query = mgr.createQuery("SELECT FROM User u WHERE u.email = :email");
        query.setParameter("email", email);
        user = (User) query.getSingleResult();
    } finally {
        mgr.close();
    }
    return user;
}