如何将ORM框架封装为通用的BaseDao

来源:互联网 发布:淘宝妈妈装模特莫姐 编辑:程序博客网 时间:2024/05/18 02:50

如何将ORM框架封装为通用的BaseDao

  • 如何将ORM框架封装为通用的BaseDao
    • 封装
    • 具体使用

最近开发的项目中需要使用到ORM框架,但是我并不想针对每一个具体业务写一个Dao,对于通用的CRUD功能,我想试着通过一个BaseDao解决问题,这里涉及到一个关键问题是:如何在编译时获取泛型的实际类型?后来通过抽象类解决了这个问题。

封装

public abstract class BaseDao<T> {    protected static DaoSession daoSession;    public BaseDao(Context context) {        DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(context, dbPath, null);        Database db = helper.getWritableDb();        daoSession = new DaoMaster(db).newSession();    }    public void insert(final T t) {        // 延迟处理异常,所以这里不在构造器中初始化rxDao        try {            final RxDao<T, Void> rxDao = (RxDao<T, Void>) daoSession.getDao(Class.forName(getGenericClassName())).rx();            new Thread(new Runnable() {                @Override                public void run() {                    // 当调用订阅操作(即调用Observable.subscribe()方法)的时候,被观察者才真正开始发出事件。                    // 核心源码见Observable类的create(OnSubscribe<T> f)方法的解释                    rxDao.insert(t).subscribe(new Subscriber<T>() {                        @Override                        public void onCompleted() {                        }                        @Override                        public void onError(Throwable e) {                            if (e != null){                                e.printStackTrace();                            }                        }                        @Override                        public void onNext(T t) {                        }                    });                }            }).start();        } catch (ClassNotFoundException e) {            e.printStackTrace();        }    }    public void update(final T t) {        try {            final RxDao<T, Void> rxDao = (RxDao<T, Void>) daoSession.getDao(Class.forName(getGenericClassName())).rx();            new Thread(new Runnable() {                @Override                public void run() {                    rxDao.update(t).subscribe(new Subscriber<T>() {                        @Override                        public void onCompleted() {                        }                        @Override                        public void onError(Throwable e) {                            if (e != null){                                e.printStackTrace();                            }                        }                        @Override                        public void onNext(T t) {                        }                    });                }            }).start();        } catch (ClassNotFoundException e) {            e.printStackTrace();        }    }    public void delete(final T t) {        try {            final RxDao<T, Void> rxDao = (RxDao<T, Void>) daoSession.getDao(Class.forName(getGenericClassName())).rx();            new Thread(new Runnable() {                @Override                public void run() {                    rxDao.delete(t).subscribe(new Subscriber<Void>() {                        @Override                        public void onCompleted() {                        }                        @Override                        public void onError(Throwable e) {                            if (e != null){                                e.printStackTrace();                            }                        }                        @Override                        public void onNext(Void aVoid) {                        }                    });                }            }).start();        } catch (ClassNotFoundException e) {            e.printStackTrace();        }    }    public void loadAll(final ColDaoCallBack<T> colDaoCallBack) {    try {            final RxDao<T, Void> rxDao = (RxDao<T, Void>) daoSession.getDao(Class.forName(getGenericClassName())).rx();            new Thread(new Runnable() {                @Override                public void run() {                    rxDao.loadAll()                            .observeOn(AndroidSchedulers.mainThread())                            .subscribe(colDaoCallBack.getAction1(), new Action1<Throwable>() {                                @Override                                public void call(Throwable throwable) {                                    if (throwable != null){                                        throwable.printStackTrace();                                    }                                }                            });                }            }).start();        } catch (ClassNotFoundException e) {            e.printStackTrace();        }    }    public final Type getType() {        Type superType = getClass().getGenericSuperclass();        Type type = ((ParameterizedType) superType).getActualTypeArguments()[0];        return type;    }    public final String getGenericClassSimpleName() {        String raw = getType().toString();        int spaceIndex = raw.lastIndexOf(" ");        int spotIndex = raw.lastIndexOf(".");        int dollarIndex = raw.lastIndexOf("$");        int index = Math.max(Math.max(spaceIndex, spotIndex), dollarIndex);        String result = raw.substring(index + 1);        return result;    }    public final String getGenericClassName() {        String raw = getType().toString();        int spaceIndex = raw.lastIndexOf(" ");        String result = raw.substring(spaceIndex + 1);        return result;    }}

实际使用的时候需要创建一个匿名内部类的实例来继承BaseDao抽象类,但是由于CRUD的操作已经在BaseDao中具体实现了,但是只需要提供一个空实现即可,同时传入实际的泛型类型。

具体使用

Bean bean = new Bean();BaseDao<Bean> baseDao = new BaseDao<>(context){};baseDao.insert(bean);
1 0