Android整合网上资源以及个人对GreenDao数据库框架的理解与使用(android-studio开发)

优点:完美试用android,个人比较看好的一点是极其方便的contentprovider,不用自己操很多代码,两三句就能搞定。根据对象进行增删改查,迷糊数据库语句的可以一试。

AS开发导入Greendao

链接:http://www.jianshu.com/p/9ae4e24e01cb

Android 工程搭建步骤:

1.Android  工程main目录下建立文件夹 java-gen

 

2.app 的gradle的配置:

apply plugin: 'com.android.application'
android {
    compileSdkVersion 23
    buildToolsVersion "23.0.1"
    sourceSets{
        main{
            java.srcDirs=['src/main/java','src/main/java-gen']
        }
    }
    defaultConfig {
        applicationId "com.wyt.pandamanager.pandamanager"
        minSdkVersion 14
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}
dependencies {
    compile fileTree(include: ['*.jar'], dir: 'libs')
    testCompile 'junit:junit:4.12'
    compile 'com.android.support:appcompat-v7:23.1.0'
    compile 'com.github.dmytrodanylyk.circular-progress-button:library:1.1.3'
    compile 'com.nineoldandroids:library:2.4.0'
    compile 'com.github.sd6352051.niftydialogeffects:niftydialogeffects:1.0.0@aar'
    compile 'com.github.rtoshiro.fullscreenvideoview:fullscreenvideoview:1.1.0'
    compile project(':PullToRefreshlibs')
    compile 'de.greenrobot:greendao:2.0.0'
}

3.new 一个java library 的module 其grade配置:

apply plugin: 'java'
dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'de.greenrobot:greendao-generator:2.0.0'
}

4.在java-library里的主类的main方法里建表

 

package com.example;
import de.greenrobot.daogenerator.DaoGenerator;
import de.greenrobot.daogenerator.Entity;
import de.greenrobot.daogenerator.Schema;
/**
 * greenDao数据库建表
 * created by hcy 2016.1.5
 */
public class DaoGen {
    public static void main(String[] args) throws Exception {
        Schema schema = new Schema(1, "com.wyt.db.bean");
        schema.setDefaultJavaPackageDao("com.wyt.db.dao");
        addPassword(schema);//建立表password
        addAlarmManager(schema);//建立表AlarmManager
        addAlarmManager_Num(schema);//建立表AlarmManager_Num
        addHuyan(schema);//建立表Huyan
        addlearninglog(schema);//简历学习日志表
        addUser(schema);//用户表
        new DaoGenerator().generateAll(schema, "app/src/main/java-gen");// 自动创建
    }
    /**
     * 用户表
     * @param schema
     */
    private static void addUser(Schema schema) {
        Entity user = schema.addEntity("User")
        user.addIdProperty().autoincrement();//主键自增
        user.addStringProperty("user_id");
        user.addStringProperty("user_phone");
        user.addStringProperty("user_email");
        user.addStringProperty("child_name");
        user.addStringProperty("child_gender");
        user.addStringProperty("child_birth");
        user.addStringProperty("child_school");
        user.addStringProperty("child_grade");
    }
    /**
     * 学习日志表
     * @param schema
     */
    private static void addlearninglog(Schema schema) {
        Entity learningLog = schema.addEntity("LearningLog");
        learningLog.addIdProperty();
        learningLog.addStringProperty("user_id");
        learningLog.addStringProperty("learn_system");
        learningLog.addStringProperty("learn_class");
        learningLog.addStringProperty("learn_app_name");
        learningLog.addStringProperty("learn_app_pkg");
        learningLog.addStringProperty("learn_app_starttime");
        learningLog.addStringProperty("learn_app_endtime");
        learningLog.addStringProperty("learn_app_content");
        learningLog.addStringProperty("createtime");
    }
    /**
     * 密码
     * @param schema
     */
    private static void addPassword(Schema schema) {
        Entity passWord = schema.addEntity("PassWord");
        passWord.addIdProperty();
        passWord.addStringProperty("password");
    }
    private static void addAlarmManager_Num(Schema schema) {
        Entity alarmManager_Num = schema.addEntity("AlarmManager_Num");
        alarmManager_Num.addIdProperty();
        alarmManager_Num.addStringProperty("alarm_type");
        alarmManager_Num.addStringProperty("alarm_date");
        alarmManager_Num.addIntProperty("alarm_hour");
        alarmManager_Num.addIntProperty("alarm_min");
        alarmManager_Num.addIntProperty("alarm_xiuxi");
    }
    private static void addAlarmManager(Schema schema) {
        Entity alarmManager = schema.addEntity("AlarmManager");
        alarmManager.addIdProperty();//id
        alarmManager.addStringProperty("alarm_type");
        alarmManager.addStringProperty("alarm_date");
        alarmManager.addIntProperty("alarm_hour");
        alarmManager.addIntProperty("alarm_min");
    }
    /**
     * 护眼
     * @param schema
     */
    private static void addHuyan(Schema schema) {
        Entity huyan = schema.addEntity("Huyan");
        huyan.addIdProperty();//ID
        huyan.addStringProperty("user_id");
        huyan.addIntProperty("huyan_hour");
        huyan.addIntProperty("huyan_min");
        huyan.addIntProperty("huyan_xiuxi");
        huyan.addStringProperty("createtime");
        huyan.addStringProperty("updatetime");
    }
}

5.写数据库操作工具类1(Application)

package application;

import android.app.Application;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import com.wyt.db.dao.DaoMaster;
import com.wyt.db.dao.DaoSession;
/**
 * Created by hcy on 2016/8/17.
 */
public class App extends Application {

    private static App mInstance;
    private static DaoMaster daoMaster;
    private static DaoSession daoSession;
    private static SQLiteDatabase db;
    @Override
    public void onCreate() {
        super.onCreate();
        if (mInstance == null) {
            mInstance = this;
        }

    }
    public static DaoMaster getDaoMaster(Context context) {
        if (daoMaster == null) {
            DaoMaster.OpenHelper helper = new DaoMaster.DevOpenHelper(context, "wyt_db", null);
            daoMaster = new DaoMaster(helper.getWritableDatabase());
        }
        return daoMaster;
    }
    public static DaoSession getDaoSession(Context context) {
        if (daoSession == null) {
            if (daoMaster == null) {
                daoMaster = getDaoMaster(context);
            }
            daoSession = daoMaster.newSession();
        }
        return daoSession;
    }
    public static SQLiteDatabase getSQLiteDatabase(Context context) {
        if (daoSession == null) {
            if (daoMaster == null) {
                daoMaster = getDaoMaster(context);
            }
            db = daoMaster.getDatabase();

        }
        return db;
    }

}


6.数据库工具类2(单例,有几个表就new  几个Dao)

import application.App;
import module.personalcenter.json.UserInfo;
/**
 * Created by hcy on 2016/8/17.
 */
public class DbService {
    public static DbService instance;
    public static Context appContext;
    private DaoSession mDaoSession;
    private USERDao userDao;//
    private StudyInfoDao studyInfoDao;
    private SQLiteDatabase db;

    public static DbService getInstance(Context context) {
        if (instance == null) {
            instance = new DbService();
            if (appContext == null) {
                appContext = context.getApplicationContext();
            }
            instance.mDaoSession = App.getDaoSession(context);
            instance.db = App.getSQLiteDatabase(context);
            instance.userDao = instance.mDaoSession.getUSERDao();
            instance.studyInfoDao = instance.mDaoSession.getStudyInfoDao();

        }
        return instance;
    }


    public boolean updateStudyInfo(String JsonData) {
        List studyInfos = studyInfoDao.loadAll();
        if (studyInfos != null && studyInfos.size() != 0) {
            StudyInfo studyInfo = studyInfos.get(0);
            studyInfo.setData(JsonData);
            studyInfoDao.update(studyInfo);
            return true;
        } else {
            StudyInfo studyInfo = new StudyInfo(JsonData);
            studyInfoDao.insert(studyInfo);
            return true;
        }
    }
}


7.数据库操作

(一)往person表里插入一条数据(重复插入会报错)[重写一个不含id的构造方法,可重复插入,因为id自增了]

Person person=new Person((long)4,"王五",17,"男");
personDao.insert(person);

(二)根据id查找所有记录的三种查询方式(我喜欢用第一种)

Listlist=personDao.queryBuilder().where(PersonDao.Properties.Id.eq(4)).build().list();
tv.setText(list.get(0).toString());

 

Person load = personDao.load((long) 4);
tv.setText(load.toString());

 

Query query = personDao.queryBuilder().where(PersonDao.Properties.Id.eq(5)).build();
query.setParameter(0,4);
List list = query.list();
tv.setText(list.toString());

  (三)查找id>=5的记录

List list = personDao.queryBuilder().where(PersonDao.Properties.Id.ge(5)).build().list();
tv.setText(list.toString());

(四)查找id>5的记录

List list = personDao.queryBuilder().where(PersonDao.Properties.Id.gt(5)).build().list();
tv.setText(list.toString());

(五)查找id<=5的记录

List list = personDao.queryBuilder().where(PersonDao.Properties.Id.le(5)).build().list();
tv.setText(list.toString());

(六)查找id<5的记录

List list = personDao.queryBuilder().where(PersonDao.Properties.Id.lt(5)).build().list();
tv.setText(list.toString());

(七)多语句查询

1.同时满足两个条件

List list = myWordBookDao.queryBuilder().where(MyWordBookDao.Properties.Userid.eq(userid), MyWordBookDao.Properties.Word.eq(word)).build().list();

(八)跟新

            MyWordBook myWordBook = list.get(0);
            myWordBook.setUserid(userid);
            myWordBook.setWord(word);
            myWordBook.setVoice(duyin);
            myWordBook.setVoiceURL(wordURL);
            myWordBook.setMean(zhushi);
            myWordBookDao.update(myWordBook);

GreenDao的ContentProvider(这个框架最让我惊喜的功能)

1.建表的时候添加contentprovider

 private static void createUserTable(Schema schema) {
        Entity user = schema.addEntity("USER");
        user.addIdProperty().autoincrement();//主键自增
        user.addStringProperty("device_number");
        user.addStringProperty("city_name");
        user.addStringProperty("school_name");
        user.addStringProperty("study_section");
        user.addStringProperty("grade");
        user.addStringProperty("constellation");
        user.addStringProperty("book_ver");
        user.addStringProperty("brith_date");
        user.addStringProperty("bound_phone_one");
        user.addStringProperty("bound_phone_name_one");
        user.addStringProperty("bound_phone_two");
        user.addStringProperty("bound_phone_name_two");
        user.addStringProperty("userid");
        user.addStringProperty("nickname");
        user.addStringProperty("icon");
        user.addStringProperty("sex");
        user.addContentProvider();//给表设置contentprovider
    }

2.ctrl+shift+f10 运行

3.运行android工程一遍,会发现java-gen/bean/xxxprovider的一个报错,textutils没有导入,as快捷键导入

4.修改xxxprovider与配置文件(红色标明)

package com.wyt.db.bean;

import android.content.ContentProvider;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import android.text.TextUtils;

import application.App;
import de.greenrobot.dao.DaoLog;

import com.wyt.db.dao.DaoSession;
import com.wyt.db.dao.USERDao;

/* Copy this code snippet into your AndroidManifest.xml inside the
 element:

    
    */
public class USERContentProvider extends ContentProvider {

   public static final String AUTHORITY = "com.wyt.db.bean.provider.USER";
    public static final String BASE_PATH = "USER";
    public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" + BASE_PATH);//provider的URl
    public static final String CONTENT_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE
            + "/" + BASE_PATH;
    public static final String CONTENT_ITEM_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE
            + "/" + BASE_PATH;

    private static final String TABLENAME = USERDao.TABLENAME;
    private static final String PK = USERDao.Properties.Id
            .columnName;

    private static final int USER_DIR = 0;
    private static final int USER_ID = 1;

    private static final UriMatcher sURIMatcher;

    static {
        sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        sURIMatcher.addURI(AUTHORITY, BASE_PATH, USER_DIR);
        sURIMatcher.addURI(AUTHORITY, BASE_PATH + "/#", USER_ID);
    }

    /**
     * This must be set from outside, it's recommended to do this inside your Application object.
     * Subject to change (static isn't nice).
     */
    public static DaoSession daoSession;

    @Override
    public boolean onCreate() {
        // if(daoSession == null) {
        // throw new IllegalStateException("DaoSession must be set before content provider is created");
        // }
        daoSession = App.getDaoSession(getContext());//这句话是没有的要自己添加,非常重要,不然provider没用的
        DaoLog.d("Content Provider started: " + CONTENT_URI);
        return true;
    }

    protected SQLiteDatabase getDatabase() {
        if (daoSession == null) {
            throw new IllegalStateException("DaoSession must be set during content provider is active");
        }
        return daoSession.getDatabase();
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        int uriType = sURIMatcher.match(uri);
        long id = 0;
        String path = "";
        switch (uriType) {
            case USER_DIR:
                id = getDatabase().insert(TABLENAME, null, values);
                path = BASE_PATH + "/" + id;
                break;
            default:
                throw new IllegalArgumentException("Unknown URI: " + uri);
        }
        getContext().getContentResolver().notifyChange(uri, null);
        return Uri.parse(path);
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        int uriType = sURIMatcher.match(uri);
        SQLiteDatabase db = getDatabase();
        int rowsDeleted = 0;
        String id;
        switch (uriType) {
            case USER_DIR:
                rowsDeleted = db.delete(TABLENAME, selection, selectionArgs);
                break;
            case USER_ID:
                id = uri.getLastPathSegment();
                if (TextUtils.isEmpty(selection)) {
                    rowsDeleted = db.delete(TABLENAME, PK + "=" + id, null);
                } else {
                    rowsDeleted = db.delete(TABLENAME, PK + "=" + id + " and "
                            + selection, selectionArgs);
                }
                break;
            default:
                throw new IllegalArgumentException("Unknown URI: " + uri);
        }
        getContext().getContentResolver().notifyChange(uri, null);
        return rowsDeleted;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection,
                      String[] selectionArgs) {
        int uriType = sURIMatcher.match(uri);
        SQLiteDatabase db = getDatabase();
        int rowsUpdated = 0;
        String id;
        switch (uriType) {
            case USER_DIR:
                rowsUpdated = db.update(TABLENAME, values, selection, selectionArgs);
                break;
            case USER_ID:
                id = uri.getLastPathSegment();
                if (TextUtils.isEmpty(selection)) {
                    rowsUpdated = db.update(TABLENAME, values, PK + "=" + id, null);
                } else {
                    rowsUpdated = db.update(TABLENAME, values, PK + "=" + id
                            + " and " + selection, selectionArgs);
                }
                break;
            default:
                throw new IllegalArgumentException("Unknown URI: " + uri);
        }
        getContext().getContentResolver().notifyChange(uri, null);
        return rowsUpdated;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection,
                        String[] selectionArgs, String sortOrder) {

        SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();
        int uriType = sURIMatcher.match(uri);
        switch (uriType) {
            case USER_DIR:
                queryBuilder.setTables(TABLENAME);
                break;
            case USER_ID:
                queryBuilder.setTables(TABLENAME);
                queryBuilder.appendWhere(PK + "="
                        + uri.getLastPathSegment());
                break;
            default:
                throw new IllegalArgumentException("Unknown URI: " + uri);
        }

        SQLiteDatabase db = getDatabase();
        Cursor cursor = queryBuilder.query(db, projection, selection,
                selectionArgs, null, null, sortOrder);
        cursor.setNotificationUri(getContext().getContentResolver(), uri);

        return cursor;
    }

    @Override
    public final String getType(Uri uri) {
        switch (sURIMatcher.match(uri)) {
            case USER_DIR:
                return CONTENT_TYPE;
            case USER_ID:
                return CONTENT_ITEM_TYPE;
            default:
                throw new IllegalArgumentException("Unsupported URI: " + uri);
        }
    }
}

配置文件:

   

 

contentRecevier

package com.wyt.hcy.test;

import android.content.ContentResolver;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.util.Log;

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

/**
 * Created by Administrator on 2016/8/29.
 */
public class DbSearchUtils {
    /**
     * 调用用户中心的数据
     * @param context
     */

    public static UserInfo getUser(Context context) {

        ContentResolver resolver = context.getContentResolver();
       Uri uri = Uri.parse("content://com.wyt.db.bean.provider.USER/USER");

        Cursor cursor = resolver.query(uri, null, null, null, null);

        List list=new ArrayList();

        if (cursor != null && cursor.getCount() != 0) {
            while (cursor.moveToNext()) {
                String device_number = cursor.getString(cursor.getColumnIndex("device_number"));//设备id

                String city_name = cursor.getString(cursor.getColumnIndex("city_name"));//地区

                String school_name = cursor.getString(cursor.getColumnIndex("school_name"));//学校
                String study_section = cursor.getString(cursor.getColumnIndex("study_section"));//学段
                String grade = cursor.getString(cursor.getColumnIndex("grade"));//年级
                String constellation = cursor.getString(cursor.getColumnIndex("constellation"));//星座
                String book_ver = cursor.getString(cursor.getColumnIndex("book_ver"));//出版社
                String brith_date = cursor.getString(cursor.getColumnIndex("brith_date"));//生日
                String bound_phone_one = cursor.getString(cursor.getColumnIndex("bound_phone_one"));//绑定手机一
                String bound_phone_name_one = cursor.getString(cursor.getColumnIndex("bound_phone_name_one"));//绑定手机一名字
                String bound_phone_two = cursor.getString(cursor.getColumnIndex("bound_phone_two"));//绑定手机二
                String bound_phone_name_two = cursor.getString(cursor.getColumnIndex("bound_phone_name_two"));//绑定手机二的名字
                
                String userid = cursor.getString(cursor.getColumnIndex("userid"));//用户id(手机号)
                String nickname = cursor.getString(cursor.getColumnIndex("nickname"));//用户名
                String icon = cursor.getString(cursor.getColumnIndex("icon"));//用户头像

                String sex = cursor.getString(cursor.getColumnIndex("sex"));//用户性别

                UserInfo userInfo = new UserInfo(device_number, city_name, school_name, study_section, grade, constellation, book_ver, brith_date, bound_phone_one, bound_phone_name_one, bound_phone_two, bound_phone_name_two, userid, nickname, icon, sex);


                Log.i("DDDDD", userInfo.toString());

                list.add(userInfo);

            }
        }


        cursor.close();


        if (list.size()==0){
            return null;
        }else {
            return list.get(0);
        }

    }
}


一个我遇到过的使用ContentProvider的错误:INSTALL FAILED CONFLICTING PROVIDER

 

 

原因:使用contentprovider要保证其AUTHORITY值不能重复。不是name值,此时修改name值是没有用的,必须修改AUTHORITY值(别忘记同时修改配置文件里的contentprovider里的AUTHORITY的值)

补充:

按时间从小到大排序:

        final List list = wytFlashDao.queryBuilder().orderAsc(WytFlashDao.Properties.FlashDownLoadTime).list();

GreenDao的分组查询.

1.貌似GreenDao是不支持分组的,但请不要忘记,GreenDao是支持sql语句查询的,so,只要注意下几个细节(空格和查询列名与表名),就可以做出分组的功能了,下面贴出示例代码,亲测可用:

//按登录时间降序排序
    //多个班级的同一个老师只取一个,即最新扫码的那个
    public List getUserListByLoginTime() {
        List queryDataList = new ArrayList<>();
        String sql = "select * from " + UserAccountInfoDao.TABLENAME + " group by " + UserAccountInfoDao.Properties.User_id.columnName + " order by " + UserAccountInfoDao.Properties.LoginTime.columnName + " DESC ";
        Cursor cursor = mDaoSession.getDatabase().rawQuery(sql, new String[]{});
        if (cursor != null) {
            while (cursor.moveToNext()) {
                long Id = cursor.getLong(cursor.getColumnIndex(UserAccountInfoDao.Properties.Id.columnName));
                String User_id = cursor.getString(cursor.getColumnIndex(UserAccountInfoDao.Properties.User_id.columnName));
                String Name = cursor.getString(cursor.getColumnIndex(UserAccountInfoDao.Properties.Name.columnName));
                String Nickname = cursor.getString(cursor.getColumnIndex(UserAccountInfoDao.Properties.Nickname.columnName));
                int  Sex = cursor.getInt(cursor.getColumnIndex(UserAccountInfoDao.Properties.Sex.columnName));
                int  User_type = cursor.getInt(cursor.getColumnIndex(UserAccountInfoDao.Properties.User_type.columnName));
                String Phone = cursor.getString(cursor.getColumnIndex(UserAccountInfoDao.Properties.Phone.columnName));
                String Head_img = cursor.getString(cursor.getColumnIndex(UserAccountInfoDao.Properties.Head_img.columnName));
                int  Status = cursor.getInt(cursor.getColumnIndex(UserAccountInfoDao.Properties.Status.columnName));
                String Access_token = cursor.getString(cursor.getColumnIndex(UserAccountInfoDao.Properties.Access_token.columnName));
                String School_id = cursor.getString(cursor.getColumnIndex(UserAccountInfoDao.Properties.School_id.columnName));
                String School_name = cursor.getString(cursor.getColumnIndex(UserAccountInfoDao.Properties.School_name.columnName));
                String Class_id = cursor.getString(cursor.getColumnIndex(UserAccountInfoDao.Properties.Class_id.columnName));
                String Class_name = cursor.getString(cursor.getColumnIndex(UserAccountInfoDao.Properties.Class_name.columnName));
                String Position = cursor.getString(cursor.getColumnIndex(UserAccountInfoDao.Properties.Position.columnName));
                String Grade_name = cursor.getString(cursor.getColumnIndex(UserAccountInfoDao.Properties.Grade_name.columnName));
                int  Grade_id = cursor.getInt(cursor.getColumnIndex(UserAccountInfoDao.Properties.Grade_id.columnName));
                String License = cursor.getString(cursor.getColumnIndex(UserAccountInfoDao.Properties.License.columnName));
                String Code = cursor.getString(cursor.getColumnIndex(UserAccountInfoDao.Properties.Code.columnName));
                String Policy = cursor.getString(cursor.getColumnIndex(UserAccountInfoDao.Properties.Policy.columnName));
                String Version = cursor.getString(cursor.getColumnIndex(UserAccountInfoDao.Properties.Version.columnName));
                String Binded_at = cursor.getString(cursor.getColumnIndex(UserAccountInfoDao.Properties.Binded_at.columnName));
                String Pwd = cursor.getString(cursor.getColumnIndex(UserAccountInfoDao.Properties.Pwd.columnName));
                long LoginTime = cursor.getLong(cursor.getColumnIndex(UserAccountInfoDao.Properties.LoginTime.columnName));
                queryDataList.add(new UserAccountInfo(Id,User_id,Name,Nickname,Sex,User_type,Phone,Head_img,Status,Access_token,School_id,School_name,Class_id,Class_name,Position,Grade_name,Grade_id,License,Code,Policy,Version,Binded_at,Pwd,LoginTime));
                Log.d("数据库查询", "getUserListByLoginTime: " + Name);
            }
        }
        return queryDataList;
        // return mUserAccountInfoDao.queryBuilder().orderDesc(UserAccountInfoDao.Properties.LoginTime).build().list();
    }

GreenDao的数据库升级

外国大佬写的,网上十篇有十一篇是用这个大牛的

package com.ishuidi.commonlib.base;

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

import com.ishuidi.commonlib.db.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;

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;
    }

    private static 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;
    }

    public void migrate(Database db, Class>... daoClasses) {
        generateTempTables(db, daoClasses);
        DaoMaster.dropAllTables(db, true);
        DaoMaster.createAllTables(db, false);
        restoreData(db, 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(");");
            Log.i("lxq", "创建临时表的SQL语句: " + createTableStringBuilder.toString());
            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(";");
            Log.i("lxq", "在临时表插入数据的SQL语句:" + insertTableStringBuilder.toString());
            db.execSQL(insertTableStringBuilder.toString());
        }
    }

    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();
            ArrayList propertiesQuery = 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);
                    propertiesQuery.add(columnName);
                } else {
                    try {
                        if (getTypeByClass(daoConfig.properties[j].type).equals("INTEGER")) {
                            propertiesQuery.add("0 as " + columnName);
                            properties.add(columnName);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }

            StringBuilder insertTableStringBuilder = new StringBuilder();

            insertTableStringBuilder.append("INSERT INTO ").append(tableName).append(" (");
            insertTableStringBuilder.append(TextUtils.join(",", properties));
            insertTableStringBuilder.append(") SELECT ");
            insertTableStringBuilder.append(TextUtils.join(",", propertiesQuery));
            insertTableStringBuilder.append(" FROM ").append(tempTableName).append(";");

            StringBuilder dropTableStringBuilder = new StringBuilder();

            dropTableStringBuilder.append("DROP TABLE ").append(tempTableName);
            Log.i("lxq", "插入正式表的SQL语句:" + insertTableStringBuilder.toString());
            Log.i("lxq", "销毁临时表的SQL语句:" + dropTableStringBuilder.toString());
            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) || type.equals(int.class)) {
            return "INTEGER";
        }
        if (type.equals(Boolean.class) || type.equals(boolean.class)) {
            return "BOOLEAN";
        }

        Exception exception = new Exception(CONVERSION_CLASS_NOT_FOUND_EXCEPTION.concat(" - Class: ").concat(type.toString()));
        exception.printStackTrace();
        throw exception;
    }
}

//意思就是建立一个新表,除了表名不同外,里面有旧表的所有字段(可能删除,可能增加)根据您新表的需求。然后将数据复制到新表,新增字段就设置成0或null,删除旧表,将新表表名改为旧表名。。
 

//下面是用法

package com.ishuidi.commonlib.base;

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

import com.ishuidi.commonlib.account.UserAccountaDbManager;
import com.ishuidi.commonlib.app.Constants;
import com.ishuidi.commonlib.db.CourseCenterDBBean;
import com.ishuidi.commonlib.db.CourseCenterDBBeanDao;
import com.ishuidi.commonlib.db.CourseCenterDBServer;
import com.ishuidi.commonlib.db.CreateCourseBeanDao;
import com.ishuidi.commonlib.db.DaoMaster;
import com.ishuidi.commonlib.db.DaoSession;
import com.ishuidi.commonlib.db.DayPlaneDao;
import com.ishuidi.commonlib.db.DeleteMaterialsBeanDao;
import com.ishuidi.commonlib.db.JXTBDataBeanDao;
import com.ishuidi.commonlib.db.LifeConventionRecentBeanDao;
import com.ishuidi.commonlib.db.LocalCoursePackageVersionDBBeanDao;
import com.ishuidi.commonlib.db.MusicPlayTimeBeanDao;
import com.ishuidi.commonlib.db.MyAppDBBeanDao;
import com.ishuidi.commonlib.db.ResourceDbBeanDao;
import com.ishuidi.commonlib.db.ResourceIntegrationDetailDao;
import com.ishuidi.commonlib.db.StoryPlayTimeBeanDao;
import com.ishuidi.commonlib.db.SubscribeCategoryDao;
import com.ishuidi.commonlib.db.UserAccountInfoDao;
import com.ishuidi.commonlib.mvp.model.bean.CourseNavBean;
import com.ishuidi.commonlib.mvp.model.bean.CourseResourcesBean;
import com.ishuidi.commonlib.utils.AppPreferencesUtil;
import com.ishuidi.commonlib.utils.CourseUtils;
import com.ishuidi.commonlib.utils.EventBusUtil;
import com.ishuidi.commonlib.utils.LogUtils;

import org.greenrobot.greendao.database.Database;
import org.greenrobot.greendao.query.QueryBuilder;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class DataBaseHelper extends DaoMaster.OpenHelper {

 

    public DataBaseHelper(Context context, String name) {
        super(context, name);
    }

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

    @Override
    public void onUpgrade(Database db, int oldVersion, int newVersion) {
        MigrationHelper.getInstance().migrate(db, CourseCenterDBBeanDao.class,
                CreateCourseBeanDao.class, DayPlaneDao.class, DeleteMaterialsBeanDao.class,
                JXTBDataBeanDao.class, LifeConventionRecentBeanDao.class, LocalCoursePackageVersionDBBeanDao.class,
                MusicPlayTimeBeanDao.class, ResourceDbBeanDao.class, ResourceIntegrationDetailDao.class,
                StoryPlayTimeBeanDao.class, SubscribeCategoryDao.class, UserAccountInfoDao.class);
     
    }

}

数据库版本号在build.grade里设置

    greendao {
        schemaVersion 27//指定数据库版本号,更新操作会用到;
        targetGenDir 'src/main/java'//生成数据库文件的目录
    }

//那么问题来了,如果我不想给新增的字段默认设置为0或者null,我就想给我新增的字段设置为11或者其他字符串怎么办呢。又或者我想让旧表复制过来的某个字段的值统一改改呢。

1.改外国大佬的代码,但人家这个是通用的,低级程序员改不动啊

2.只好在复制完,应用启动前改改

 

1.我在我的aplication里设置一个共有的静态变量

public class BoxApplication extends Application {
    /**
     * 全局环境
     */
 
    private static boolean dataBaseUpdataTo21 = false;
    public static void dataBaseUpdataTo21(boolean flag) {
        dataBaseUpdataTo21 = flag;
    }
}

当新版的数据库版本号为21的时候就将这个静态变量设置为true

 @Override
    public void onUpgrade(Database db, int oldVersion, int newVersion) {
        MigrationHelper.getInstance().migrate(db, CourseCenterDBBeanDao.class,
                CreateCourseBeanDao.class, DayPlaneDao.class, DeleteMaterialsBeanDao.class,
                JXTBDataBeanDao.class, LifeConventionRecentBeanDao.class, LocalCoursePackageVersionDBBeanDao.class,
                MusicPlayTimeBeanDao.class, ResourceDbBeanDao.class, ResourceIntegrationDetailDao.class,
                StoryPlayTimeBeanDao.class, SubscribeCategoryDao.class, UserAccountInfoDao.class);
        if (newVersion == 21) {
            BoxApplication.dataBaseUpdataTo21(true);
        }
      
    }

在application oncreate方法,设置完数据库之后调用

 private void setupDatabase(String db_name) {
        //创建数据库shop.db"

        DataBaseHelper helper = new DataBaseHelper(this, db_name, null);

//        DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(this, db_name, null);
        //获取可写数据库
        SQLiteDatabase db = helper.getWritableDatabase();
        //获取数据库对象
        DaoMaster daoMaster = new DaoMaster(db);
        //获取Dao对象管理者
        daoSession = daoMaster.newSession();

        if (dataBaseUpdataTo21) {
            //新表赋值或者其他操作
            UserAccountaDbManager.getInstance().updateSyncUserTable();
        }
    
     
    }


 

 



 





 

 

 

 


 


 

 


 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(Android)