1.比起ormlite等其他库,greendao性能更优
greendao的特点:
最大性能(可能是Android最快的ORM);我们的基准也是开源的。
易于使用的强大API覆盖关系和连接。
最小的内存消耗。
小库的大小(小于100KB)保持你的建造时间低和避免65 K法限制。
数据库加密:greendao支持SQLCipher来保持你的用户的数据安全。
强大的社区:超过5 GitHub的恒星显示有强大和活跃的社区。
2.添加依赖
1)在build.gradle(Project)添加下面这一行代码
classpath 'org.greenrobot:greendao-gradle-plugin:3.0.0'
示例:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.3'
classpath 'org.greenrobot:greendao-gradle-plugin:3.0.0'
}
}
2.在build.gradle(Module),添加下面的代码
apply plugin: 'org.greenrobot.greendao'
compile'org.greenrobot:greendao:3.0.1'
compile'org.greenrobot:greendao-generator:3.0.0'
greendao {
schemaVersion 3 //版本
daoPackage 'com.example.testretrofitrxjava.db.helper' // 一般为app包名+生成文件的文件夹名
targetGenDir 'src/main/java' //生成文件路径
}
示例:
apply plugin: 'com.android.application'
apply plugin: 'org.greenrobot.greendao'
android {
compileSdkVersion 25
buildToolsVersion "25.0.3"
defaultConfig {
applicationId "com.example.testretrofitrxjava"
minSdkVersion 15
targetSdkVersion 25
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile'org.greenrobot:greendao:3.0.1'
compile'org.greenrobot:greendao-generator:3.0.0'
}
greendao {
schemaVersion 3 //版本
daoPackage 'com.example.testretrofitrxjava.db.helper' //自己新建的包名路径,DaoMaster.java和DaoSession.java在此包里面生成
targetGenDir 'src/main/java' //生成文件路径
}
3.添加好依赖,下面开始写代码
1)新建一个User类,对应数据库的一张表(下面的构造方法和get,set方法都是自动生成)
@Entity //实体注解,默认表名User
public class User {
@Id(autoincrement = true)//主键自增,必须是Long类型
private Long id;
@Property //@Property(nameInDb = "NAME")自定义数据库列的名称,默认是name
private String name;
@Property
private Integer age;
@Property
private Integer weight;
@Transient //@Transient添加此标记之后不会生成数据库表的列
private String test;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public Long getId() {
return this.id;
}
public void setId(Long id) {
this.id = id;
}
public Integer getAge() {
return this.age;
}
public void setAge(Integer age) {
this.age = age;
}
public void setWeight(Integer weight) {
this.weight = weight;
}
public Integer getWeight() {
return this.weight;
}
@Generated(hash = 1840779289)
public User(Long id, String name, Integer age, Integer weight) {
this.id = id;
this.name = name;
this.age = age;
this.weight = weight;
}
@Generated(hash = 586692638)
public User() {
}
}
2)创建完User类之后,重新 Make Project(快捷键:Ctrl+f9),就会在指定的路径自动生成DaoMaster.java和DaoSession.java
这是我的项目路径生成的
3)为了方便管理,写一个数据库管理类
public class DBHelper {
private static final String TAG = "DBHelper";
private static MyOpenHelper mHelper;
private static Database db;
private static DaoMaster mDaoMaster;
private static DaoSession mDaoSession;
/**
* 设置greenDao,在application的onCreate方法初始化
*/
public static void initDb(Context context) {
if (mHelper != null) {
return;
}
/**context 上下文
* test-db 数据库名称
*/
mHelper = new MyOpenHelper(context, "test-db", null);
db = mHelper.getWritableDb();
mDaoMaster = new DaoMaster(db);
mDaoSession = mDaoMaster.newSession();
}
public static DaoSession getDaoSession() {
return mDaoSession;
}
/**
* 默认DaoMaster.OpenHelper,数据库升级删除之前所有的数据
* 自定义MyOpenHelper,实际开发中,数据库升级要保存原先的数据
*/
private static class MyOpenHelper extends DaoMaster.OpenHelper {
public MyOpenHelper(Context context, String name) {
super(context, name);
}
public MyOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory) {
super(context, name, factory);
}
@Override
public void onCreate(Database db) {
super.onCreate(db);
}
@Override
public void onUpgrade(Database db, int oldVersion, int newVersion) {
// super.onUpgrade(db, oldVersion, newVersion);
Log.e(TAG, "onUpgrade: 更新啦");
MigrationHelper.getInstance().migrate(db, UserDao.class, SchoolDao.class);
}
}
}
数据库升级辅助类(网上copy)
/**
* 这是一个数据库升级保存数据的辅助类
*/
public class MigrationHelper {
private static final String CONVERSION_CLASS_NOT_FOUND_EXCEPTION = "MIGRATION HELPER - CLASS DOESN'T MATCH WITH THE CURRENT PARAMETERS";
private static MigrationHelper instance;
public static MigrationHelper getInstance() {
if (instance == null) {
instance = new MigrationHelper();
}
return instance;
}
public void migrate(Database db, Class<? extends AbstractDao<?, ?>>... daoClasses) {
generateTempTables(db, daoClasses);
DaoMaster.dropAllTables(db, true);
DaoMaster.createAllTables(db, false);
restoreData(db, daoClasses);
}
/**
* 生成临时列表
*
* @param db
* @param daoClasses
*/
private void generateTempTables(Database db, Class<? extends AbstractDao<?, ?>>... daoClasses) {
for (int i = 0; i < daoClasses.length; i++) {
DaoConfig daoConfig = new DaoConfig(db, daoClasses[i]);
String divider = "";
String tableName = daoConfig.tablename;
String tempTableName = daoConfig.tablename.concat("_TEMP");
ArrayList<String> properties = new ArrayList<>();
StringBuilder createTableStringBuilder = new StringBuilder();
createTableStringBuilder.append("CREATE TABLE ").append(tempTableName).append(" (");
for (int j = 0; j < daoConfig.properties.length; j++) {
String columnName = daoConfig.properties[j].columnName;
if (getColumns(db, tableName).contains(columnName)) {
properties.add(columnName);
String type = null;
try {
type = getTypeByClass(daoConfig.properties[j].type);
} catch (Exception exception) {
exception.printStackTrace();
}
createTableStringBuilder.append(divider).append(columnName).append(" ").append(type);
if (daoConfig.properties[j].primaryKey) {
createTableStringBuilder.append(" PRIMARY KEY");
}
divider = ",";
}
}
createTableStringBuilder.append(");");
db.execSQL(createTableStringBuilder.toString());
StringBuilder insertTableStringBuilder = new StringBuilder();
insertTableStringBuilder.append("INSERT INTO ").append(tempTableName).append(" (");
insertTableStringBuilder.append(TextUtils.join(",", properties));
insertTableStringBuilder.append(") SELECT ");
insertTableStringBuilder.append(TextUtils.join(",", properties));
insertTableStringBuilder.append(" FROM ").append(tableName).append(";");
db.execSQL(insertTableStringBuilder.toString());
}
}
/**
* 存储新的数据库表 以及数据
*
* @param db
* @param daoClasses
*/
private void restoreData(Database db, Class<? extends AbstractDao<?, ?>>... daoClasses) {
for (int i = 0; i < daoClasses.length; i++) {
DaoConfig daoConfig = new DaoConfig(db, daoClasses[i]);
String tableName = daoConfig.tablename;
String tempTableName = daoConfig.tablename.concat("_TEMP");
ArrayList<String> properties = new ArrayList();
for (int j = 0; j < daoConfig.properties.length; j++) {
String columnName = daoConfig.properties[j].columnName;
if (getColumns(db, tempTableName).contains(columnName)) {
properties.add(columnName);
}
}
StringBuilder insertTableStringBuilder = new StringBuilder();
insertTableStringBuilder.append("INSERT INTO ").append(tableName).append(" (");
insertTableStringBuilder.append(TextUtils.join(",", properties));
insertTableStringBuilder.append(") SELECT ");
insertTableStringBuilder.append(TextUtils.join(",", properties));
insertTableStringBuilder.append(" FROM ").append(tempTableName).append(";");
StringBuilder dropTableStringBuilder = new StringBuilder();
dropTableStringBuilder.append("DROP TABLE ").append(tempTableName);
db.execSQL(insertTableStringBuilder.toString());
db.execSQL(dropTableStringBuilder.toString());
}
}
private String getTypeByClass(Class<?> type) throws Exception {
if (type.equals(String.class)) {
return "TEXT";
}
if (type.equals(Long.class) || type.equals(Integer.class) || type.equals(long.class)) {
return "INTEGER";
}
if (type.equals(Boolean.class)) {
return "BOOLEAN";
}
Exception exception = new Exception(CONVERSION_CLASS_NOT_FOUND_EXCEPTION.concat(" - Class: ").concat(type.toString()));
exception.printStackTrace();
throw exception;
}
private List<String> getColumns(Database db, String tableName) {
List<String> columns = new ArrayList<>();
Cursor cursor = null;
try {
cursor = db.rawQuery("SELECT * FROM " + tableName + " limit 1", null);
if (cursor != null) {
columns = new ArrayList<>(Arrays.asList(cursor.getColumnNames()));
}
} catch (Exception e) {
Log.v(tableName, e.getMessage(), e);
e.printStackTrace();
} finally {
if (cursor != null)
cursor.close();
}
return columns;
}
}
4.操作数据库(相对比较简单的操作)
1)添加
User user = new User();
user.setName("张三" + i);
user.setAge(i);
user.setWeight(50 + i);
DBHelper.getDaoSession().getUserDao().insert(user);//插入数据
//DBHelper.getDaoSession().getUserDao().insertOrReplace(user);//如果存在替换,不存在就添加
2)删除
根据对象删除
User user = DBHelper.getDaoSession().getUserDao().queryBuilder().limit(1).unique();
DBHelper.getDaoSession().getUserDao().delete(user);
根据主键删除
DBHelper.getDaoSession().getUserDao().deleteByKey(1L);
删除全部
DBHelper.getDaoSession().getUserDao().deleteAll();
3)查询
查询全部
DBHelper.getDaoSession().getUserDao().loadAll();
条件查询(queryBuilder())
//查询名字叫张三的人
DBHelper.getDaoSession().getUserDao().queryBuilder().where(UserDao.Properties.Name.eq("张三")).list();
//查找年龄超过10岁的人(包含10岁)
DBHelper.getDaoSession().getUserDao().queryBuilder().where(UserDao.Properties.Age.ge(10)).list();
4)修改
//名称改为“李四”
User user = DBHelper.getDaoSession().getUserDao().queryBuilder().limit(1).unique();
user.setName("李四");
DBHelper.getDaoSession().getUserDao().update(user);
5.假如要修改表结构或者添加表,就要升级数据库
这里示例是修改表结构
第一步:修改版本号,原来的版本加1
greendao {
schemaVersion 3 //版本,升级数据库的是加1
daoPackage 'com.example.testretrofitrxjava.db.helper' // 自己新建的包名路径,DaoMaster.java和DaoSession.java在此包里面下生成
targetGenDir 'src/main/java' //生成文件路径
}
第二步:在对应的实体类操作,这里要注意,添加的新成员不能使用(int long等基本类型),要使用对应的封装类Integer或者Long,不然运行就会出错
示例
@Property
private Integer newAddData;//不能用int类型
第三步:(Ctrl+f9)Make Project
6.如果想要加密数据,获取加密的数据库
mHelper.getEncryptedWritableDb("EncryptedWritableDb");