简体   繁体   中英

Get Entity by Attribute other than ID

I am new to Endpoints and am trying to query an Entity by an attribute other than id. Specifically, I have a User.java and a UserEndpoints.java class and would like to be able to return a single record based on the 'email' attribute. I am able to get a result returned to the Activity which calls the asynchronous task when I pass in the ID of a specific record, so I know that the data flows fine. Do I need to create an endpoint called something like getUserByEmail? Do I need to modify the getUser function somehow?

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;
}
}

Since Datastore creates single-indexes for you, something like this should work

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

Tip: If you also want to ensure that email is unique and if it will not change for a user, make it the id.

This is how I ended up working this out:

/**
 * 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;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM