GreenDao3.2使用

听说GreenDao数据库效率高,那么现在开始使用它。

GreenDao项目地址

第一步
配置项目build.gradle,
在对应位置添加:

classpath 'org.greenrobot:greendao-gradle-plugin:3.2.1'
mavenCentral()

修改后的文件:

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:2.3.0-beta4'
        classpath 'org.greenrobot:greendao-gradle-plugin:3.2.1'
        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        jcenter()
        mavenCentral()
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

第二步:
修改module目录下的build.gradle文件:
对应位置添加:

apply plugin: 'org.greenrobot.greendao'
compile 'org.greenrobot:greendao:3.2.0'

修改后的文件:

apply plugin: 'com.android.application'
apply plugin: 'org.greenrobot.greendao'
android {
    compileSdkVersion 25
    buildToolsVersion "25.0.2"
    defaultConfig {
        applicationId "xyz.reginer.greendao"
        minSdkVersion 18
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.1.1'
    testCompile 'junit:junit:4.12'
    compile 'org.greenrobot:greendao:3.2.0'
}

第三步 :
添加greendao的数据库版本号:
生成的操作类可以不指定路径。

greendao {
    schemaVersion 1
}

修改后的文件:

apply plugin: 'com.android.application'
apply plugin: 'org.greenrobot.greendao'
android {
    compileSdkVersion 25
    buildToolsVersion "25.0.2"
    defaultConfig {
        applicationId "xyz.reginer.greendao"
        minSdkVersion 18
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}
greendao {
    schemaVersion 1
}
dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:25.1.1'
    testCompile 'junit:junit:4.12'
    compile 'org.greenrobot:greendao:3.2.0'
}

第四步:
创建实体类(数据库表,字段)
这里做下注解说明:

@Entity:告诉GreenDao该对象为实体,只有被@Entity注释的Bean类才能被dao类操作

@Id:对象的Id,使用Long类型作为EntityId,否则报错。(autoincrement = true)表示主键会自增,false使用旧值

@Unique:该属性值必须在数据库中是唯一值

@Property:可以自定义字段名,外键不能使用该属性

@NotNull:属性不能为空

@Transient:使用该注释的属性不会被存入数据库的字段中

@Generated:编译后自动生成的构造函数、方法等的注释,提示构造函数、方法等不能被修改
@Entity
public class User {
    //不能用int
    @Id(autoincrement = true)
    private Long id;
    @Property(nameInDb = "name")
    private String name;
    @Unique
    private String QQ;
    private int age;
    private String address;

}

build之后:

package xyz.reginer.greendao;

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

/**
 * ----------Dragon be here!----------/
 *    ┏┓   ┏┓
 *   ┏┛┻━━━┛┻┓
 *   ┃       ┃
 *   ┃   ━   ┃
 *   ┃ ┳┛ ┗┳ ┃
 *   ┃       ┃
 *   ┃   ┻   ┃
 *   ┃       ┃
 *   ┗━┓   ┏━┛
 *     ┃   ┃神兽保佑
 *     ┃   ┃代码无BUG!
 *     ┃   ┗━━━┓
 *     ┃       ┣┓
 *     ┃       ┏┛
 *     ┗┓┓┏━┳┓┏┛
 *      ┃┫┫ ┃┫┫
 *      ┗┻┛ ┗┻┛
 * ━━━━━━神兽出没━━━━━━
 * 创   建:Reginer in  2017/2/15 11:18.
 * 联系方式:QQ:282921012
 * 功能描述:bean对象
 */
@Entity
public class User {
    //不能用int
    @Id(autoincrement = true)
    private Long id;
    @Property(nameInDb = "name")
    private String name;
    @Unique
    private int QQ;
    private int age;
    private String address;

    /**
     * 这部分是我创建的
     *
     * @param name    昵称
     * @param QQ      QQ
     * @param age     年龄
     * @param address 住址
     */
    public User(String name, int QQ, int age, String address) {
        this.name = name;
        this.QQ = QQ;
        this.age = age;
        this.address = address;
    }

    @Generated(hash = 964878038)
    public User(Long id, String name, int QQ, int age, String address) {
        this.id = id;
        this.name = name;
        this.QQ = QQ;
        this.age = age;
        this.address = address;
    }

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

    public Long getId() {
        return this.id;
    }

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

    public String getName() {
        return this.name;
    }

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

    public int getQQ() {
        return this.QQ;
    }

    public void setQQ(int QQ) {
        this.QQ = QQ;
    }

    public int getAge() {
        return this.age;
    }

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

    public String getAddress() {
        return this.address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

}

第五步:
创建数据库帮助类:

public class DbHelper extends DaoMaster.OpenHelper {

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

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        super.onUpgrade(db, oldVersion, newVersion);
    }

}

第六步:
创建Application类:

public class App extends Application {

    private DaoSession daoSession;

    @Override
    public void onCreate() {
        super.onCreate();

        DbHelper helper = new DbHelper(this, "user.db", null);
        Database db = helper.getWritableDb();
        daoSession = new DaoMaster(db).newSession();
    }

    public DaoSession getDaoSession() {
        return daoSession;
    }
}

第七步:
正式操作:
增:

private void add() {
        //____________________保存一个————————
        User user = new User("那时年少", 282921012, 25, "大连");
        mUserDao.insert(user);

        //____________________保存list————————
        List<User> mUsers = new ArrayList<>();
        for (int i = 0; i < 50; i++) {
            mUsers.add(new User("那时年少" + i, i, 25, "大连"));
        }
        mUserDao.insertInTx(mUsers);
    }

删:

private void del() {
        mUserDao.deleteByKey((long) 1);
//        删除单个数据
//        mUserDao().delete(user);
//        删除多个数据
//        mUserDao().deleteInTx(userList);
    }

改:

private void up() {
        User user = new User((long) 3, "那时年少", 282921012, 25, "伊拉克");
        mUserDao.update(user);
    }

查:

private void query() {
        //--------------------------查询全部---------
        List<User> mUsers = mUserDao.loadAll();
        // List< User> mUsers = mUserDao.queryBuilder().list();
        //--------------------------条件查询---------
        List<User> users = mUserDao.queryBuilder().where(UserDao.Properties.QQ.le(20)).list();
        Log.d(TAG, "mUsers.size is:: " + mUsers.size() + "--- users.size is::" + users.size());
    }

八:数据库升级:
借用网上一个工具类MigrationHelper:

public class MigrationHelper {
    /**
     * 调用升级方法
     *
     * @param db         db
     * @param daoClasses dao.class
     */
    @SafeVarargs
    public static void migrate(Database db, Class<? extends AbstractDao<?, ?>>... daoClasses) {
        //1 新建临时表
        generateTempTables(db, daoClasses);
        //2 创建新表
        createAllTables(db, false, daoClasses);
        //3 临时表数据写入新表,删除临时表
        restoreData(db, daoClasses);
    }


    /**
     * 生成临时表,存储旧的表数据
     *
     * @param db         db
     * @param daoClasses daoClasses
     */
    @SafeVarargs
    private static void generateTempTables(Database db, Class<? extends AbstractDao<?, ?>>... daoClasses) {
        for (Class<? extends AbstractDao<?, ?>> daoClass : daoClasses) {
            DaoConfig daoConfig = new DaoConfig(db, daoClass);
            String tableName = daoConfig.tablename;
            if (!checkTable(db, tableName))
                continue;
            String tempTableName = daoConfig.tablename.concat("_TEMP");
            String insertTableStringBuilder = "alter table " +
                    tableName +
                    " rename to " +
                    tempTableName +
                    ";";
            db.execSQL(insertTableStringBuilder);
        }
    }

    /**
     * 检测table是否存在
     *
     * @param db        db
     * @param tableName tableName
     */
    private static Boolean checkTable(Database db, String tableName) {
        Cursor c = db.rawQuery("SELECT count(*) FROM sqlite_master WHERE type='table' AND name='" + tableName + "'", null);
        if (c.moveToNext()) {
            int count = c.getInt(0);
            return count > 0;
        }
        return false;
    }


    /**
     * 创建新的表结构
     *
     * @param db          db
     * @param ifNotExists ifNotExists
     * @param daoClasses  daoClasses
     */
    @SafeVarargs
    private static void createAllTables(Database db, boolean ifNotExists, @NonNull Class<? extends AbstractDao<?, ?>>... daoClasses) {
        reflectMethod(db, "createTable", ifNotExists, daoClasses);
    }

    /**
     * 创建根删除都在NoteDao声明了,可以直接拿过来用
     * dao class already define the sql exec method, so just invoke it
     */
    @SuppressWarnings("unchecked")
    private static void reflectMethod(Database db, String methodName, boolean isExists, @NonNull Class<? extends AbstractDao<?, ?>>... daoClasses) {
        if (daoClasses.length < 1) {
            return;
        }
        try {
            for (Class cls : daoClasses) {
                //根据方法名,找到声明的方法
                Method method = cls.getDeclaredMethod(methodName, Database.class, boolean.class);
                method.invoke(null, db, isExists);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 临时表的数据写入新表
     *
     * @param db         db
     * @param daoClasses daoClasses
     */
    @SafeVarargs
    private static void restoreData(Database db, Class<? extends AbstractDao<?, ?>>... daoClasses) {
        for (Class<? extends AbstractDao<?, ?>> daoClass : daoClasses) {
            DaoConfig daoConfig = new DaoConfig(db, daoClass);
            String tableName = daoConfig.tablename;
            String tempTableName = daoConfig.tablename.concat("_TEMP");
            if (!checkTable(db, tempTableName))
                continue;
            // get all columns from tempTable, take careful to use the columns list
            List<String> columns = getColumns(db, tempTableName);
            //新表,临时表都包含的字段
            ArrayList<String> properties = new ArrayList<>(columns.size());
            for (int j = 0; j < daoConfig.properties.length; j++) {
                String columnName = daoConfig.properties[j].columnName;
                if (columns.contains(columnName)) {
                    properties.add(columnName);
                }
            }
            if (properties.size() > 0) {
                final String columnSQL = TextUtils.join(",", properties);

                String insertTableStringBuilder = "INSERT INTO " + tableName + " (" +
                        columnSQL +
                        ") SELECT " +
                        columnSQL +
                        " FROM " + tempTableName + ";";
                db.execSQL(insertTableStringBuilder);
            }
            db.execSQL("DROP TABLE " + tempTableName);
        }
    }

    private static List<String> getColumns(Database db, String tableName) {
        List<String> columns = null;
        Cursor cursor = null;
        try {
            cursor = db.rawQuery("SELECT * FROM " + tableName + " limit 0", null);
            if (null != cursor && cursor.getColumnCount() > 0) {
                columns = Arrays.asList(cursor.getColumnNames());
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (cursor != null)
                cursor.close();
            if (null == columns)
                columns = new ArrayList<>();
        }
        return columns;
    }

}

在User中添加一个字段girlFriend;

重写升级方法:

@Override
    public void onUpgrade(Database db, int oldVersion, int newVersion) {
        super.onUpgrade(db, oldVersion, newVersion);
        MigrationHelper.migrate(db, UserDao.class);
    }

修改数据库版本号 +1:

schemaVersion 2

九:执行数据库语句:

DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(this, "user.db", null);
SQLiteDatabase db = helper.getWritableDatabase();
String sql = "这里是语句";
db.execSQL(sql);

源码地址

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值