greenDao的使用---重点来啦 实现ORM连表 增删改查 颤抖吧凡人

来源:互联网 发布:苹果铃声软件 编辑:程序博客网 时间:2024/05/16 23:57

发现网上的资料还是真心少,问一问群里的大神,大神就给你扔一个链接(官网)。。。硬着头皮看啊,细细的揣摩每个英文单词,每一个标点符号,每次绝望以后,总是又灰头土脸的继续看啊~终于略有所成,给大家分享一下。。。希望你们能少走弯路。不会配置AS的去看我这个系列上一篇文章,这里就不多说了。

1.连表


Relations

Database tables may relate to each other using 1:1, 1:n, or m:n relations. If you are new to database relations, it’s a good idea to catch up before we discus ORM specifics. Here are some random links discussing relations in general.

In greenDAO, entities relate using to-one or to-many relations. For example, if you want to model a 1:n relation in greenDAO, you will have a to-one and a to-many relation. However, note that the to-one and a to-many relations are not connected with each other, so you will have to update both.

Relation Names and multiple Relations

Each relation has a name, which is used for the corresponding property in the generated entity hosting the relationship. The default name is the name of the target entity. This name can be overridden by using the setName method. Keep in mind that the default name cannot not unique if an entity has multiple relations to the same target entity. In this case you must specify relation names explicitly.

Modelling To-One Relations

In your greenDAO generator model you must model a property for the foreign key (ID) value. Using this property, you can add a to-one relation using Entity.addToOne.
Example: A user has a picture.

// The variables "user" and "picture" are just regular entities
Property pictureIdProperty = user.addLongProperty("pictureId").getProperty();
user.addToOne(picture, pictureIdProperty);

This will result in a User entity having a Picture property (getPicture/setPicture), and you can work directly with Picture objects.

The getter Methods of to-one relations resolve the target entity lazily on the first access. Subsequent accesses will return the previously resolved object directly.

Note that the foreign key property (“pictureId”) and the entity object property (“picture”) are tied together. If you change the the pictureId, the next getPicture() call will resolve the Picture entity for the updated ID. Also, if you set a new Picture entity, the pictureId property will be updated as well.

greenDAO supports also eager loading to-one relations. It will resolve an entity with all to-one relations with a single database query. This is great for performance if you need the related entities anyway. Currently, you useloadDeep and queryDeep methods of the generated DAO to use this feature (may change in the future).


直接上代码

首先在你Java生成Class中这么写


Entity substanceEntitiy = schema.addEntity("Substances");// 表名substanceEntitiy.setTableName("Substances"); // 可以对表重命名substanceEntitiy.addIdProperty();substanceEntitiy.addStringProperty("Name").notNull();// de.greenrobot.daogenerator.Property typeProperty= substanceEntitiy.addLongProperty("Type").notNull().getProperty();// 主键,索引substanceEntitiy.addStringProperty("MatchTimes").notNull();substanceEntitiy.addBooleanProperty("Shield").notNull();// Entity substancesCategory = schema.addEntity("SubstancesCategory");// 表名substancesCategory.setTableName("SubstancesCategory"); // 可以对表重命名substancesCategory.addIdProperty().getProperty();substancesCategory.addStringProperty("Name").notNull();substancesCategory.addStringProperty("Remark");substanceEntitiy.addToOne(substancesCategory,typeProperty);//substancesCategory作为外部属性加入substanceEntitiy 通过substanceEntitiy Type 作为连接//SELECT T."_id",T."NAME",T."TYPE",T."MATCH_TIMES",T."SHIELD",T0."_id",T0."NAME",T0."REMARK" FROM Substances// T LEFT JOIN SubstancesCategory T0 ON T.'TYPE'=T0.'_id' WHERE T."_id"=?//To-One

这里强调一点就是连表的外部类一般是不会初始化的。

private SubstancesCategory substancesCategory;private Long substancesCategory__resolvedKey;
/** To-one relationship, resolved on first access. */public SubstancesCategory getSubstancesCategory() {    long __key = this.Type;    if(substancesCategory__resolvedKey==null)    Log.i("SS", "nul");    if (substancesCategory__resolvedKey == null || !substancesCategory__resolvedKey.equals(__key)) {        if (daoSession == null) {            throw new DaoException("Entity is detached from DAO context");        }        SubstancesCategoryDao targetDao = daoSession.getSubstancesCategoryDao();        SubstancesCategory substancesCategoryNew = targetDao.load(__key);        synchronized (this) {            substancesCategory = substancesCategoryNew;           substancesCategory__resolvedKey = __key;        }    }    return substancesCategory;}public void setSubstancesCategory(SubstancesCategory substancesCategory) {    Log.i("Sub", substancesCategory.toString());    if (substancesCategory == null) {        throw new DaoException("To-one property 'Type' has not-null constraint; cannot set to-one to null");    }    synchronized (this) {        this.substancesCategory = substancesCategory;        Type = substancesCategory.getId();        Log.i("Type", String.valueOf(Type));        substancesCategory__resolvedKey = Type;    }}
运行后调用的时候你会发现报错 

就是说你这新增的属性时空的不能用啊 为什么呢 去看看人家官网说的调用这孙子方法 loaddeap

private void initData() {    if(substancesList==null)        substancesList = new ArrayList<Substances>();    substancesList.clear();    DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(this, "tr-db", null);    db = helper.getWritableDatabase();    daoMaster = new DaoMaster(db);    daoSession = daoMaster.newSession();    subDao = daoSession.getSubstancesDao();    subCateDao=daoSession.getSubstancesCategoryDao();    String textColumn = SubstancesDao.Properties.Id.columnName;    String orderBy = textColumn + " COLLATE LOCALIZED ASC";    cursor = db.query(subDao.getTablename(), subDao.getAllColumns(), null, null, null, null, orderBy);    while (cursor.moveToNext()) {        //根据列名获取列索引        int idColumnIndex = cursor.getColumnIndex(SubstancesDao.Properties.Id.columnName);        long idValue = cursor.getLong(idColumnIndex);        Log.i("MainActivity","cursor.moveToNext");        Substances temp=subDao.loadDeep(idValue);        if(temp!=null) {            Log.i("SubstancesName", temp.getName().toString());            Log.i("getSubstancesCategory", temp.getSubstancesCategory().getName().toString());            substancesList.add(temp);        }    }}
大功告成 你现在就可以访问这些外表的所有属性了!

2.连表更新 

楼主用了2个Activity 第二个Ac来编辑 返回的数据在1个Ac中更新。

所有你要传递的T或者ArrayList<T>都得实现Parcelabel 包括外属性难兄弟们也得实现 in.read dest.writeto都得写 具体看我的Parcelabel 的帖子。

看看我如何更新的

编辑后的数据:

   @Override    public void onClick(View v) {        Substances substances= substancesList.get(position);        substances.setName("ffffff");        Log.i("getId", substances.getSubstancesCategory().getName().toString());        substances.setSubstancesCategory(new SubstancesCategory(substances.getSubstancesCategory().getId(),"New",""));        Intent intent=new Intent();        Bundle bundle=new Bundle();        bundle.putParcelable(KEY_Bundle,substances);        intent.putExtra(KEY_Intent, bundle);        Log.i("EditActivity", " getSubstancesCategory:"+substances.getSubstancesCategory().getName());        setResult(resultCode,intent);        finish();;    }});
1个Ac接收并更新

@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {    super.onActivityResult(requestCode, resultCode, data);    Log.i("MainActivity", "resultCode"+resultCode);    Bundle bundle=data.getBundleExtra(EditActivity.KEY_Intent);    Substances substances = bundle.getParcelable(EditActivity.KEY_Bundle);    if(substances!=null)        Log.i("MainActivity", "returned substances !=null");    else        Log.i("MainActivity", "returned substances ==null");    if(resultCode==1)    {        Log.i("MainActivity", "now update database!");        subDao.update(substances);        subCateDao.update(substances.getSubstancesCategory());    }}
为啥更新俩 去看官网收的很明白。

给你们贴上 懒人!

In greenDAO, entities relate using to-one or to-many relations. For example, if you want to model a 1:n relation in greenDAO, you will have a to-one and a to-many relation. However, note that the to-one and a to-many relations are not connected with each other, so you will have to update both.

下面是查询

楼主发现一种简单的方式

DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(this, "tr-db", null);db = helper.getWritableDatabase();daoMaster = new DaoMaster(db);daoSession = daoMaster.newSession();subDao = daoSession.getSubstancesDao();subCateDao=daoSession.getSubstancesCategoryDao();initSP();Query query = subDao.queryBuilder().orderAsc(SubstancesDao.Properties.Id).build();substancesList = query.forCurrentThread().list();
加入条件

private void queryByName(String queryStr) {        Query query = subDao.queryBuilder().where(                SubstancesDao.Properties.Name.like("%" + queryStr + "%"))                .build();        List temp = query.list();        if(temp!=null) {            Log.i("MainActivity", "temp size=" + temp.size());            ShowListView( temp);        }
先更到这里

楼主去年使用GreenDao走了很大的弯路,由于GreenDao使用java程序生成的model类,而这个类我又要让他实现Parecelable接口实现传递,蛋疼的我当时好几次不小心生成新的类的时候覆盖了旧的类。。。让设计模式情何以堪。。于是今年果断继承了一下下 贴一下代码以后

public class SubstancesBean extends Substances implements Parcelable {    private boolean isSelected;    public void SetIDNull() {        setId(null);    }    public boolean isSelected() {        return isSelected;    }    public void setIsSelected(boolean isSelected) {        this.isSelected = isSelected;    }    public List<PeakBean> getPeakBean() {        return peakBean;    }    public void setPeakBean(List<PeakBean> peakBean) {        this.peakBean = peakBean;    }    private List<PeakBean> peakBean = new ArrayList<PeakBean>();    public SubstancesBean() {    }    public SubstancesBean(Long id) {        this.setId(id);    }    public SubstancesBean(Long id, String Name, long Type, String MatchTimes, boolean Shield, String Peak0, String Peak1, String Peak2, String Peak3, Long PeakNumber, String MutexSubstances, String Remark, SubstanceCategory substancesCategory) {        setId(id);        setName(Name);        setType(Type);        setMatchTimes(MatchTimes);        setShield(Shield);        setPeak0(Peak0);        setPeak1(Peak1);        setPeak2(Peak2);        setPeak3(Peak3);        setPeakNumber(PeakNumber);        setShield(Shield);        setMutexSubstances(MutexSubstances);        setRemark(Remark);        initPeakBean();        setSubstanceCategory(substancesCategory);    }    private void initPeakBean() {        this.getPeakBean().clear();        String peak0 = this.getPeak0();        Log.i("Substance", "peak1 Length:" + peak0.length());        if (peak0.contains(",")) {            String[] strs = peak0.split(",");            if (strs.length == 5) {                Log.i("Substance", "initPeakBean1");                this.getPeakBean().add(new PeakBean((Long.valueOf(strs[0])), Long.valueOf(strs[1]), Long.valueOf(strs[2]), Long.valueOf(strs[3]), Long.valueOf(strs[4])));            }        }        String peak1 = this.getPeak1();        if (peak1.contains(",")) {            String[] strs = peak1.split(",");            if (strs.length == 5) {                Log.i("Substance", "initPeakBean2");                this.getPeakBean().add(new PeakBean((Long.valueOf(strs[0])), Long.valueOf(strs[1]), Long.valueOf(strs[2]), Long.valueOf(strs[3]), Long.valueOf(strs[4])));            }        }        String peak2 = this.getPeak2();        if (peak2.contains(",")) {            String[] strs = peak2.split(",");            if (strs.length == 5) {                Log.i("Substance", "initPeakBean3");                this.getPeakBean().add(new PeakBean((Long.valueOf(strs[0])), Long.valueOf(strs[1]), Long.valueOf(strs[2]), Long.valueOf(strs[3]), Long.valueOf(strs[4])));            }        }        String peak3 = this.getPeak3();        if (peak3.contains(",")) {            String[] strs = peak3.split(",");            if (strs.length == 5) {                Log.i("Substance", "initPeakBean4");                this.getPeakBean().add(new PeakBean((Long.valueOf(strs[0])), Long.valueOf(strs[1]), Long.valueOf(strs[2]), Long.valueOf(strs[3]), Long.valueOf(strs[4])));            }        }        Log.i("Substance", "Substance Count:" + this.getPeakBean().size());    }    private SubstancesBean(Parcel in) {        setId(in.readLong());        setName(in.readString());        setType(in.readLong());        setPeak0(in.readString());        setPeak1(in.readString());        setPeak2(in.readString());        setPeak3(in.readString());        setPeakNumber(in.readLong());        setMatchTimes(in.readString());        setShield(in.readByte() != 0);        isSelected = in.readByte() != 0;        setSubstanceCategory((SubstanceCategory) in.readParcelable(SubstancesCategoryBean.class.getClassLoader()));        setMutexSubstances(in.readString());        setRemark(in.readString());        in.readTypedList(this.peakBean, PeakBean.CREATOR);    }    @Override    public int describeContents() {        return 0;    }    @Override    public void writeToParcel(Parcel dest, int flags) {        dest.writeLong(getId());        dest.writeString(getName());        dest.writeLong(getType());        dest.writeString(getPeak0());        dest.writeString(getPeak1());        dest.writeString(getPeak2());        dest.writeString(getPeak3());        dest.writeLong(getPeakNumber());        dest.writeString(getMatchTimes());        dest.writeByte((byte) (getShield() ? 1 : 0));        dest.writeByte((byte) (isSelected ? 1 : 0));        SubstancesCategoryBean substancesCategoryBean = new SubstancesCategoryBean(getSubstanceCategory().getId(), getSubstanceCategory().getName(), getSubstanceCategory().getRemark());        dest.writeParcelable(substancesCategoryBean, flags);        dest.writeString(getMutexSubstances());        dest.writeString(getRemark());        dest.writeTypedList(this.peakBean);    }    public static final Creator<SubstancesBean> CREATOR = new Creator<SubstancesBean>() {        @Override        public SubstancesBean createFromParcel(Parcel in) {            return new SubstancesBean(in);        }        @Override        public SubstancesBean[] newArray(int size) {            return new SubstancesBean[size];        }    };}

下面是生成的类

package model;import dao.DaoSession;import de.greenrobot.dao.DaoException;import dao.SubstanceCategoryDao;import dao.SubstancesDao;// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT. Enable "keep" sections if you want to edit. /** * Entity mapped to table Substances. */public class Substances {    private Long id;    /** Not-null value. */    private String Name;    private long Type;    /** Not-null value. */    private String MatchTimes;    private boolean Shield;    private String Peak0;    private String Peak1;    private String Peak2;    private String Peak3;    private Long PeakNumber;    private String MutexSubstances;    private String Remark;    /** Used to resolve relations */    private transient DaoSession daoSession;    /** Used for active entity operations. */    private transient SubstancesDao myDao;    private SubstanceCategory substanceCategory;    private Long substanceCategory__resolvedKey;    public Substances() {    }    public Substances(Long id) {        this.id = id;    }    public Substances(Long id, String Name, long Type, String MatchTimes, boolean Shield, String Peak0, String Peak1, String Peak2, String Peak3, Long PeakNumber, String MutexSubstances, String Remark) {        this.id = id;        this.Name = Name;        this.Type = Type;        this.MatchTimes = MatchTimes;        this.Shield = Shield;        this.Peak0 = Peak0;        this.Peak1 = Peak1;        this.Peak2 = Peak2;        this.Peak3 = Peak3;        this.PeakNumber = PeakNumber;        this.MutexSubstances = MutexSubstances;        this.Remark = Remark;    }    /** called by internal mechanisms, do not call yourself. */    public void __setDaoSession(DaoSession daoSession) {        this.daoSession = daoSession;        myDao = daoSession != null ? daoSession.getSubstancesDao() : null;    }    public Long getId() {        return id;    }    public void setId(Long id) {        this.id = id;    }    /** Not-null value. */    public String getName() {        return Name;    }    /** Not-null value; ensure this value is available before it is saved to the database. */    public void setName(String Name) {        this.Name = Name;    }    public long getType() {        return Type;    }    public void setType(long Type) {        this.Type = Type;    }    /** Not-null value. */    public String getMatchTimes() {        return MatchTimes;    }    /** Not-null value; ensure this value is available before it is saved to the database. */    public void setMatchTimes(String MatchTimes) {        this.MatchTimes = MatchTimes;    }    public boolean getShield() {        return Shield;    }    public void setShield(boolean Shield) {        this.Shield = Shield;    }    public String getPeak0() {        return Peak0;    }    public void setPeak0(String Peak0) {        this.Peak0 = Peak0;    }    public String getPeak1() {        return Peak1;    }    public void setPeak1(String Peak1) {        this.Peak1 = Peak1;    }    public String getPeak2() {        return Peak2;    }    public void setPeak2(String Peak2) {        this.Peak2 = Peak2;    }    public String getPeak3() {        return Peak3;    }    public void setPeak3(String Peak3) {        this.Peak3 = Peak3;    }    public Long getPeakNumber() {        return PeakNumber;    }    public void setPeakNumber(Long PeakNumber) {        this.PeakNumber = PeakNumber;    }    public String getMutexSubstances() {        return MutexSubstances;    }    public void setMutexSubstances(String MutexSubstances) {        this.MutexSubstances = MutexSubstances;    }    public String getRemark() {        return Remark;    }    public void setRemark(String Remark) {        this.Remark = Remark;    }    /** To-one relationship, resolved on first access. */    public SubstanceCategory getSubstanceCategory() {        long __key = this.Type;        if (substanceCategory__resolvedKey == null || !substanceCategory__resolvedKey.equals(__key)) {            if (daoSession == null) {                throw new DaoException("Entity is detached from DAO context");            }            SubstanceCategoryDao targetDao = daoSession.getSubstanceCategoryDao();            SubstanceCategory substanceCategoryNew = targetDao.load(__key);            synchronized (this) {                substanceCategory = substanceCategoryNew;            substanceCategory__resolvedKey = __key;            }        }        return substanceCategory;    }    public void setSubstanceCategory(SubstanceCategory substanceCategory) {        if (substanceCategory == null) {            throw new DaoException("To-one property 'Type' has not-null constraint; cannot set to-one to null");        }        synchronized (this) {            this.substanceCategory = substanceCategory;            Type = substanceCategory.getId();            substanceCategory__resolvedKey = Type;        }    }    /** Convenient call for {@link AbstractDao#delete(Object)}. Entity must attached to an entity context. */    public void delete() {        if (myDao == null) {            throw new DaoException("Entity is detached from DAO context");        }            myDao.delete(this);    }    /** Convenient call for {@link AbstractDao#update(Object)}. Entity must attached to an entity context. */    public void update() {        if (myDao == null) {            throw new DaoException("Entity is detached from DAO context");        }            myDao.update(this);    }    /** Convenient call for {@link AbstractDao#refresh(Object)}. Entity must attached to an entity context. */    public void refresh() {        if (myDao == null) {            throw new DaoException("Entity is detached from DAO context");        }            myDao.refresh(this);    }}

这样子搞就不怕被覆盖了!脑子还是得动起来~


1 0
原创粉丝点击