I'm creating my first data enabled app but am struggling with the last part - actually adding and retrieving the data. For now I am only concerned with adding data to the table. Following this tutorial I have created model classes for my tables and a DBHelper class with all my CRUD methods (I can post all these if required but not sure they are necessary to answer this question. Please correct me if I am wrong!). Unfortunately the tutorial ends here and doesn't go into detail on how to pass the data from the UI of the app into the DB.
After some Google searches I have found an example of how to pass some data to these methods but only how to pass one piece of data at a time, so only really useful if my table has just one field - mine has more than one.
For example, if I have a a table for "Todo" tasks, in my dbhelper my create method may be;
public void createTodo(String todoText) {
ContentValues contentValues = new ContentValues();
contentValues.put("todo", todoText);
// Insert into DB
db.insert("todos", null, contentValues);
}
so from my activity I just need
dao.createTodo(todoTextValue);
For my app I will be adding more than one field at a time, so my create method looks like this;
public long createSite(Site site){
SQLiteDatabase database = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_SITE_NAME, site.getSiteName());
values.put(KEY_SITE_LAT, site.getSiteLat());
values.put(KEY_SITE_LON, site.getSiteLon());
values.put(KEY_CREATED_AT, site.getSiteCreatedDateTime());
// Insert Row
long siteid = database.insert(TABLE_SITES, null, values);
So my question really is how I can pass all the different bits of data to the createSite method.
I don't know if this really needs an answer, but well here's a code...
Assuming your Site class is like this.
public class Site {
private String siteName;
private double siteLat;
private double siteLon;
private Date siteCreatedDateTime;
// getters and setters here
}
You then pass the data from your EditText value to your new Site object. It will look like this in your activity.
EditText siteNameInput = (EditText) findViewById(R.id.siteNameInput);
EditText siteLatInput = (EditText) findViewById(R.id.siteLatInput);
EditText siteLonInput = (EditText) findViewById(R.id.siteLonInput);
EditText siteCreatedDateTimeInput = (EditText) findViewById(R.id.siteCreatedDateTimeInput);
String siteName = siteNameInput.getText().toString();
String siteLat = siteLatInput.getText().toString();
String siteLon = siteLonInput.getText().toString();
String siteCreatedDateTime= siteCreatedDateTimeInput.getText().toString();
Site site = new Site();
site.setSiteName(siteName);
site.setSiteLat(siteLat);
site.setSiteLon(siteLon);
site.setSiteCreatedDateTime(siteCreatedDateTime);
dao.createSite(site);
Hope this helps you... You can learn more on Object-Oriented programming in Java here
public long createSite(Model site,String name, String address){
SQLiteDatabase database = this.getWritableDatabase();
ContentValues values = new ContentValues();
values.put(KEY_NAME, site.name);
values.put(KEY_ADDRESS, site.address);
// Insert Row
long siteid = database.insert(TABLE_SITES, null, values);
to add elements to the class you just add
public class Model {
String name;
String address;
//add year as many as you need
Model(String name, String address){
this.name=name;
this.address=address;
}
}
And in you activity you call this
In java to add a new object in this case Model
Model x = new Model("josh","Ireland");
and you just pass to
dao.createTodo(x);
Todo and Site are models. Each variable represents a column of that table. You need to create a custom model for each of your tables. The createSite method takes an object of type Site and adds it as a row in the TABLE_SITES in the DB. values.put(...)takes columnName, value. So here you give your own column names and values.
Instead of getting into all this I suggest you use an orm like active android:
http://www.activeandroid.com/
Related
Pretty simple question, assuming I've got the model for a row in a table, I'd like to get the insert statement necessary to create that row.
List<MyModel> updatedRows = new Select()
.from(MyDatabase.getMyModels().get(table))
.where(Condition.column(NameAlias.builder("id").build())
.in(new Select(UpdatedRecord$Table.updated_record_id)
.from(UpdatedRecord.class)
.where(UpdatedRecord$Table.updated_table.eq(table))))
.queryList();
StringBuilder updateStatements = new StringBuilder();
for (MyModel tableModel : updatedRows) {
// this is the insert statement, but there's no way to get it as a string
tableModel.getModelAdapter().getInsertStatement();
updateStatements.append(insertSqlStatementString);
}
tableModel.getModelAdapter().getInsertStatement() properly returns the insert statement, however, it is in the form of a DatabaseStatement, and I can't find any documentation for that class. I want the insert statement as a string.
Looking at that line in the debugger shows that underneath it there is a Statement and inside of that, mSQL which holds the string.
Can anyone help me out or point me in the right direction?
Tried this to no avail:
String tableCreateStatement = tableModel.getModelAdapter().getCreationQuery();
DatabaseStatement dbSt = tableModel.getModelAdapter().getCompiledStatement();
tableModel.getModelAdapter().bindToInsertStatement(dbSt, tableModel);
AndroidDatabaseStatement a = (AndroidDatabaseStatement)dbSt;
String p = a.getStatement().toString();
Here's what I ended up using after the main contributor to DBFlow responded to my question here:
// BaseModel row;
ContentValues values = new ContentValues();
row.getModelAdapter().bindToInsertValues(values, row);
String query = SQLite.insert(row.getClass()).columnValues(values).getQuery();
I have an app that inserts data into a database with 2 tables (project and alvara)
The insertion method for the second table depends on what type the first table gets. (1 or 2) for resumed idea.
This is a method that I made for looking into the second table with cursor. If it finds, it sets in setters from alvara_db class. And later on, I use getters to show info on textviews in another activity. The issue is that it's not setting info at all. Is anything wrong in my Cursor?
Thanks in advance!
public ArrayList<alvara_db> getAlvaras(){
SQLiteDatabase db = this.getReadableDatabase();
ArrayList<alvara_db> projects = new ArrayList<>();
String[] project = new String[]{String.valueOf(tipoprojetoid)};
Cursor cur = db.rawQuery("SELECT placa, proj_exec, resp_tec, rtnum, parecer FROM alvara WHERE projetoid = ?", project);
cur.moveToFirst();
alvara_db alvaras = new alvara_db();
alvaras.setPlaca(cur.getInt(cur.getColumnIndex("placa")));
alvaras.setProj_exec(cur.getInt(cur.getColumnIndex("proj_exec")));
alvaras.setResp_tec(cur.getString(cur.getColumnIndex("resp_tec")));
alvaras.setRtnum(cur.getInt(cur.getColumnIndex("rtnum")));
alvaras.setParecer(cur.getString(cur.getColumnIndex("parecer")));
projects.add(alvaras);
return projects;
}
Fragment where I call getAlvaras method:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.detalhes_projeto_alvara);
db.getAlvaras();
placa = alvaras.getPlaca();
resp_tec = alvaras.getResp_tec();
proj_exec = alvaras.getProj_exec();
rtnum = alvaras.getRtnum();
}
You are not using the returned value from db.getAlvaras().
Instead the alvaras variable in your second snippet is something that is likely not initialized - the code you posted does not show that exactly.
(In addition, you might want to check the return value of moveToFirst() in case the query matches no rows, and add a do-while loop to retrieve more than one row.)
I'm trying to pass a string from Mainactivity to the databaseadapter class to update the column one with a string (as its designated with string instead of int) in sqlite but realize that db.update() only works with int.
a) In mainactivity, for int
Integer jacky = 78;
myDb.updateK(jacky);
b) In mainactivity, for String
String jackie = "jacko";
myDb.updateK(jackie);
In databaseadapter
String cup = "_id = 1";
//since jack doesn't have to be jacky or jackie, and can be mary
public void updateK(int mary){
ContentValues tree = new ContentValues();
tree.put("columnone", mary);
db.update("TableOne", tree, cup, null);
}
In the case above, only case a) works when using an int whereas case b) using a string jacko, does not work. Is there a way to work around this and pass the string from mainactivity to databaseadapter?
As you probably can tell, I'm new to android and I appreciate any pointers you guys can give me.
a) In mainactivity, for int
Integer jacky = 78;
myDb.updateK(jacky);
b) In mainactivity, for String
String jackie = "jacko";
myDb.updateK(jackie);
In databaseadapter
String cup = "_id = 1";
//since jack doesn't have to be jacky or jackie, and can be mary
public void updateK(Object mary){
ContentValues tree = new ContentValues();
tree.put("columnone", mary);
db.update("TableOne", tree, cup, null);
}
NOTE : Your tree should also accept objects
"columnone" should be a column name of table "TableOne". Verify the type of that column (you should define column data type when define your table). According to your question it should be a INTEGER type. If so you can change its type to TEXT then you have to change the case a) as follows.
myDb.updateK(String.valueof(jacky));
I m working on an e-learning type of an application where i retrieve the data from the database on list.
It works fine on the emulator,but when i use the APK file of that app on real device,it does not show any data on list, my database is stored in the windows-file explorer-package-data-database-table_name.
I am referring to this site
http://anujarosha.wordpress.com/2011/12/19/how-to-retrieve-data-from-a-sqlite-database-in-android/
Here's a snippet of my code using database
list_adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, namelist1());
list1.setAdapter(list_adapter);
}
public List<String> namelist1()
{
// We have to return a List which contains only String values. Lets create a List first
List<String> namelist= new ArrayList<String>();
// First we need to make contact with the database we have created using the DbHelper class
Database_helper_class open_database_helper= new Database_helper_class(this);
// Then we need to get a readable database
SQLiteDatabase sqlitedatabase = open_database_helper.getReadableDatabase();
// We need a a guy to read the database query. Cursor interface will do it for us
//(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy)
Cursor cursor =sqlitedatabase.query(open_database_helper.TABLE_E_LEARNING,null,null,null,null,null,null);
//above query is read all the database column
// Cursor object read all the fields. So we make sure to check it will not miss any by looping through a while loop
while(cursor.moveToNext()){
String str_name = cursor.getString(cursor.getColumnIndex(Database_helper_class.QUES_COLUMN));
String str_id = cursor.getString(cursor.getColumnIndex(Database_helper_class.ANS_COLUMN));
//double str_gpa = cursor.getDouble(cursor.getColumnIndex(Database_helper_class.GPA_COLUMN));
// Finish reading one raw, now we have to pass them to the POJO
nameclass nameclassobj1=new nameclass();
nameclassobj1.setname(str_name);
nameclassobj1.setid(str_id);
//nameclassobj1.setgpa(str_gpa);
// Lets pass that POJO to our ArrayList which contains undergraduates as type
pojo_namelist.add(nameclassobj1);
// But we need a List of String to display in the ListView also.
//That is why we create "nameList"
namelist.add(str_name);
}
sqlitedatabase.close();
sqlitedatabase.query() returns a cursor which is positioned before the first record. make sure to call moveToFirst() before trying to access any data from it.
verify your database path in DBHelper.class. And after that Write below line before you call while loop.
cursor.moveToFirst();
This will point to your first record and then your while loop will work.
Try it like this:
// Cursor object read all the fields. So we make sure to check it will not miss any by looping through a while loop
cursor.moveToFirst();
while(!cursor.isAfterLast()){
String str_name = cursor.getString(cursor.getColumnIndex(Database_helper_class.QUES_COLUMN));
String str_id = cursor.getString(cursor.getColumnIndex(Database_helper_class.ANS_COLUMN));
//double str_gpa = cursor.getDouble(cursor.getColumnIndex(Database_helper_class.GPA_COLUMN));
// Finish reading one raw, now we have to pass them to the POJO
nameclass nameclassobj1=new nameclass();
nameclassobj1.setname(str_name);
nameclassobj1.setid(str_id);
//nameclassobj1.setgpa(str_gpa);
// Lets pass that POJO to our ArrayList which contains undergraduates as type
pojo_namelist.add(nameclassobj1);
// But we need a List of String to display in the ListView also.
//That is why we create "nameList"
namelist.add(str_name);
}
Use the isAfterLast()-method to check, if your reached the end of your cursor.
Sorry for late reply, got busy in other application
Actually the data was not saved in the database, that is why i was not getting it on device.
It works now.
I've executed some queries on my SQLite DB on Android.
Main instruction used is this:
Cursor cursor = myDB.rawQuery(select, null);
Now I want the results of this query to be converted to a generic class I've created in the project. If you think I want an ORM system, you are right, but all I've found now are ORM systems that want to query the DB, save objects in the DB and manage the DB itself.
Instead now I need a 'simple' ORM feature that can do exactly what the google.gson library does with JSON strings, it converts JSON strings to custom objects, and I want the same but for converting SQLite cursors to my Classes.
Any suggestion how to do this?
I don't think there is an automated way to do this. Just populate the object yourself. For example, if your cursor was just an id and a name and you wanted to create a Person object:
Person populatePerson(Cursor cursor)
{
try
{
int idIndex = cursor.getColumnIndexOrThrow("_id");
int nameIndex = cursor.getColumnIndexOrThrow("name");
long id = cursor.getLong(idIndex);
String name = cursor.getString(nameIndex);
return new Person(id, name);
}
catch (Exception e)
{
e.printStackTrace();
}
}
You could wrap this function in your own Cursor class to make the process transparent.
Check out MicroOrm
private static class SomeObject {
#Column(SOME_FIELD)
private String mSomeField;
}
SomeObject object = microOrm.fromCursor(cursor, SomeObject.class);