greendao3.0的使用, 以及数据库升级(保留原有数据), 和对应的sqlite写的方式

1, 配置build.gradle

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

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

allprojects {
    repositories {
        jcenter()
    }
}

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

2, 配置app的build.gradle

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

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.3"
    defaultConfig {
        applicationId "com.diandou.demo38_greendaodemo"
        minSdkVersion 15
        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.3.1'
    testCompile 'junit:junit:4.12'
    compile'org.greenrobot:greendao:3.0.1'
    compile'org.greenrobot:greendao-generator:3.0.0'
}
greendao {
    schemaVersion 2
    daoPackage 'com.anye.greendao.gen'
    targetGenDir 'src/main/java'
}

3,编写实体类(这是我格式化之后的 实际在未使用build之前, 只写字段即可)

package com.diandou.demo38_greendaodemo;

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

/**
 * Created by baiya on 2018/1/8.
 */

@Entity
public class User {

    @Id
    private Long id;
    private String name;
    private int age;
    private String sex;
    private String address;
    public String getAddress() {
        return this.address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    public String getSex() {
        return this.sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public int getAge() {
        return this.age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    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;
    }
    @Generated(hash = 96308365)
    public User(Long id, String name, int age, String sex, String address) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.sex = sex;
        this.address = address;
    }
    @Generated(hash = 586692638)
    public User() {
    }


}

4, make project

greendao3.0的使用, 以及数据库升级(保留原有数据), 和对应的sqlite写的方式_第1张图片
5, 此时的项目结构:
greendao3.0的使用, 以及数据库升级(保留原有数据), 和对应的sqlite写的方式_第2张图片
6, App类添加代码..

package com.diandou.demo38_greendaodemo;

import android.app.Application;
import android.database.sqlite.SQLiteDatabase;

import com.anye.greendao.gen.DaoMaster;
import com.anye.greendao.gen.DaoSession;

/**
 * Created by baiya on 2018/1/8.
 */

public class App extends Application {

    private MySQLiteOpenHelper mHelper;
    private SQLiteDatabase db;
    private DaoMaster mDaoMaster;
    private DaoSession mDaoSession;
    public static App instances;


    @Override
    public void onCreate() {
        super.onCreate();
        instances = this;
        setDatabase();

    }

    /**
     * 单例模式
     *
     * @return
     */
    public static App getInstances() {
        return instances;
    }
    /**
     * 设置greenDao
     */
    private void setDatabase() {
        // 通过 DaoMaster 的内部类 DevOpenHelper,你可以得到一个便利的 SQLiteOpenHelper 对象。
        // 可能你已经注意到了,你并不需要去编写「CREATE TABLE」这样的 SQL 语句,因为 greenDAO 已经帮你做了。
        // 注意:默认的 DaoMaster.DevOpenHelper 会在数据库升级时,删除所有的表,意味着这将导致数据的丢失。
        // 所以,在正式的项目中,你还应该做一层封装,来实现数据库的安全升级。
        mHelper = new MySQLiteOpenHelper(this, "notes-db", null);
        db = mHelper.getWritableDatabase();
        // 注意:该数据库连接属于 DaoMaster,所以多个 Session 指的是相同的数据库连接。
        mDaoMaster = new DaoMaster(db);
        mDaoSession = mDaoMaster.newSession();
    }

    public DaoSession getDaoSession() {
        return mDaoSession;
    }

    public SQLiteDatabase getDb() {
        return db;
    }
}

7, Activity中测试增删改查…

package com.diandou.demo38_greendaodemo;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;

import com.anye.greendao.gen.UserDao;

import org.greenrobot.greendao.query.QueryBuilder;

import java.util.List;

public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    int i = 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.add).setOnClickListener(this);
        findViewById(R.id.delete).setOnClickListener(this);
        findViewById(R.id.update).setOnClickListener(this);
        findViewById(R.id.cha).setOnClickListener(this);
    }

    private void add() {

        User user = new User(null, "zhangsan", i, "男", "北京");
        i = i + 1;
        App.getInstances().getDaoSession().insert(user);
        Log.i("-------", "添加成功");

    }

    private void delete() {
        UserDao userDao = App.getInstances().getDaoSession().getUserDao();
        List list = userDao.queryBuilder().list();

        if (list == null || list.isEmpty()) {
            return;
        }
        for (int j = 0; j < list.size(); j++) {
            User user = list.get(j);
            if ("zhangsan".equals(user.getName())) {
                userDao.delete(user);
                Log.i("-------", "删除方法正在删除名字是张三的人");
            }
        }
        Log.i("-------", "删除成功");

    }

    private void update() {

        UserDao userDao = App.getInstances().getDaoSession().getUserDao();
        QueryBuilder builder = userDao.queryBuilder();
        List zhangsan = builder.where(UserDao.Properties.Age.eq(1)).list();
        if (zhangsan == null || zhangsan.isEmpty()) {
            return;
        }
        for (int i = 0; i < zhangsan.size(); i++) {
            User user = zhangsan.get(i);
            user.setName("lisi");
            user.setSex("女");
            App.getInstances().getDaoSession().update(user);
            Log.i("-------", "修改成功");
        }
        List list = App.getInstances().getDaoSession().getUserDao().queryBuilder().list();

        if (list == null || list.isEmpty()) {
            Log.i("-------", "修改方法的暂无数据");
            return;
        }
        for (int j = 0; j < list.size(); j++) {
            User user = list.get(j);
            Log.i("-------修改方法的遍历", "name:[" + user.getName() + "],[age:" + user.getAge() + "],[sex:" + user.getSex() + "],[id" + user.getId() + "]");
        }
    }


    private void cha() {
        UserDao userDao = App.getInstances().getDaoSession().getUserDao();
        QueryBuilder builder = userDao.queryBuilder();
        List list = builder.list();
        if (list == null || list.isEmpty()) {
            Log.i("-------", "所有数据为空");
            return;
        }
        for (int i = 0; i < list.size(); i++) {
            User user = list.get(i);
            String name = user.getName();
            int age = user.getAge();
            Log.i("-------", "allName :  [name:" + name + "],[age:" + age + "],[sex:" + user.getSex() + "],[id:" + user.getId() + "],[address:" + user.getAddress() + "]");
        }
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.add:
                add();
                break;
            case R.id.delete:
                delete();
                break;
            case R.id.update:
                update();
                break;
            case R.id.cha:
                cha();
                break;

        }
    }

}

8, 数据库升级: 比如说是要给user表加个字段了…

greendao {
    schemaVersion 2//这里改为2
    daoPackage 'com.anye.greendao.gen'
    targetGenDir 'src/main/java'
}

package com.diandou.demo38_greendaodemo;

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

/**
 * Created by baiya on 2018/1/8.
 */

@Entity
public class User {

    @Id
    private Long id;
    private String name;
    private int age;
    private String sex;
    private String address;//手动添加一个address子段
    public String getAddress() {
        return this.address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    public String getSex() {
        return this.sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public int getAge() {
        return this.age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    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;
    }
    @Generated(hash = 96308365)
    public User(Long id, String name, int age, String sex, String address) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.sex = sex;
        this.address = address;
    }
    @Generated(hash = 586692638)
    public User() {
    }


}

在build一下..注意此时还需添加一个migrationHelper的类(数据库升级)

package com.diandou.demo38_greendaodemo;


import android.database.Cursor;
import android.text.TextUtils;
import android.util.Log;

import com.anye.greendao.gen.DaoMaster;

import org.greenrobot.greendao.AbstractDao;
import org.greenrobot.greendao.database.Database;
import org.greenrobot.greendao.internal.DaoConfig;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * Created by baiya on 2018/1/8.
 */

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>... 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>... 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 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>... 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 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 getColumns(Database db, String tableName) {
        List 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;
    }
}

再在mysqliteOpenHelper中配置一下…


    @Override
    public void onUpgrade(Database db, int oldVersion, int newVersion) {
        super.onUpgrade(db, oldVersion, newVersion);
        Log.i("version", oldVersion + "---先前和更新之后的版本---" + newVersion);
        if (oldVersion < newVersion) {
            Log.i("version", oldVersion + "---先前和更新之后的版本---" + newVersion);
            MigrationHelper.getInstance().migrate(db, UserDao.class);
            //更改过的实体类(新增的不用加)   更新UserDao文件 可以添加多个  XXDao.class 文件
//             MigrationHelper.getInstance().migrate(db, UserDao.class,XXDao.class);
        }
    }

重新跑到手机上, 可以测试下原有的数据是否还在

ok, 如果我们不想用greendao了, 此时想回到sqlite, 怎么办呢…:
看代码..:

package com.diandou.demo40_greendao_sqlite;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

/**
 * Created by baiya on 2018/2/7.
 */

public class DemoSQLiteOpenHelper extends SQLiteOpenHelper{


    private static final String TAG = "DemoSQLiteOpenHelper";

    public DemoSQLiteOpenHelper(Context context) {
        /**
         * 参数说明:
         *
         * 第一个参数: 上下文
         * 第二个参数: 数据库文件名称
         * 第三个参数: null代表默认的游标工厂
         * 第四个参数: 数据库的版本号 (数据库版本号只增不减)
         *
         */
        super(context, "notes-db", null, 4);
        Log.d(TAG,"DemoSQLiteOpenHelper");
    }

    /**
     * 数据库创建时调用
     *
     * 只有在app第一次安装时才会调用这个方法
     * @param db
     */
    @Override
    public void onCreate(SQLiteDatabase db) {
//        db.execSQL(
//                "create table contactinfo (" +
//                "id integer primary key autoincrement, " +
//                "name varchar(20), " +
//                "phone varchar(20))"
//        );
//        Log.d(TAG,"onCreate");
        db.execSQL("CREATE TABLE " + "\"USER\" (" + //
                "\"_id\" INTEGER PRIMARY KEY ," + // 0: id
                "\"NAME\" TEXT," + // 1: name
                "\"AGE\" INTEGER NOT NULL ," + // 2: age
                "\"SEX\" TEXT," + // 3: sex
                "\"ADDRESS\" TEXT);");
    }

    /**
     * 数据库升级时调用
     *
     * 只有在上面super执行的时候才会执行这个方法
     *
     * @param db
     * @param oldVersion
     * @param newVersion
     */
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

        Log.d(TAG,"onUpgrade + oldVersion: " + oldVersion + "newVersion: " + newVersion);
//        switch (oldVersion) {
//            case 2:
//                db.execSQL(
//                        "create table contactinfo2 (" +
//                        "id integer primary key autoincrement, " +
//                        "name varchar(20), " +
//                        "phone varchar(20))"
//                );   // 判断版本号.如果是老版本, 走upgrade逻辑,创建新的表
//                break;
//            case 3:
//                db.execSQL("alter table contactinfo add category_id integer");
//            default:
//
//        }
    }



}
package com.diandou.demo40_greendao_sqlite;

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

/**
 * Created by baiya on 2018/2/7.
 */

public class DemoDao {
    private DemoSQLiteOpenHelper helper;

    public DemoDao(Context context) {
        helper = new DemoSQLiteOpenHelper(context);
    }

//    /**
//     * 添加一条记录
//     * @param name 联系人姓名
//     * @param phone 联系人电话
//     * @return 返回的是添加后在数据库的行号  -1代表添加失败
//     */
//    public long add(String name, String phone, String category_id){
//        SQLiteDatabase db = helper.getWritableDatabase();
//        //db.execSQL("insert into contactinfo (name,phone) values (?,?)", new Object[]{name,phone});
//        ContentValues values = new ContentValues();
//        values.put("name", name);
//        values.put("phone", phone);
//        values.put("category_id", category_id);
//        //内部是组拼sql语句实现的.
//        long rowid = db.insert("contactinfo", null, values);
//        //记得释放数据库资源
//        db.close();
//        return rowid;
//    }
//    /**
//     * 根据姓名删除一条记录
//     * @param name 要删除的联系人的姓名
//     * @return 返回0代表的是没有删除任何的记录 返回整数int值代表删除了几条数据
//     */
//    public int delete(String name){
//        //判断这个数据是否存在.
//        SQLiteDatabase db = helper.getWritableDatabase();
//        //db.execSQL("delete from contactinfo where name=?", new Object[]{name});
//        int rowcount = db.delete("contactinfo", "name=?", new String[]{name});
//        db.close();
//        //再从数据库里面查询一遍,看name是否还在
//        return rowcount;
//    }
//    /**
//     * 修改联系人电话号码
//     * @param newphone 新的电话号码
//     * @param name 要修改的联系人姓名
//     * @return 0代表一行也没有更新成功, >0 整数代表的是更新了多少行记录
//     */
//    public int update(String newphone , String name){
//        //根据姓名修改电话号码
//        SQLiteDatabase db = helper.getWritableDatabase();
//        //db.execSQL("update contactinfo set phone =? where name=?", new Object[]{newphone,name});
//        ContentValues values = new ContentValues();
//        values.put("phone", newphone);
//        int rowcount =  db.update("contactinfo", values, "name=?", new String[]{name});
//        db.close();
//        return rowcount;
//    }
//    /**
//     * 查询联系人的电话号码
//     * @param name 要查询的联系人
//     * @return 电话号码
//     */
//    public String getPhoneNumber(String name){
//        String phone = null;
//        SQLiteDatabase db = helper.getReadableDatabase();
//        //Cursor  cursor = db.rawQuery("select phone from contactinfo where name=?", new String[]{name});
//        Cursor cursor =  db.query("contactinfo", new String[]{"phone"}, "name=?", new String[]{name}, null, null, null);
//        if(cursor.moveToNext()){//如果光标可以移动到下一位,代表就是查询到了数据
//            phone = cursor.getString(0);
//        }
//        cursor.close();//关闭掉游标,释放资源
//        db.close();//关闭数据库,释放资源
//        return phone;
//    }


    public String getAll(){
        String all = "";
        SQLiteDatabase db = helper.getReadableDatabase();
        Cursor cursor =  db.query("USER", new String[]{"NAME"}, null, null, null, null, null);
        while (cursor.moveToNext()){//如果光标可以移动到下一位,代表就是查询到了数据
            all += cursor.getString(0)+"///";
        }
        cursor.close();//关闭掉游标,释放资源
        db.close();//关闭数据库,释放资源
        return all;
    }

    public String updateField(){
        String allTable = "";
        SQLiteDatabase db = helper.getReadableDatabase();
        Cursor cursor = db.rawQuery("select name from sqlite_master where type='table' order by name", null);
        while(cursor.moveToNext()){
            //遍历出表名
            String name = cursor.getString(0);
            allTable += name+"....";
        }

        return allTable;
    }



}
package com.diandou.demo40_greendao_sqlite;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        DemoDao demoDao = new DemoDao(this);
        Log.d("====", ""+demoDao.updateField());
        Log.d("====", ""+demoDao.getAll());
    }
}

一跑便知…..

你可能感兴趣的:(android)