Codementor Events

greenDAO CRUD Demo Application

Published Jul 01, 2017
greenDAO CRUD Demo Application

This is a sequel to Integrating greenDao into your android application

Had to write this post due to requests for a demo app using GreenDao ORM. So lets list the feature of our GreenDAO CRUD App. CRUD stands for Create, Read, Delete & Update.

  1. Add item to grocery list (Create)
  2. list all groceries items added (Read)
  3. Update grocery list (Update)
  4. Remove grocery Item (Delete)

So we will be creating a new Android project called OurGroceryApp. Please go through Seting up GreenDao ORM. Follow Step 2 through Step 6.

Then on Step 6 insead of creating entity User with fields user_id, last_name, first_name and email.

We will be creating an entity named Grocery with fields name,quantity and status. This is what our MyGenerator Class looks like now

package com.example;

import org.greenrobot.greendao.generator.DaoGenerator;
import org.greenrobot.greendao.generator.Entity;
import org.greenrobot.greendao.generator.Schema;

public class MyGenerator {
  public static void main(String[] args) {
    Schema schema = new Schema(1, "com.akinsete.ourgrocerylist.db"); // Your app package name and the (.db) is the folder where the DAO files will be generated into.
    schema.enableKeepSectionsByDefault();

    addTables(schema);

    try {
      new DaoGenerator().generateAll(schema,"./app/src/main/java");
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  private static void addTables(final Schema schema) {
    addGroceryEntity(schema);
  }

  // This is use to describe the columns of your table
  private static Entity addGroceryEntity(final Schema schema) {
    Entity grocery = schema.addEntity("Grocery");
    grocery.addIdProperty().primaryKey().autoincrement();
    grocery.addStringProperty("name").notNull();
    grocery.addIntProperty("quantity").notNull();
    grocery.addStringProperty("status");
    return grocery;
  }
}

Right on the MyGenerator Class and Run "MyGenerator.run()". After this we will now have our DAO files, entities generated in our main project.
Screen Shot 2017-06-30 at 9.56.31 PM.png

So proceed to Step 8

Creata a class to extend Application. See Application file after adding greenDAO to enable easy access from all our activities.

package com.akinsete.ourgrocerylist;

import android.app.Application;

import com.akinsete.ourgrocerylist.db.DaoMaster;
import com.akinsete.ourgrocerylist.db.DaoSession;

import org.greenrobot.greendao.database.Database;

/**
 * Created by Akinsete on 6/30/17.
 */

public class AppController extends Application {

  public static final boolean ENCRYPTED = true;
  private DaoSession daoSession;

  @Override
  public void onCreate() {
    super.onCreate();


    DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(this,"grocery-db"); //The users-db here is the name of our database.
    Database db = helper.getWritableDb();
    daoSession = new DaoMaster(db).newSession();
  }

  public DaoSession getDaoSession() {
    return daoSession;
  }

}

Now add a ListView to display our Grocery List and a FAB to navigate to add more item to our list. The listview will be used for displaying out grocery list, deleting an item and also to modify items on the grocery list.

So back to greenDAO, In our MainActivity do the following.

  1. Create a DAOSession variable and a Grocery list varaible from our Grocery model class;
    	DaoSession daoSession;
        List<Grocery> groceries = new ArrayList<>();
  1. In the OnCreate method get the DAOSession from or AppController class
    daoSession = ((AppController) getApplication()).getDaoSession();
  1. On this particular activity we will be performing 3 major operations.
    a. fetch out grocery list
    b. delete an item on the grocery list
    c. get selected item to update then pass the item to the modify activity

So we will have

  private void fetchGroceryList(){
    groceries.clear();
    //// Get the entity dao we need to work with.
    GroceryDao groceryDao = daoSession.getGroceryDao();

    //// Load all items
    groceries.addAll(groceryDao.loadAll());

    /// Notify our adapter of changes
    groceryArrayAdapter.notifyDataSetChanged();
  }


  private void deleteGroceryItem(long id){
    //// Get the entity dao we need to work with.
    GroceryDao groceryDao = daoSession.getGroceryDao();

    /// perform delete operation
    groceryDao.deleteByKey(id);

    fetchGroceryList();
  }

  private void proceedToUpdateItem(Grocery grocery){
    // Pass grocery id to the next screen
    Intent intent = new Intent(this,ModifyGroceryList.class);
    intent.putExtra("create",false);
        // make sure your Grocery Class implements seriallizable
    intent.putExtra("grocery",grocery);
    startActivity(intent);
  }

So this is our main complete MainActivity.class.

package com.akinsete.ourgrocerylist;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;

import com.akinsete.ourgrocerylist.db.DaoSession;
import com.akinsete.ourgrocerylist.db.Grocery;
import com.akinsete.ourgrocerylist.db.GroceryDao;

import java.util.ArrayList;
import java.util.List;

public class MainActivity extends AppCompatActivity {
  ListView listView;
  List<Grocery> groceries = new ArrayList<>();

  DaoSession daoSession;
  ArrayAdapter<Grocery> groceryArrayAdapter;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    listView = (ListView) findViewById(R.id.list_view);
    daoSession = ((AppController) getApplication()).getDaoSession();
    setupListView();
  }


  @Override
  protected void onResume() {
    super.onResume();

    fetchGroceryList();
  }


  private void setupListView() {
    groceryArrayAdapter = new ArrayAdapter<>(this,android.R.layout.simple_list_item_1,groceries);
    listView.setAdapter(groceryArrayAdapter);

    listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
      @Override
      public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {

        showOptions(position);

        return false;
      }
    });
  }


  private void showOptions(int position) {
    final Grocery selectedGroceryItem = groceries.get(position);

    AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);

    String[] options = new String[2];

    options[0] = "Edit " + selectedGroceryItem.getName();
    options[1] = "Delete " + selectedGroceryItem.getName();

    alertDialogBuilder.setItems(options, new DialogInterface.OnClickListener() {
      @Override
      public void onClick(DialogInterface dialog, int which) {
        if(which == 0){
          proceedToUpdateItem(selectedGroceryItem);
        }else if(which == 1){
          deleteGroceryItem(selectedGroceryItem.getId());
        }

      }
    });
    alertDialogBuilder.create().show();
  }


  private void fetchGroceryList(){
    groceries.clear();
    //// Get the entity dao we need to work with.
    GroceryDao groceryDao = daoSession.getGroceryDao();

    //// Load all items
    groceries.addAll(groceryDao.loadAll());

    /// Notify our adapter of changes
    groceryArrayAdapter.notifyDataSetChanged();
  }


  private void deleteGroceryItem(long id){
    //// Get the entity dao we need to work with.
    GroceryDao groceryDao = daoSession.getGroceryDao();
    /// perform delete operation
    groceryDao.deleteByKey(id);

    fetchGroceryList();
  }


  private void proceedToUpdateItem(Grocery grocery){
    // Pass grocery id to the next screen
    Intent intent = new Intent(this,ModifyGroceryList.class);
    intent.putExtra("create",false);
    intent.putExtra("grocery",grocery);
    startActivity(intent);
  }

  public void addNewItem(View view) {
    // Go to add item activity
    Intent intent = new Intent(this,ModifyGroceryList.class);
    intent.putExtra("create",true);
    startActivity(intent);
  }
}

Please note, there are lots of operations that can be performed on the groceryDao Object etc

    groceryDao.deleteAll();
    groceryDao.delete(grocery);
    groceryDao.insert(grocery);
    groceryDao.load(grocery_id);
    groceryDao.insertOrReplaceInTx(groceryEntities);

and many more.

In our ModifyGroceryList.class Activity we will be performing 2 major greenDAO operations. Which is
1. Update a grocery item
2. Add new grocery item


  private void updateItem(long id){
    GroceryDao groceryDao = daoSession.getGroceryDao();
    Grocery grocery = new Grocery();
    grocery.setId(id);
    grocery.setName(name.getText().toString());
    grocery.setQuantity(Integer.parseInt(quantity.getText().toString()));
    groceryDao.saveInTx(grocery);
    Toast.makeText(this, "Item updated", Toast.LENGTH_SHORT).show();
    finish();
  }

  private void insetItem(){
    GroceryDao groceryDao = daoSession.getGroceryDao();
    Grocery grocery = new Grocery();
    grocery.setName(name.getText().toString());
    grocery.setQuantity(Integer.parseInt(quantity.getText().toString()));
    groceryDao.insert(grocery);
    Toast.makeText(this, "Item inserted", Toast.LENGTH_SHORT).show();
    finish();
  }

And below is the complete ModifyGroceryList.class Activity

package com.akinsete.ourgrocerylist;

import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;

import com.akinsete.ourgrocerylist.db.DaoSession;
import com.akinsete.ourgrocerylist.db.Grocery;
import com.akinsete.ourgrocerylist.db.GroceryDao;

public class ModifyGroceryList extends AppCompatActivity {

  Grocery grocery;
  DaoSession daoSession;

  EditText name,quantity;
  Button btn_save;

  boolean createNew = false;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_modify_grocery_list);

    name = (EditText)findViewById(R.id.name);
    quantity = (EditText)findViewById(R.id.quantity);
    btn_save = (Button) findViewById(R.id.btn_save);

    daoSession = ((AppController) getApplication()).getDaoSession();

    handleIntent(getIntent());

    setClickEventListener();
  }


  private void handleIntent(Intent intent) {
    createNew = intent.getBooleanExtra("create",false);

    //// This means we are editing a grocery item
    if(!createNew){
      grocery = (Grocery)intent.getSerializableExtra("grocery");
      name.setText(grocery.getName());
 			quantity.setText(String.valueOf(grocery.getQuantity()));
    }
  }


  private void setClickEventListener() {
    btn_save.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
        if(createNew){
          insetItem();
        }else{
          updateItem(grocery.getId());
        }
      }
    });
  }


  private void updateItem(long id){
    GroceryDao groceryDao = daoSession.getGroceryDao();
    Grocery grocery = new Grocery();
    grocery.setId(id);
    grocery.setName(name.getText().toString());
    grocery.setQuantity(Integer.parseInt(quantity.getText().toString()));
    groceryDao.saveInTx(grocery);
    Toast.makeText(this, "Item updated", Toast.LENGTH_SHORT).show();
    finish();
  }


  private void insetItem(){
    GroceryDao groceryDao = daoSession.getGroceryDao();
    Grocery grocery = new Grocery();
    grocery.setName(name.getText().toString());
    grocery.setQuantity(Integer.parseInt(quantity.getText().toString()));
    groceryDao.insert(grocery);
    Toast.makeText(this, "Item inserted", Toast.LENGTH_SHORT).show();
    finish();
  }
}

And thats it for our grocery app. See Github Repo for complete project.

For those that requested for this sorry its coming little late. I have been busy.

Please do not hesitate to ask for more.
Thanks.

Discover and read more posts from Sunday Akinsete
get started
post comments3Replies
Wazma Ali
6 years ago

Why do I get this in my listView -> [Ljava.lang.String;@9d2d436
instead of Name and quantity?

Robert Ruby
6 years ago

Getting this error when trying to update… using your repository code. Any ideas?

2019-01-03 20:06:19.111 26312-26312/com.akinsete.ourgrocerylist E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.akinsete.ourgrocerylist, PID: 26312
java.lang.ClassCastException: com.akinsete.ourgrocerylist.db.Grocery cannot be cast to java.io.Serializable
at com.akinsete.ourgrocerylist.MainActivity.proceedToUpdateItem(MainActivity.java:120)
at com.akinsete.ourgrocerylist.MainActivity.access$100(MainActivity.java:21)
at com.akinsete.ourgrocerylist.MainActivity$2.onClick(MainActivity.java:82)
at com.android.internal.app.AlertController$AlertParams$3.onItemClick(AlertController.java:1119)
at android.widget.AdapterView.performItemClick(AdapterView.java:310)
at android.widget.AbsListView.performItemClick(AbsListView.java:1155)
at android.widget.AbsListView$PerformClick.run(AbsListView.java:3120)
at android.widget.AbsListView$3.run(AbsListView.java:4035)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:866)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:756)

Marselino Widis
6 years ago

I’m getting the same error , do you have any idea to fix it?