3

einfügen i Modell der Klasse der Stadt habe wie unten:wie Rekord in objektivieren Einheit mit einer Eins-zu-eins oder eins-zu-viele-Beziehung in android

@Entity 
public class City { 
    @Id 
    Long id; 
    String name; 
    public String getName() { 
     return name; 
    } 
    public void setName(String name) { 
     this.name = name; 
    } 

ich eine andere Modell Klasse Person habe unten angegeben:

@Entity 
public class Person { 
    @Id 
    Long id; 
    String name; 
    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 


    @ApiResourceProperty(ignored = AnnotationBoolean.TRUE) 
    Key<City> city; 
} 

Danach habe ich die Endpunkte sowohl für die Klasse mit android Studio generieren und bereitstellen.

hier ist der Code für die generierten Endpunkte:

PersonEndpoint

@Api(
     name = "personApi", 
     version = "v1", 
     resource = "person", 
     namespace = @ApiNamespace(
       ownerDomain = "backend.faceattendence.morpho.com", 
       ownerName = "backend.faceattendence.morpho.com", 
       packagePath = "" 
     ) 
) 
public class PersonEndpoint { 

    private static final Logger logger = Logger.getLogger(PersonEndpoint.class.getName()); 

    private static final int DEFAULT_LIST_LIMIT = 20; 

    static { 
     // Typically you would register this inside an OfyServive wrapper. See: https://code.google.com/p/objectify-appengine/wiki/BestPractices 
     ObjectifyService.register(Person.class); 
    } 

    /** 
    * Returns the {@link Person} with the corresponding ID. 
    * 
    * @param id the ID of the entity to be retrieved 
    * @return the entity with the corresponding ID 
    * @throws NotFoundException if there is no {@code Person} with the provided ID. 
    */ 
    @ApiMethod(
      name = "get", 
      path = "person/{id}", 
      httpMethod = ApiMethod.HttpMethod.GET) 
    public Person get(@Named("id") Long id) throws NotFoundException { 
     logger.info("Getting Person with ID: " + id); 
     Person person = ofy().load().type(Person.class).id(id).now(); 
     if (person == null) { 
      throw new NotFoundException("Could not find Person with ID: " + id); 
     } 
     return person; 
    } 

    /** 
    * Inserts a new {@code Person}. 
    */ 
    @ApiMethod(
      name = "insert", 
      path = "person", 
      httpMethod = ApiMethod.HttpMethod.POST) 
    public Person insert(Person person) { 
     // Typically in a RESTful API a POST does not have a known ID (assuming the ID is used in the resource path). 
     // You should validate that person.id has not been set. If the ID type is not supported by the 
     // Objectify ID generator, e.g. long or String, then you should generate the unique ID yourself prior to saving. 
     // 
     // If your client provides the ID then you should probably use PUT instead. 
     ofy().save().entity(person).now(); 
     logger.info("Created Person."); 

     return ofy().load().entity(person).now(); 
    } 

    /** 
    * Updates an existing {@code Person}. 
    * 
    * @param id  the ID of the entity to be updated 
    * @param person the desired state of the entity 
    * @return the updated version of the entity 
    * @throws NotFoundException if the {@code id} does not correspond to an existing 
    *       {@code Person} 
    */ 
    @ApiMethod(
      name = "update", 
      path = "person/{id}", 
      httpMethod = ApiMethod.HttpMethod.PUT) 
    public Person update(@Named("id") Long id, Person person) throws NotFoundException { 
     // TODO: You should validate your ID parameter against your resource's ID here. 
     checkExists(id); 
     ofy().save().entity(person).now(); 
     logger.info("Updated Person: " + person); 
     return ofy().load().entity(person).now(); 
    } 

    /** 
    * Deletes the specified {@code Person}. 
    * 
    * @param id the ID of the entity to delete 
    * @throws NotFoundException if the {@code id} does not correspond to an existing 
    *       {@code Person} 
    */ 
    @ApiMethod(
      name = "remove", 
      path = "person/{id}", 
      httpMethod = ApiMethod.HttpMethod.DELETE) 
    public void remove(@Named("id") Long id) throws NotFoundException { 
     checkExists(id); 
     ofy().delete().type(Person.class).id(id).now(); 
     logger.info("Deleted Person with ID: " + id); 
    } 

    /** 
    * List all entities. 
    * 
    * @param cursor used for pagination to determine which page to return 
    * @param limit the maximum number of entries to return 
    * @return a response that encapsulates the result list and the next page token/cursor 
    */ 
    @ApiMethod(
      name = "list", 
      path = "person", 
      httpMethod = ApiMethod.HttpMethod.GET) 
    public CollectionResponse<Person> list(@Nullable @Named("cursor") String cursor, @Nullable @Named("limit") Integer limit) { 
     limit = limit == null ? DEFAULT_LIST_LIMIT : limit; 
     Query<Person> query = ofy().load().type(Person.class).limit(limit); 
     if (cursor != null) { 
      query = query.startAt(Cursor.fromWebSafeString(cursor)); 
     } 
     QueryResultIterator<Person> queryIterator = query.iterator(); 
     List<Person> personList = new ArrayList<Person>(limit); 
     while (queryIterator.hasNext()) { 
      personList.add(queryIterator.next()); 
     } 
     return CollectionResponse.<Person>builder().setItems(personList).setNextPageToken(queryIterator.getCursor().toWebSafeString()).build(); 
    } 

    private void checkExists(Long id) throws NotFoundException { 
     try { 
      ofy().load().type(Person.class).id(id).safe(); 
     } catch (com.googlecode.objectify.NotFoundException e) { 
      throw new NotFoundException("Could not find Person with ID: " + id); 
     } 
    } 
} 

CityEndpoint

@Api(
     name = "cityApi", 
     version = "v1", 
     resource = "city", 
     namespace = @ApiNamespace(
       ownerDomain = "backend.faceattendence.morpho.com", 
       ownerName = "backend.faceattendence.morpho.com", 
       packagePath = "" 
     ) 
) 
public class CityEndpoint { 

    private static final Logger logger = Logger.getLogger(CityEndpoint.class.getName()); 

    private static final int DEFAULT_LIST_LIMIT = 20; 

    static { 
     // Typically you would register this inside an OfyServive wrapper. See: https://code.google.com/p/objectify-appengine/wiki/BestPractices 
     ObjectifyService.register(City.class); 
    } 

    /** 
    * Returns the {@link City} with the corresponding ID. 
    * 
    * @param id the ID of the entity to be retrieved 
    * @return the entity with the corresponding ID 
    * @throws NotFoundException if there is no {@code City} with the provided ID. 
    */ 
    @ApiMethod(
      name = "get", 
      path = "city/{id}", 
      httpMethod = ApiMethod.HttpMethod.GET) 
    public City get(@Named("id") Long id) throws NotFoundException { 
     logger.info("Getting City with ID: " + id); 
     City city = ofy().load().type(City.class).id(id).now(); 
     if (city == null) { 
      throw new NotFoundException("Could not find City with ID: " + id); 
     } 
     return city; 
    } 

    /** 
    * Inserts a new {@code City}. 
    */ 
    @ApiMethod(
      name = "insert", 
      path = "city", 
      httpMethod = ApiMethod.HttpMethod.POST) 
    public City insert(City city) { 
     // Typically in a RESTful API a POST does not have a known ID (assuming the ID is used in the resource path). 
     // You should validate that city.id has not been set. If the ID type is not supported by the 
     // Objectify ID generator, e.g. long or String, then you should generate the unique ID yourself prior to saving. 
     // 
     // If your client provides the ID then you should probably use PUT instead. 
     ofy().save().entity(city).now(); 
     logger.info("Created City."); 

     return ofy().load().entity(city).now(); 
    } 

    /** 
    * Updates an existing {@code City}. 
    * 
    * @param id the ID of the entity to be updated 
    * @param city the desired state of the entity 
    * @return the updated version of the entity 
    * @throws NotFoundException if the {@code id} does not correspond to an existing 
    *       {@code City} 
    */ 
    @ApiMethod(
      name = "update", 
      path = "city/{id}", 
      httpMethod = ApiMethod.HttpMethod.PUT) 
    public City update(@Named("id") Long id, City city) throws NotFoundException { 
     // TODO: You should validate your ID parameter against your resource's ID here. 
     checkExists(id); 
     ofy().save().entity(city).now(); 
     logger.info("Updated City: " + city); 
     return ofy().load().entity(city).now(); 
    } 

    /** 
    * Deletes the specified {@code City}. 
    * 
    * @param id the ID of the entity to delete 
    * @throws NotFoundException if the {@code id} does not correspond to an existing 
    *       {@code City} 
    */ 
    @ApiMethod(
      name = "remove", 
      path = "city/{id}", 
      httpMethod = ApiMethod.HttpMethod.DELETE) 
    public void remove(@Named("id") Long id) throws NotFoundException { 
     checkExists(id); 
     ofy().delete().type(City.class).id(id).now(); 
     logger.info("Deleted City with ID: " + id); 
    } 

    /** 
    * List all entities. 
    * 
    * @param cursor used for pagination to determine which page to return 
    * @param limit the maximum number of entries to return 
    * @return a response that encapsulates the result list and the next page token/cursor 
    */ 
    @ApiMethod(
      name = "list", 
      path = "city", 
      httpMethod = ApiMethod.HttpMethod.GET) 
    public CollectionResponse<City> list(@Nullable @Named("cursor") String cursor, @Nullable @Named("limit") Integer limit) { 
     limit = limit == null ? DEFAULT_LIST_LIMIT : limit; 
     Query<City> query = ofy().load().type(City.class).limit(limit); 
     if (cursor != null) { 
      query = query.startAt(Cursor.fromWebSafeString(cursor)); 
     } 
     QueryResultIterator<City> queryIterator = query.iterator(); 
     List<City> cityList = new ArrayList<City>(limit); 
     while (queryIterator.hasNext()) { 
      cityList.add(queryIterator.next()); 
     } 
     return CollectionResponse.<City>builder().setItems(cityList).setNextPageToken(queryIterator.getCursor().toWebSafeString()).build(); 
    } 

    private void checkExists(Long id) throws NotFoundException { 
     try { 
      ofy().load().type(City.class).id(id).safe(); 
     } catch (com.googlecode.objectify.NotFoundException e) { 
      throw new NotFoundException("Could not find City with ID: " + id); 
     } 
    } 
} 

I Beziehung zwischen Stadt machen wollen und Person, so dass viele Menschen können gehört zu einer Stadt. Fragen:

  1. Ist dies die richtige Modellierung der Klasse für diese Art von Beziehung? wenn nicht, bitte sagen Sie mir das korrekte Modell der Eins-zu-Eins und Eins-zu-viele-Beziehung

  2. Wie Sie Datensatz in den Datenspeicher für diese Art von Beziehung durch Java-Code (Endpunkte) und über API-Explorer einfügen?

  3. Benötigen Sie die Verwendung von @Parent Annotation oder @Index Annotation?

  4. Nach dem Erstellen dieser Beziehung, wenn ich eine Stadt lösche, müssen alle Personen, die zu dieser Stadt gehören, automatisch gelöscht werden. Kann diese Modellierung das erreichen? Bitte teilen Sie mir den Code für dies auch mit. wenn nicht, wie kann ich das durch Beziehung erreichen?

Antwort

1

Zunächst einmal lesen Sie die Diskussion mit objektivieren Gruppen auf untenstehenden Link passiert: how to insert record in objectify entity having one-to-one or one-to-many relationship in android So ist es eine bessere Möglichkeit, Ihre APIs auf der Basis von Schlüsseln zu gestalten (zB Web-Safe-Schlüssel) nicht auf der Grundlage auf ID, weil ID ist nicht eindeutig im Datenspeicher. so ich meine Person Modellklasse zu ändern:

@Entity 
public class Person { 
    @Id 
    Long id; 
    String name; 
    @Parent 
    @Index 
    @ApiResourceProperty(ignored = AnnotationBoolean.TRUE) 
    Key<City> city; 
    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public String getWebsafeKey() { 
     return Key.create(city.getKey(), Person.class, id).getString(); 
    } 

} 

die getWebsafeKey() gibt mir die websafe Schlüssel für die Person Klasse ihre Mutterinformation. Ich möchte diesen websicheren Schlüssel, damit ich gespeicherte Entity direkt abrufen kann, indem ich Schlüssel abfrage.

für City Modellklasse, da sie nicht Mutter getWebsafeKey hat() Methode wird wie folgt aussehen:

public String getWebsafeKey() { 
     return Key.create(City.class, id).getString(); 
    } 

Antwort der Frage 2: Einfügen Stadt wird in der Frage gleich sein, es bedeutet, ist keine Änderung in der Methode insert() des Endpunkts Stadt. Person in einer Stadt Einsetzen wie folgt aussehen wird:

@ApiMethod(
     name = "insert", 
     path = "city/{city_web_safe_key}/person", 
     httpMethod = ApiMethod.HttpMethod.POST) 
     public Person insert(@Named("city_web_safe_key") String cityWebSafeKey,Person person) { 
     Key<City> cityKey = Key.create(cityWebSafeKey); 
       person.city = Ref.create(cityKey); 
        ofy().save().entity(person).now(); 
        logger.info("Created Person."); 
        return ofy().load().entity(person).now(); 
       } 

Ebenso müssen Sie alle anderen @ApiMethod ändern, die „id“ Parameter auch, weil, wenn Sie automatisch die Endpunkte von Ihnen Modellklasse erzeugen alle @ApiMethod wird auf der Basis von "id", wie in der Frage gezeigt. Sie müssen den Parameter "id" durch "web safe key" ersetzen. das gleiche gilt für City Endpunkte Methode auch. Zum besseren Verständnis über Parameter sollten Sie [hier klicken] [2]

zum Beispiel erhalten Methode der Person Endpunkte aussehen wird:

@ApiMethod(
      name = "get", 
      path = "person/{person_websafe_key}", 
      httpMethod = ApiMethod.HttpMethod.GET) 
    public Site get(@Named("person_websafe_key") String personWSKey) throws NotFoundException { 
     logger.info("Getting person with WSkey: " + personWSKey); 
     Person person = (Person) ofy().load().key(Key.create(personWSKey)).now(); 
     if (person == null) { 
      throw new NotFoundException("Could not find person with WSKey: " + personWSKey); 
     } 
     return person; 
    } 

Antwort der Frage 4: Objectify nicht zwingen Entwickler zu einer solchen Art von Löschung. Es geht darum, welche Anforderungen Sie haben. Hier ist die Entfernungsmethode von Stadt, die auch die in der Stadt anwesende Person löscht.

@ApiMethod(
      name = "remove", 
      path = "city/{city_web_safe_key}", 
      httpMethod = ApiMethod.HttpMethod.DELETE) 
    public void remove(@Named("city_web_safe_key") String cityWSKey) throws NotFoundException { 
     Key<City> cityKey = Key.create(cityWSKey); 
     checkExists(cityKey); 
     //ofy().delete().key(cityKey).now(); 
     ofy().delete().keys(ofy().load().ancestor(cityKey).keys().list()); 

    } 

Antwort von Frage 1 und 3 bereits in oben Antwort abgedeckt für Detailwissen see documentation

+0

Zum besseren Verständnis über Parameter sollten Sie vist: https://cloud.google.com/appengine/docs/java/endpoints/parameter-and-return-types – Baqir

+0

würde Sie sind so nett, ein vollständiges einfaches Arbeitsbeispiel Ihres Codes zu zeigen? Ich erhalte 503 HTTP-Fehler und versuche, Ihren Ansatz zu wiederholen. – isabsent

+0

Code funktioniert gut in Android Studio, wenn Sie die Schritte folgen: Erstellen von Modellen, Erstellen von Endpunkten für diese Modelle, über Änderungen an den Endpunkten machen, Erstellen von Datastore-Indizes. xml für zusammengesetzte Indizes, und schließlich das Projekt auf App-Engine-Server, , jetzt können Sie eine Anfrage von APIs Explorer oder Sie aus Java-Code. – Baqir

3

Ich kann keine Fragen zu Google Endpoints beantworten, aber die Grundidee der Modellierung Person mit einem Schlüsselfeld zeigt auf City ist wahrscheinlich richtig - vorausgesetzt, es gibt viele, viele Menschen in eine Stadt. Sie möchten das Schlüsselfeld @Index ändern, um nach Personen in einer Stadt zu suchen. Beachten Sie, dass diese Abfrage letztendlich konsistent ist. Wenn Sie also viele Personen in einer Stadt hinzufügen/entfernen, sollten Sie eine Verzögerung zwischen dem Hinzufügen von Personen und dem Ausführen des Löschvorgangs einfügen.

Sie könnten dies modellieren, so dass Stadt das @Parent der Person ist. Dies würde die endgültige Konsistenz eliminieren, aber es würde bedeuten, dass Sie niemals eine Person in eine neue Stadt bewegen können. Es würde auch bedeuten, dass sich keine Stadt oder Person in dieser Stadt aufgrund des Transaktionsdurchsatzlimits einer einzelnen Unternehmensgruppe mehr als einmal pro Sekunde ändern kann. Angenommen, Sie sprechen tatsächlich über Personen und Städte, möchten Sie das wahrscheinlich nicht. Aber es hängt von Ihrem Datensatz ab.

+0

Eltern Anmerkung Verwendung gibt Fehler: Parameterized Typ com.googlecode.objectify.Key <{} Parent> nicht unterstützt – harrane

+0

danke für deinen Kommentar @stickfigure es wirklich mein Verständnis von Beziehung erhöht. Aber ich wollte die Antworten der oben genannten Fragen mit Endpunkten kennen – Baqir

Verwandte Themen