My model is like:
public class MyModel{
private String mId;
private String mName;
T mAnObject;
}
How can I store T object in database.
If you need to save specific properties, just do that, otherwise you could serialize it to JSON, as an option (as demonstrated here).
Example:
Object myObj has three properties: String title, String subtitle, String text
1 - You can save them as separate database rows and then when you read from the database you recombine them to create your Object.
2 - You can also use Json to save the properties, this way you only need to store a single String in the database and when you read from the database convert the Json String to your Object.
Related
I have an app that stores lots of data to work offline as well.
I have three classes, in a hierarchy like;
public class MainGroup
{
private UUID Oid;
private String name;
private Date CreatedOn;
}
-
public class Group
{
private UUID Oid;
private String name;
private Date CreatedOn;
private MainGruop MainGroup;
}
-
public class Product
{
private UUID Oid;
private String name;
private Date CreatedOn;
private MainGruop MainGroup;
private Group Group;
}
( Oid fields are selected as PrimaryKey with realm attribute. )
Let's say, all MainGroup objects were stored in Realm DB. Then, when i'm trying to insert Group objects, with nested MainGroup object but with only its Oid field to link its master, Realm updates the MainProduct record (with given Oid), and clear the other fields as nulls.
In same way, when i'm inserting Product objects and nested objects are includes only Oid, realm updates all fields with nulls.
So, there are more complex and deeply related objects and when i make a request to get JSON from server, i must produce a very big JSON response to keep data.
And mention to insert method; I'm creating java objects with JSON response via GSON and i'm using Realm.copyToRealmOrUpdate(obj); method to insert.
To reduce payload (JSON size, serialize and insertion process), i need to find a way to fix this issue.
Basically, there are two things I don't understand: objects with objects and objects with lists of objects
Say I receive a list of objects from the server. Each of them looks like this:
#Entity
public class BigObject {
#PrimaryKey
private int id;
private User user;
private List<SmallObject> smallObjects;
}
with these two objects as fields:
#Entity
public class User {
#PrimaryKey
private int id;
private String name;
#TypeConverters(GenderConverter.class)
public MyEnums.Gender gender;
}
#Entity
public class SmallObject {
#PrimaryKey (autoGenerate = true)
private int id;
private String smallValue;
}
They are more complicated than this, so I can't use #TypeConverters as Room suggests:
error: Cannot figure out how to save this field into database. You can consider adding a type converter for it.
How do I store this data structure in Room?
I think the best way to answer this is a breif overview in storing structures...
Lists
Room does not support storing lists that are nested inside of a POJO. The recommended way to store lists is to use the foreign key approach. Store the List of objects in a seperate table (in this case a smallObjects table) with a foreign key to their related parent object (in this case "big_object_id"). It should look something like this...
#Entity
public class BigObject {
#PrimaryKey
private int id;
private User user;
#Ignore
private List<SmallObject> smallObjects;
}
#Entity(foreignKeys = {
#ForeignKey(
entity = BigObject.class,
parentColumns = "id",
childColumns = "big_object_fk"
)})
public class SmallObject {
#PrimaryKey (autoGenerate = true)
private int id;
private String smallValue;
#ColumnInfo(name = "big_object_fk")
private int bigObjectIdFk
}
Note that we have added the #Ignore annotaiton to List<SmallObject> as we want to ignore the field during Room persistance (as lists are not supported). It now exists so that when we request our list of related small objects from the DB we can still store them in the POJO.
To my knowledge this will mean you are making two queries.
BigObject b = db.BigObjectDao.findById(bOId);
List<SmallObject> s = db.smallObjectDao.findAllSOforBO(bOId);
b.setsmallObjects(s);
It appears that there is a short hand for this in the form of #Relation
Type Converters
These are for cases where you have a complex data structure that can be flattend without losing information, and stored in a single column. A good example of this is the Date object. A Date object is complex and holds a lot of values, so storing it in the database is tricky. We use a type converter to extract the milli representation of a date object and store that. We then convert the millis to a date object on the way out thus keeping our data intact.
Embedded
This is used when you want to take the fields of all nested POJOs in your parent POJO and flatten them out to store in one table. an example :
- name
- age
- location
- x
- y
- DOB
..when embedded this structure would be stored in the database as :
- name
- age
- location_x
- location_y
- DOB
In a sense Embedded exists to save you time creating type converters for every nested object that contains primary type fields like String, int, float, etc...
Convert Object/List<Object> to String and then, Store it.
You can store the objects in Room Library as String. For that, you can serialize the object and store it as String in the Room Database.
Store to Room
Object -> Serialize -> String -> Store
Read from Room
String -> Deserialize ->Object -> Read
How to Serialize/Deserialize?
There are many options available. You can either do it manually or you can use a library for this. You can use Google's GSON library. It is pretty easy to use.
Code: Object -> String
public String stringFromObject(List<YourClass> list){
Gson gson = new Gson();
String jsonString = gson.toJson(list);
return jsonString;
}
Code: String-> Object
public List<YourClass> getObjectFromString(String jsonString){
Type listType = new TypeToken<ArrayList<YourClass>>(){}.getType();
List<YourClass> list = new Gson().fromJson(jsonString, listType);
return list;
}
how to create table for a custom object that contain a list of like this
public class Mobel implements Parcelable {
int thumbnail;
List<Integer> pics;
int price;
String joziat;
String code;
}
as you know there is no problem with int and string columns but how should i store my list of integer ? i was thinking to make a separate table for it but as i don't know ho many pic i have for particular object have no idea how should i join them
While indeed you can not store objects in sqlite, you can serialize it and store the serialized object:
Gson gson = new Gson();
String toStoreObject = gson.toJson(modelObject, Model.class);
And when you get the string back just do:
Model modelObject = gson.fromJson(storedObjectString, Model.class);
Or just serialize the property of the object (in your case the List).
Different things I would do:
Create another table for the images and link that table to the table in which you store your Model object (n to 1 relationship)
Don't store images in sqlite. Store them in the internal storage and in sqlite save just the path to the file.
If you really really want to store the images in sqlite, convert the image to a base64 string and store that one.
Is it possible to save a data retrieved from the database into a string?
For my case I want to save the TAG_NAME which is a data from the database into a string. Can I do it the same way as done for the Textview?
// display product data in EditText
txtwelcome.setText(product.getString(TAG_NAME));
String name = (product.getString(TAG_NAME));
Its absolutely possible,as product.getString(TAG_NAME) always returns a string either empty or with value,you can store it in a String.
And even you can store any value from DB into String using .toString() extension
try with the toString()
String name = (product.getString(TAG_NAME).toString());
I am working on Android platform. I am using POJO class to create the Sqlite DB field names.
e.x.
class Provider {
int id;
String data;
String value;
}
Based on the above POJO class, 3 fields with the given name will be generated at SQlite DB.But i want to create the name of fields(Column) different name into Sqlite DB.
e.x.
class Provider {
#Annotation(FieldNameInDB = loginId)
int id;
#Annotation(FieldNameInDB = providerData)
String data;
#Annotation(FieldNameInDB = providerValue)
String value;
}
Above POJO class having annotation and also the column names has been given using annotation, whatever the names being used needs to be created as column names (loginId,providerData,providerValue).
So, SQLite DB will have 3 columns named as (loginId,providerData,providerValue).
Please provide solution using Java Annotation to create Custom Column names into SQLite DB and using custom names, we can retrieve the values from it.
Try it out:
#DatabaseField(columnName="providerData")
private String data;