3.GreenDao简单使用

一、GreenDao 简介

 

        GreenDAO 是一款开源的面向 Android 的轻便、快捷的 ORM 框架,将 Java 对象映射到 SQLite 数据库中,我们操作数据库的时候,不再需要编写复杂的 SQL语句, 在性能方面,greenDAO 针对 Android 进行了高度优化,最小的内存开销 、依赖体积小 同时还是支持 数据库加密。

        greenDAO 官网地址:greenrobot.org/greendao/

        greenDAO GitHub 源码地址:greenrobot/greenDAO

二、GreenDao 特征

    1、支持 protocol buffer(protobuf) 协议
    GreenDao 支持 protocol buffer(protobuf) 协议数据的直接存储,如果你通过 protobuf 协议与服务器交互,将不需要任何的映射
    2、代码生成
    greenDAO 会根据配置信息自动生成核心管理类以及 DAO 对象
    3、性能
    所有 ORM 数据库的,greenDAO 是最快的,greenDAO 不作性能方面任何妥协

三、核心类介绍

1、DaoMaster:

使用 greenDAO 的入口点。DaoMaster 负责管理数据库对象(SQLiteDatabase)和 DAO 类(对象),我们可以通过它内部类 OpenHelper 和 DevOpenHelper SQLiteOpenHelper 创建不同模式的 SQLite 数据库。
2、DaoSession :

管理指定模式下的所有 DAO 对象,DaoSession 提供了一些通用的持久性方法比如插入、负载、更新和删除实体。
3、XxxDAO :

对于每个实体类, greenDAO 都会生成一个与之对应 DAO 对象,如:User 实体,则会生成一个 UserDao 类
4、Entities:

可持久化对象。通常,实体对象代表一个数据库行,使用标准 Java 属性(如一个 POJO 或 JavaBean )
 

 

四、集成 GreenDao

a、设置仓库与插件(Project: build.gradle)

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

b、配置依赖 ( Module:app build.gradle )

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

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

    // This is only needed if you want to use encrypted databases
    compile 'net.zetetic:android-database-sqlcipher:3.5.6' //加密库依赖(可选项)
}

c、配置数据库相关信息 ( Module:app build.gradle )

greendao {
    schemaVersion 1 // 数据库版本号
    daoPackage 'com.example.zhangruirui.greendao'  // 设置 DaoMaster、DaoSession、Dao 包名
    targetGenDir 'src/main/java'  // 设置 DaoMaster、DaoSession、Dao 目录
}

d、基本使用步骤

// 生成数据库文件,名为 students-db
DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(this, "students-db", null);
SQLiteDatabase db = helper.getWritableDatabase();
// 建立特定模式下的所有的 DAO 对象和数据 db 对象的映射
DaoMaster master = new DaoMaster(db);
// 管理特定模式下的所有 DAO 对象,并提供一些通用的 CRUD 持久化方法
DaoSession session = master.newSession();
// 得到指定的 StudentDao 对象
StudentDao dao = session.getStudentDao();
dao.insert(student);
//...

五、实战

1、我们写一个简单的实体类(User),测试一下

import org.greenrobot.greendao.annotation.Entity;
import org.greenrobot.greendao.annotation.Generated;
import org.greenrobot.greendao.annotation.Id;

@Entity
public class User {

  @Id
  private long id;

  private String name;

  private int age;

  @Generated(hash = 446251977)
  public User(long id, String name, int age) {
    this.id = id;
    this.name = name;
    this.age = age;
  }

  @Generated(hash = 586692638)
  public User() {
  }

  public long getId() {
    return id;
  }

  public void setId(long id) {
    this.id = id;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public int getAge() {
    return age;
  }

  public void setAge(int age) {
    this.age = age;
  }
}

2、点击 Make Project(或者 Make Moudle ‘App’) 编译一下工程 。如果配置正确,会在配置的包目录下自动会生成 DaoMaster,DaoSession 和 UserDao 类 。

3、然后我们定义 OpenHelper 类:UserDBOpenHelper

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;

import com.example.zhangruirui.DaoMaster;

public class UserDBOpenHelper extends DaoMaster.DevOpenHelper {
  public UserDBOpenHelper(Context context, String name) {
    super(context, name);
  }

  public UserDBOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory) {
    super(context, name, factory);
  }

  @Override
  public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    DaoMaster.dropAllTables(wrap(db), true);
  }
}

4、然后,类似 SQLite ,我们需要定义 DBManager:UserManager 创建单例实例,来供外部操作数据库

import android.content.Context;
import android.support.annotation.WorkerThread;

import com.google.gson.Gson;

import java.io.Serializable;
import java.lang.reflect.Type;

public class UserManager {
  private volatile static UserManager mInstance = null;
  private Context mContext;
  private UserStorage mUserStorage = new UserStorage(mContext);

  private UserManager() {

  }

  public static UserManager getInstance() {
    if (mInstance == null) {
      synchronized (UserManager.class) {
        if (mInstance == null) {
          mInstance = new UserManager();
        }
      }
    }
    return mInstance;
  }

  public <T> T getUserAge(String key, Type typeOfT) {
    try {
      String json = mUserStorage.getUserAge(key);
      Gson gson = new Gson();

      CacheEntry entry = gson.fromJson(json, CacheEntry.class);
      return gson.fromJson(entry.mJson, typeOfT);
    } catch (Exception e) {
      e.printStackTrace();
    }
    return null;
  }

  @WorkerThread
  public void setUserAge(String key, Object entity, Type type) {
    setUserInner(key, entity, type);
  }

  @WorkerThread
  private void setUserInner(String key, Object entity, Type type) {
    Gson gson = new Gson();
    String json = gson.toJson(entity, type);
    CacheEntry entry = new CacheEntry(json);
    json = gson.toJson(entry, CacheEntry.class);
    if (entity == null) {
      mUserStorage.removeUser(key);
    } else {
      mUserStorage.addUser(key, json);
    }
  }

  static class CacheEntry implements Serializable {

    final String mJson;

    CacheEntry(String json) {
      mJson = json;
    }
  }
}

5、获取 UserDao 对数据库表进行 CRUD 操作即可:UserStorage

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.support.annotation.WorkerThread;

import com.example.cui.User;

import org.greenrobot.greendao.query.DeleteQuery;
import org.greenrobot.greendao.query.QueryBuilder;

public class UserStorage {

  private SQLiteDatabase mDatabase;
  private UserDao mUserDao; // 获取 dao 对象
  private final static String DB_NAME = "user_name_age.db"; // 定义数据库名

  // 获取核心类的实例
  UserStorage(Context context) {
    DaoMaster.OpenHelper helper = new UserDBOpenHelper(context, DB_NAME, null);
    try {
      mDatabase = helper.getWritableDatabase();
      DaoMaster daoMaster = new DaoMaster(mDatabase);
      DaoSession daoSession = daoMaster.newSession();
      mUserDao = daoSession.getUserDao();

    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  public User getUserByName(String name) {
    if (!isDataBaseValid()) {
      return null;
    }

    return mUserDao.queryBuilder().where(UserDao.Properties.Name.eq(name)).unique();

  }

  /**
   * 根据用户的名字删除对应的记录
   */
  public void removeUser(String name) {
    if (!isDataBaseValid()) {
      return;
    }
    try {
      QueryBuilder<User> qb = mUserDao.queryBuilder();
      DeleteQuery<User> bd = qb.where(UserDao.Properties.Name.eq(name))
          .buildDelete();
      bd.executeDeleteWithoutDetachingEntities();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  /**
   * 新增记录,如果存在则更新,不存在直接插入
   */
  @WorkerThread
  public synchronized void addUser(String name, String json) {
    if (!isDataBaseValid()) {
      return;
    }

    try {
      User user = new User();
      user.setName(name);
      user.setAge(json);

      /**
       * 解决 Exception:
       * Cannot update entity without key - was it inserted before?
       */
      User oldUser = getUserByName(name);
      if (oldUser != null) {
        user.setId(oldUser.getId());
      }
      // mUserDao.save(user);
      if (getUserByName(name) == null) {
        mUserDao.insert(user);
      } else {
        mUserDao.update(user);
      }
    } catch (Exception e) {
      e.printStackTrace();
    }
  }

  /**
   * 删除所有数据
   */
  @WorkerThread
  public synchronized void deleteAll() {
    mUserDao.deleteAll();
  }

  private boolean isDataBaseValid() {
    return mUserDao != null;
  }

  public String getUserAge(String key) {
    return mUserDao.queryBuilder().where(UserDao.Properties.Name.eq(key)).list().get(0).getAge();
  }
}

六、注解

@Entity

表明这个实体类会在数据库中生成一个与之相对应的表

@Entity(
        // If you have more than one schema, you can tell greenDAO
        // to which schema an entity belongs (pick any string as a name).
        schema = "myschema",
        
        // Flag to make an entity "active": Active entities have update,
        // delete, and refresh methods.
        active = true,
        
        // Specifies the name of the table in the database.
        // By default, the name is based on the entities class name.
        nameInDb = "AWESOME_USERS",
        
        // Define indexes spanning multiple columns here.
        indexes = {
                @Index(value = "name DESC", unique = true)
        },
        
        // Flag if the DAO should create the database table (default is true).
        // Set this to false, if you have multiple entities mapping to one table,
        // or the table creation is done outside of greenDAO.
        createInDb = false,

        // Whether an all properties constructor should be generated.
        // A no-args constructor is always required.
        generateConstructors = true,

        // Whether getters and setters for properties should be generated if missing.
        generateGettersSetters = true
)
public class User {
  ...
}

@Id(autoincrement = true)

对应数据表中的 Id 字段,主键,必须为 Long 型
如果需要使用主键自增,此时 id 类型为 Long(注意是大写的)

@Transient

添加此标记后不会生成数据库表的列,仅仅作为一个普通的 java 类字段,用来临时存储数据的,不会被持久化

@Unique

表名该属性在数据库中只能有唯一值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值