Пользовательский тип в GreenDao с классом POJO

Это мой образец JSON:

{  
   "open":true,
   "total_products":100,
   "product":[  
      {  
         "p_id":1,
         "price":"5.00",
         "name":"blah one"
      },
      {  
         "p_id":2,
         "price":"15.00",
         "name":"blah two"
      },
...
    ]
}

Это мой класс POJO:

@Entity(nameInDb = "products")
public class ProductsPOJO {

    @SerializedName("open")
    @Property(nameInDb = "open")
    private boolean open;

    @SerializedName("total_products")
    @Property(nameInDb = "total_products")
    private Long total_products;

    @Convert(converter = ProductConverter.class, columnType = String.class)
    @SerializedName("product")
    @Property(nameInDb = "product")
    private Product product;

    public static class productConverter implements PropertyConverter<Product, String> {
        //What shoudl I write in convert part?!
        @Override
        public Product convertToEntityProperty(String databaseValue) {
            if (databaseValue == null) {
                return null;
            }
            for (Product p : Product.values()) {
                if (p.id == databaseValue) {
                    return p;
                }
            }
            return Product.DEFAULT;
        }

        @Override
        public String convertToDatabaseValue(Product entityProperty) {
            return entityProperty == null ? null : entityProperty.;
        }
        //
        /*@Override
        public Product convertToEntityProperty(String databaseValue) {
        return Product.valueOf(databaseValue);
        }

        @Override
        public String convertToDatabaseValue(Product entityProperty) {
        return entityProperty.name();
        }*/
    }

    public static class Product{
        @Id
        @SerializedName("p_id")
        private Long p_id;

        @SerializedName("price")
        @Property(nameInDb = "price")
        private String price;

        @SerializedName("name")
        @Property(nameInDb = "name")
        private String name;

        //Getters & Setters
    }

    public Product getProduct() {
        return product;
    }

    public void setProduct(Product data) {
        this.product = product;
    }

    //open & total_products Getters & Setters
}

Но я не знаю, что мне написать для productConverter.
С другой стороны, поля в классе Product имеют несколько типов. String и Integer.
Я прочитал это: https://github.com/greenrobot/greenDAO/blob/V3.1.1/examples/DaoExample/src/main/java/org/greenrobot/greendao/пример/Note.java#L26-L27

http://greenrobot.org/greendao/documentation/custom-types/


person Dr.jacky    schedule 20.05.2017    source источник


Ответы (2)


EDIT: :/ Я также перепутал здесь две вещи, greenrobot objectbox и greendao... Извините за это, но ответ остается прежним, просто замените objectbox на greendao :)


По-моему тут вы что-то путаете с GSON и ObjectBox (GreenDao)

Вы, Json, похожи на ответ сервера. Но в вашей базе данных вы обычно просто хотите сохранить объекты продукта, а не ответ. Так что может быть лучше иметь только ServerResultPOJO для анализа вашего ответа с помощью GSON, например (нижеприведенный код не тестировался и, возможно, содержит незначительные ошибки, просто чтобы направить вас на правильный путь).

public class ServerResultPOJO {
    @SerializedName("open")
    private boolean open;

   @SerializedName("total_products")
   private Long total_products;

   @SerializedName("product")
   private List<Product> products;
}

Тогда ваш класс Prdouct может быть сущностью ObjectBox (GreenDao).

@Entity
public static class Product{
    @Id
    private long id;

    @Index
    @SerializedName("p_id")
    private Long p_id;

    @SerializedName("price")
    @Property(nameInDb = "price")
    private String price;

    @SerializedName("name")
    @Property(nameInDb = "name")
    private String name;

    //Getters & Setters
}

[Было бы лучше не использовать идентификатор сервера в качестве идентификатора объекта базы данных. Сохраните идентификатор и идентификатор сервера отдельно. Не будет путаницы с автоинкрементом и прочим.]

Тогда вам не нужны никакие конвертеры, просто некоторые методы, которые помещают все продукты из вашего ответа в базу данных. Перед добавлением нового объекта вы можете выполнить поиск p_id, чтобы проверить, нужно ли вам синхронизироваться с базой данных перед размещением.

Итак, сначала проанализируйте свой ответ, а затем выполните действия с базой данных.

Если вам действительно нужен ответ как объект базы данных, вам нужно отношение «один ко многим». Но тогда вы не можете использовать одни и те же классы для сущностей и анализа GSON, или вы работаете с некоторыми полями @transient, что значительно усложняет ситуацию.

person Mate    schedule 20.05.2017

Это было из-за

"GSON ожидал BEGIN_ARRAY, но был BEGIN_OBJECT"

Следует сделать что-то вроде этого:

JsonParser parser = new JsonParser();
JsonObject rootObject = parser.parse(JSON_STRING).getAsJsonObject();
//You can get the "open" and "total_products" here too.//
JsonElement productElement = rootObject.get("product");

Gson gson = new Gson();
List<Product> productList = new ArrayList<>();
//Check if "data" element is an array or an object and parse accordingly...
if (productElement.isJsonObject()) {
//The returned list has only 1 element
Product p = gson.fromJson(productElement, Product.class);
productList.add(p);
}
else if (productElement.isJsonArray()) {
//The returned list has >1 elements
Type productListType = new TypeToken<List<Product>>() {}.getType();
productList = gson.fromJson(productElement, productListType);
}

[Источник: https://stackoverflow.com/a/16656096/421467]

person Dr.jacky    schedule 20.05.2017