Android ORM系列之GreenDao最佳实践

GreenDAO是一个可以帮助Android开发者快速将Java对象映射到SQLite数据库的表单中的ORM解决方案,通过使用一个简单的面向对象API,开发者可以对Java对象进行存储、更新、删除和查询。

GreenDao有两个项目,一个是生成dao和model的generator的项目,该项目是java项目,一个是用于android的核心jar包。在使用前,我们必须先生成dao和model。

首先加入依赖。

compile 'de.greenrobot:greendao:2.0.0'
compile 'de.greenrobot:greendao-generator:2.0.0'

然后在我们的包名之下新建一个db的包,在db下新建dao和model的包以及一个generator的包,就像下图。
这里写图片描述

在generator包下,新建一个生成dao和model的类GreenDaoGenerator,在里面加入代码

public class GreenDaoGenerator {
    public static void main(String[] args) throws Exception {
        Schema schema = new Schema(1, "cn.edu.zafu.greendao.db.model");
        schema.setDefaultJavaPackageDao("cn.edu.zafu.greendao.db.dao");
        schema.enableKeepSectionsByDefault();
        //schema.enableActiveEntitiesByDefault();
        //ActiveRecord
        addEntity(schema);
        new DaoGenerator().generateAll(schema, "./app/src/main/java");
    }

    private static void addEntity(Schema schema) {
        Entity person = schema.addEntity("Person");
        person.addIdProperty().primaryKey();
        person.addStringProperty("name");
        person.addDoubleProperty("height");
        person.addDoubleProperty("weight");

        Entity card = schema.addEntity("Card");
        card.addIdProperty().primaryKey();
        card.addStringProperty("num");
        card.addStringProperty("address");

        Property idcardPK = person.addLongProperty("cardId").getProperty();
        person.addToOne(card, idcardPK);

        Property personPK = card.addLongProperty("personId").getProperty();
        card.addToOne(person,personPK);
    }

}

Schema schema = new Schema(1, “cn.edu.zafu.greendao.db.model”); 代表创建的数据库的版本号以及默认的java package,如果不修改默认的包名,生成的dao和model都会在该包下,这里我们修改了dao的包名schema.setDefaultJavaPackageDao(“cn.edu.zafu.greendao.db.dao”);,生成的model中,我们可能需要加入自己的一些信息,但是又不希望下次生成的时候消失,所以可以使用schema.enableKeepSectionsByDefault();,使用后会在model类中有如下这些标示

// KEEP INCLUDES - put your custom includes here
// KEEP INCLUDES END

// KEEP FIELDS - put your custom fields here
// KEEP FIELDS END

 // KEEP METHODS - put your custom methods here
// KEEP METHODS END

你只需将你需要的信息添加到这三个之间,分布代表引入的包,字段,方法。之后重新生成这些信息将会被保留。

schema.enableActiveEntitiesByDefault();代表实体类是否支持active,用过php中yii框架的都应该清楚,实体类可以直接进行crud操作。我们不开启就好了,如果开启了的话,实体类将之间支持update, refresh, deleted 等操作。

之后就使用 schema.addEntity()函数增加Entity 对象,即对应的实体类,通过添加属性方法addProperty系列方法增加字段,最后调用new DaoGenerator().generateAll(schema, “./app/src/main/java”);方法生成dao和model。

生成的步骤也很简单,在该类上右键,点run即可。

这里写图片描述

生成之后控制台就会输出

这里写图片描述

然后我们编写一个核心辅助类。用于获取DaoMaster和DaoSession

public class DbCore {
    private static final String DEFAULT_DB_NAME = "default.db";
    private static DaoMaster daoMaster;
    private static DaoSession daoSession;

    private static Context mContext;
    private static String DB_NAME;

    public static void init(Context context) {
        init(context, DEFAULT_DB_NAME);
    }

    public static void init(Context context, String dbName) {
        if (context == null) {
            throw new IllegalArgumentException("context can't be null");
        }
        mContext = context.getApplicationContext();
        DB_NAME = dbName;
    }

    public static DaoMaster getDaoMaster() {
        if (daoMaster == null) {
            DaoMaster.OpenHelper helper = new DaoMaster.DevOpenHelper(mContext, DB_NAME, null);
            daoMaster = new DaoMaster(helper.getWritableDatabase());
        }
        return daoMaster;
    }

    public static DaoSession getDaoSession() {
        if (daoSession == null) {
            if (daoMaster == null) {
                daoMaster = getDaoMaster();
            }
            daoSession = daoMaster.newSession();
        }
        return daoSession;
    }

    public static void enableQueryBuilderLog(){

        QueryBuilder.LOG_SQL = true;
        QueryBuilder.LOG_VALUES = true;
    }
}

接下来就是基础的泛型Service

public class BaseService<T, K> {
    private AbstractDao<T, K> mDao;


    public BaseService(AbstractDao dao) {
        mDao = dao;
    }


    public void save(T item) {
        mDao.insert(item);
    }

    public void save(T... items) {
        mDao.insertInTx(items);
    }

    public void save(List<T> items) {
        mDao.insertInTx(items);
    }

    public void saveOrUpdate(T item) {
        mDao.insertOrReplace(item);
    }

    public void saveOrUpdate(T... items) {
        mDao.insertOrReplaceInTx(items);
    }

    public void saveOrUpdate(List<T> items) {
        mDao.insertOrReplaceInTx(items);
    }

    public void deleteByKey(K key) {
        mDao.deleteByKey(key);
    }

    public void delete(T item) {
        mDao.delete(item);
    }

    public void delete(T... items) {
        mDao.deleteInTx(items);
    }

    public void delete(List<T> items) {
        mDao.deleteInTx(items);
    }

    public void deleteAll() {
        mDao.deleteAll();
    }


    public void update(T item) {
        mDao.update(item);
    }

    public void update(T... items) {
        mDao.updateInTx(items);
    }

    public void update(List<T> items) {
        mDao.updateInTx(items);
    }

    public  T query(K key) {
        return  mDao.load(key);
    }

    public List<T> queryAll() {
        return mDao.loadAll();
    }

    public List<T> query(String where, String... params) {

        return mDao.queryRaw(where, params);
    }

    public QueryBuilder<T> queryBuilder() {

        return mDao.queryBuilder();
    }

    public long count() {
        return mDao.count();
    }

    public void refresh(T item) {
        mDao.refresh(item);

    }

    public void detach(T item) {
        mDao.detach(item);
    }
}

一个实现类,第二个泛型参数是主键类型

public class CardService extends BaseService<Card,Long> {
    public CardService(CardDao dao) {
        super(dao);
    }
}
public class PersonService extends BaseService<Person,Long> {
    public PersonService(PersonDao dao) {
        super(dao);
    }
}

编写一个工具类获得service

public class DbUtil {
    private static CardService cardService;
    private static PersonService personService;


    private static PersonDao getPersonDao() {
        return DbCore.getDaoSession().getPersonDao();
    }

    private static CardDao getCardDao() {
        return DbCore.getDaoSession().getCardDao();
    }

    public static CardService getCardService() {
        if (cardService == null) {
            cardService = new CardService(getCardDao());
        }
        return cardService;
    }

    public static PersonService getPersonService() {
        if (personService == null) {
            personService = new PersonService(getPersonDao());
        }
        return personService;
    }
}

在Application中初始化,并设置在清单文件中

public class App extends Application{
    @Override
    public void onCreate() {
        super.onCreate();
        DbCore.init(this);
    }
}

增删改查,下面为单元测试的方法

public class ApplicationTest extends ApplicationTestCase<Application> {
    private PersonService mPersonService;
    private CardService mCardService;

    public ApplicationTest() {
        super(Application.class);
    }

    @Override
    protected void setUp() throws Exception {
        super.setUp();
        DbCore.init(getContext());
        DbCore.enableQueryBuilderLog();
        mPersonService = DbUtil.getPersonService();
        mCardService = DbUtil.getCardService();
    }

    public void testSave(){
        Card c=new Card();
        c.setNum("3303241646813416463468");
        c.setAddress("杭州");

        mCardService.save(c);

        Person p=new Person();
        p.setName("张三");
        p.setHeight(178.00);
        p.setWeight(65.00);
        p.setCard(c);
        mPersonService.save(p);

        c.setPerson(p);
        mCardService.saveOrUpdate(c);

    }
    public void testSave1(){
        Card c=new Card();
        c.setNum("3303241646813416463468");
        c.setAddress("杭州");

        Card c1=new Card();
        c1.setNum("12121646813416463468");
        c1.setAddress("温州");

        mCardService.save(c, c1);

        c.setNum("11111");
        mCardService.saveOrUpdate(c, c1);


    }

    public void testSave2(){
        Card c=new Card();
        c.setNum("3303241646813416463468");
        c.setAddress("杭州");

        Card c1=new Card();
        c1.setNum("12121646813416463468");
        c1.setAddress("温州");

        List<Card> cards=new ArrayList<Card>();

        cards.add(c);
        cards.add(c1);


        mCardService.save(cards);

        c1.setNum("22222");

        mCardService.saveOrUpdate(cards);



    }


    public void testDelete(){
        Card c=new Card();
        c.setNum("333333333333333");
        c.setAddress("3333");

        mCardService.save(c);
        mCardService.delete(c);

        c=new Card();
        c.setNum("444444");
        c.setAddress("44444444");

        mCardService.save(c);
        mCardService.deleteByKey(c.getId());

    }

    public void testDelete1(){
        Card c=new Card();
        c.setNum("55555");
        c.setAddress("5555");



        Card c1=new Card();
        c1.setNum("666666");
        c1.setAddress("66666666");
        mCardService.save(c,c1);
        mCardService.delete(c, c1);

    }

    public void testDelete2(){
        Card c=new Card();
        c.setNum("55555");
        c.setAddress("5555");

        Card c1=new Card();
        c1.setNum("666666");
        c1.setAddress("66666666");
        List<Card> cards=new ArrayList<Card>();

        cards.add(c);
        cards.add(c1);

        mCardService.save(cards);
        mCardService.delete(cards);

    }

    public  void testDelete3(){
        mCardService.deleteAll();
    }

    public void testUpdate(){
        Card c=new Card();
        c.setNum("55555");
        c.setAddress("5555");

        mCardService.save(c);
        c.setNum("123456");
        mCardService.update(c);
    }
    public void testUpdate1(){
        Card c=new Card();
        c.setNum("55555");
        c.setAddress("5555");

        mCardService.save(c);
        c.setNum("123456");

        Card c1=new Card();
        c1.setNum("6666");
        c1.setAddress("66666");

        mCardService.save(c1);
        c1.setNum("654321");
        mCardService.update(c,c1);
    }

    public void testUpdate2(){
        Card c=new Card();
        c.setNum("aaaaa");
        c.setAddress("aaaaaaaaaa");

        mCardService.save(c);
        c.setNum("bbbbbbbbb");

        Card c1=new Card();
        c1.setNum("ccccc");
        c1.setAddress("cccccccc");

        mCardService.save(c1);
        c1.setNum("dddddddddd");

        List<Card> cards=new ArrayList<Card>();

        cards.add(c);
        cards.add(c1);
        mCardService.update(cards);
    }

    public void testQuery(){
        Card c=new Card();
        c.setNum("aaaaa111");
        c.setAddress("aaaaaaaa11111aa");

        mCardService.save(c);

        List<Card> cards = mCardService.queryAll();
        Log.e("TAG", cards + "");

        Card query = mCardService.query(c.getId());
        Log.e("TAG", query + "");

        List<Card> query1 = mCardService.query("where NUM=?", c.getNum());
        Log.e("TAG", query1 + "");

        long count = mCardService.count();
        Log.e("TAG", count + "");

        List<Card> list = mCardService.queryBuilder().where(CardDao.Properties.Num.eq(c.getNum())).list();
        Log.e("TAG", list + "");
    }
}

关于关联关系的映射,下一篇文章细说。

源码下载。

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值