GreenDao学习

GreenDao学习

官网:http://greenrobot.org/greendao/

ORM: object Relationnal Mapping,即关系对象映射,他的思想就是将关系数据库中表的数据映射成对象,以对象的形式呈现,这样开发人员就可以将数据的操作转化为对象的操作,。因此它的目的是方便开发人员以面向对象的思想实现数据库的操作

一、GreenDao是什么?
GreenDAO是一个开源的安卓ORM框架,能够使SQLite数据库的开发再次变得有趣。它减轻开发人员处理低级数据库需求,同时节省开发时间。 SQLite是一个令人敬畏的内嵌的关系数据库,编写SQL和解析查询结果是相当乏味和耗时的任务。通过将Java对象映射到数据库表(称为ORM,“对象/关系映射”),GreenDAO可以将它们从这些映射中释放出来,这样,您可以使用简单的面向对象的API来存储,更新,删除和查询数据库。
简单的讲,GreenDAO 是一个将对象映射到 SQLite 数据库中的轻量且快速的 ORM 解决方案。

这里写图片描述

二、greenDAO’s Features at a glance(GreenDao优点)

Maximum performance(最优性能): (probably the fastest ORM for Android); our benchmarks are open sourced too
Easy to use(便于使用): powerful APIs covering relations and joins
Minimal(低消耗): memory consumption
Small(空间小): library size (<100KB) to keep your build times low and to avoid the 65k method limit
Database encryption(数据加密): greenDAO supports SQLCipher to keep your user’s data safe
Strong community(强壮的社区): More than 5.000 GitHub stars show there is a strong and active community

三、GreenDao配置

1、添加依赖

①In your root build.gradle file:

buildscript {
    repositories {
        jcenter()
        mavenCentral() // add repository
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.3.0'
        classpath 'org.greenrobot:greendao-gradle-plugin:3.2.2' // add plugin
    }
}

②In your app projects build.gradle file:

apply plugin: 'com.android.application'
apply plugin: 'org.greenrobot.greendao' // apply plugin

greendao {
    schemaVersion 1
    daoPackage '包名.gen'
    targetGenDir 'src/main/java'
} 

dependencies {
    compile 'org.greenrobot:greendao:3.2.2' // add library
}

schemaVersion:指定数据库schema版本号,迁移等操作会用到;
daoPackage:通过gradle插件生成的数据库相关文件的包名,默认为你的entity所在的包名;
targetGenDir:自定义生成数据库文件的目录,可以将生成的文件放到我们的java目录中,而不是build中,这样就不用额外的设置资源目录了。

2、通过GreenDao3注解的语法来定义我们的一个数据库实体类及其数据库操作方法

@Entity
public class User{
    @Id(autoincrement = true)
    private Long _id;
    private String name;
    @NotNull
    private String age;
}

这里的几个注解含义:

  • @Entity:将我们的java普通类变为一个能够被greenDAO识别的数据库类型的实体类;
  • @nameInDb:在数据库中的名字,如不写则为实体中类名;
  • @Id:选择一个long / Long属性作为实体ID。 在数据库方面,它是主键。 参数autoincrement是设置ID值自增;
  • @NotNull:使该属性在数据库端成为“NOT
    NULL”列。 通常使用@NotNull标记原始类型(long,int,short,byte)是有意义的
  • @Transient:表明这个字段不会被写入数据库,只是作为一个普通的java类字段,用来临时存储数据的,不会被持久化。

3、通过点击AndroidStudio中的MakeProject,便发现GreenDao为我们的Meizi实体类生成了对应的Getter、Setter方法以及俩个构造函数,同时在我们配置的com.ping.greendao.gen包下生成了三个对应类文件DaoMaster、DaoSession和MeiziDao,之后所有相关的数据库操作都依靠这三个文件了;

DaoMaster:使用greenDAO的切入点。DaoMaster保存数据库对象(SQLiteDatabase)并管理特定模式的DAO类(而不是对象)。 它具有静态方法来创建表或将它们删除。 其内部类OpenHelper和DevOpenHelper是在SQLite数据库中创建模式的SQLiteOpenHelper实现。一个DaoMaster就代表着一个数据库的连接。
DaoSession:管理特定模式的所有可用DAO对象,您可以使用其中一个getter方法获取。 DaoSession还为实体提供了一些通用的持久性方法,如插入,加载,更新,刷新和删除。 DaoSession可以让我们使用一些Entity的基本操作和获取Dao操作类,DaoSession可以创建多个,每一个都是属于同一个数据库连接的。
XxxDAO:数据访问对象(DAO)持续存在并查询实体。 对于每个实体,GreenDAO生成一个DAO。 它比DaoSession有更多的持久化方法,例如:count,loadAll和insertInTx。

4、编写DaoManager,用于创建数据库、创建数据库表、包含增删改查的操作以及数据库的升级

/**
 * Created by anwanfei on 2017/8/4.
 * 创建数据库、创建数据库表、包含增删改查的操作以及数据库的升级
 */

public class DaoManager {
    private static final String TAG = DaoManager.class.getSimpleName();
    private static final String DB_NAME = "shipDetails";

    private Context context;

    //多线程中要被共享的使用volatile关键字修饰
    private volatile static DaoManager manager = new DaoManager();
    private static DaoMaster sDaoMaster;
    private static DaoMaster.DevOpenHelper sHelper;
    private static DaoSession sDaoSession;

    /**
     * 单例模式获得操作数据库对象
     *
     * @return
     */
    public static DaoManager getInstance() {
        return manager;
    }

    public void init(Context context) {
        this.context = context;
    }

    /**
     * 判断是否有存在数据库,如果没有则创建
     *
     * @return
     */
    public DaoMaster getDaoMaster() {
        if (sDaoMaster == null) {
            DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(context, DB_NAME, null);
            sDaoMaster = new DaoMaster(helper.getWritableDatabase());
        }
        return sDaoMaster;
    }

    /**
     * 完成对数据库的添加、删除、修改、查询操作,仅仅是一个接口
     *
     * @return
     */
    public DaoSession getDaoSession() {
        if (sDaoSession == null) {
            if (sDaoMaster == null) {
                sDaoMaster = getDaoMaster();
            }
            sDaoSession = sDaoMaster.newSession();
        }
        return sDaoSession;
    }

    /**
     * 打开输出日志,默认关闭
     */
    public void setDebug() {
        QueryBuilder.LOG_SQL = true;
        QueryBuilder.LOG_VALUES = true;
    }

    /**
     * 关闭所有的操作,数据库开启后,使用完毕要关闭
     */
    public void closeConnection() {
        closeHelper();
        closeDaoSession();
    }

    public void closeHelper() {
        if (sHelper != null) {
            sHelper.close();
            sHelper = null;
        }
    }

    public void closeDaoSession() {
        if (sDaoSession != null) {
            sDaoSession.clear();
            sDaoSession = null;
        }
    }
}

5 、编写XxxDaoUtil,用于完成对某一张数据表的具体操作——ORM操作

/**
 * Created by anwanfei on 2017/8/4.
 */

public class ShipDetailsDaoUtil {
    private static final String TAG = ShipDetailsDaoUtil.class.getSimpleName();
    private DaoManager mManager;

    public ShipDetailsDaoUtil(Context context) {
        mManager = DaoManager.getInstance();
        mManager.init(context);
    }

    /**
     * 完成ShipDetailsBean记录的插入,如果表未创建,先创建ShipDetailsBean表
     *
     * @param ShipDetailsBean
     * @return
     */
    public boolean insertShipDetailsBean(ShipDetailsBean ShipDetailsBean) {
        boolean flag = false;
        flag = mManager.getDaoSession().getShipDetailsBeanDao().insert(ShipDetailsBean) == -1 ? false : true;
        Log.i(TAG, "insert ShipDetailsBean :" + flag + "-->" + ShipDetailsBean.toString());
        return flag;
    }

    /**
     * 插入多条数据,在子线程操作
     *
     * @param ShipDetailsBeanList
     * @return
     */
    public boolean insertMultShipDetailsBean(final List<ShipDetailsBean> ShipDetailsBeanList) {
        boolean flag = false;
        try {
            mManager.getDaoSession().runInTx(new Runnable() {
                @Override
                public void run() {
                    for (ShipDetailsBean ShipDetailsBean : ShipDetailsBeanList) {
                        mManager.getDaoSession().insertOrReplace(ShipDetailsBean);
                    }
                }
            });
            flag = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }

    /**
     * 修改一条数据
     *
     * @param ShipDetailsBean
     * @return
     */
    public boolean updateShipDetailsBean(ShipDetailsBean ShipDetailsBean) {
        boolean flag = false;
        try {
            mManager.getDaoSession().update(ShipDetailsBean);
            flag = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }

    /**
     * 删除单条记录
     *
     * @param ShipDetailsBean
     * @return
     */
    public boolean deleteShipDetailsBean(ShipDetailsBean ShipDetailsBean) {
        boolean flag = false;
        try {
            //按照id删除
            mManager.getDaoSession().delete(ShipDetailsBean);
            flag = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }

    /**
     * 删除所有记录
     *
     * @return
     */
    public boolean deleteAll() {
        boolean flag = false;
        try {
            //按照id删除
            mManager.getDaoSession().deleteAll(ShipDetailsBean.class);
            flag = true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }

    /**
     * 查询所有记录
     *
     * @return
     */
    public List<ShipDetailsBean> queryAllShipDetailsBean() {
        return mManager.getDaoSession().loadAll(ShipDetailsBean.class);
    }

    /**
     * 根据主键id查询记录
     *
     * @param key
     * @return
     */
    public ShipDetailsBean queryShipDetailsBeanById(long key) {
        return mManager.getDaoSession().load(ShipDetailsBean.class, key);
    }

    /**
     * 使用native sql进行查询操作
     */
    public List<ShipDetailsBean> queryShipDetailsBeanByNativeSql(String sql, String[] conditions) {
        return mManager.getDaoSession().queryRaw(ShipDetailsBean.class, sql, conditions);
    }

    /**
     * 使用queryBuilder进行查询
     *
     * @return
     */
    public List<ShipDetailsBean> queryShipDetailsBeanByQueryBuilder(String id) {
        QueryBuilder<ShipDetailsBean> queryBuilder = mManager.getDaoSession().queryBuilder(ShipDetailsBean.class);
        return queryBuilder.where(ShipDetailsBeanDao.Properties.ShipName.eq(id)).list();
    }

    /**
     * 模糊查询
     *
     * @param value
     * @return
     */
    public List<ShipDetailsBean> getCarsByLike(String value) {
        return mManager.getDaoSession().queryBuilder(ShipDetailsBean.class).where(ShipDetailsBeanDao.Properties.ShipName.like("%" + value + "%")).list();
    }
}

 /**
 * 多条件模糊查询
 *
 * @param value
 * @return
 */
 public List<ShipDetailsBean> getShipsByLike(String value) {
    return mManager.getDaoSession().queryBuilder(ShipDetailsBean.class)
                .whereOr(ShipDetailsBeanDao.Properties.ShipName.like("%" + value + "%"), ShipDetailsBeanDao.Properties.Mmsi.like("%" + value + "%")).list();
    }

三、代码中调用XXXUtils进行增删改查

①单个插入操作: mUserDaoUtils.insertMeizi(new User(null, "an","28"));

②批量插入操作:

List<User> users= new ArrayList<>();
users.add(new User(null, "an""28"));
users.add(new User(null, "an""28"));
users.addnew User(null, "an""28"));
mUserDaoUtils.insertMultUser(users);

③单个更改操作:(其中原有的数据都不会保存,如果新建的对象有属性没有设置,则会为空,不为空的字段没有设置,则报错)

User user= new User();
user.set_id(1002l);
user.setName("fei");
mUserDaoUtils.updateUser(user);

④删除某条记录操作

User user= new User();
user.set_id(1002l);
mUserDaoUtils.deleteUser(user);

⑤删除所有记录操作
mUserDaoUtils.deleteAll();

⑥查询所有记录

mUserDaoUtils.queryMeiziById(1008l).toString();

⑦根据主键查询记录

List<User> UserList = mUserDaoUtils.queryAllMeizi();

⑧各种条件查询:使用native sql进行条件查询:

String sql = "where _id > ?";
String[] condition = new String[]{"1008"};
List<User> UserList = mUserDaoUtils.queryUsrByNativeSql(sql, condition);

⑨使用queryBuilder进行条件查询

QueryBuilder能够让你在不涉及SQL语句的情况下查询实体。写SQL有几个缺点,首先是易错的,其次是要在运行时才知道有没有问题(假如属性名是pid,你写成了id,也要到运营时才会崩溃),QueryBuilder能够在编译时检查错误(如属性的引用是否错误)。 
关于Api:在org.greenrobot.greendao.query包下,QueryBuilder类中查看其方法;构造函数可以传递我们的Xxx实体类型,查询方法有很多逻辑的where方法。where方法中需要设置WhereCondition类型的条件参数,而在org.greenrobot.greendao包下的Property类中,每一种操作符的方法都返回WhereCondition类型。获取Property实例则不需要我们去做,在我们的XxxDao中已经有对应的提供,例如我们这里的MeiziDao.Properties.XXX。
List<User> UserList = mUserDaoUtils.queryMeiziByQueryBuilder(1008);

LazyList懒加载是指一次性查完数据保存在内存中,然后关闭所有连接,再次查询时从内存中获取。一般查询大数据量时用。

三、参考:http://blog.csdn.net/bskfnvjtlyzmv867/article/details/71250101

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值