android中數據庫框架 GreenDao

android中數據庫框架 GreenDao

代碼已上傳 http://download.csdn.net/download/qq_24349695/10240859

樓主之前的項目用到了本地緩存,SharedPreferences緩存的數據有限,就研究了SQLite,發現SQLite的存儲查詢過程比較繁瑣,搜索過之後選擇了GreeDao框架

GreenDao官網 http://greenrobot.org/greendao/documentation/introduction/

樓主使用android studio編譯器

GreenDao配置

一、添加依賴

compile'org.greenrobot:greendao:3.0.1'  
compile'org.greenrobot:greendao-generator:3.0.0' 

二、配置app的Gradle

apply plugin: 'org.greenrobot.greendao'  

buildscript {  
    repositories {  
        mavenCentral()  
    }  
    dependencies {  
        classpath 'org.greenrobot:greendao-gradle-plugin:3.0.0'  
    }  
}  

greendao {  
    schemaVersion 1  
    daoPackage 'com.example.anonymous.greendao'  
    targetGenDir 'src/main/java'  
}  

schemaVersion—->指定數據庫schema版本號,遷移等操作會用到
daoPackage——–>通過gradle插件生成的數據庫相關文件,這裏我設置的文件路徑是com.example.anonymous.greendao
targetGenDir——–>這就是我們上面說到的自定義生成數據庫文件的目錄了,可以將生成的文件放到我們的java目錄中,而不是build中,這樣就不用額外的設置資源目錄了

buildscript {  
    repositories {  
        mavenCentral()  
    }  
    dependencies {  
        classpath 'org.greenrobot:greendao-gradle-plugin:3.0.0'  
    }  
}  

可以寫在oroject build.gradle 中

如下

// 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.2.2'
        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
}

當然寫在app的Gradle中也可以,官網是寫在project中的

app的Gradle整體

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

buildscript {  
    repositories {  
        mavenCentral()  
    }  
    dependencies {  
        classpath 'org.greenrobot:greendao-gradle-plugin:3.0.0'  
    }  
}  

greendao {  
    schemaVersion 1  
    daoPackage 'com.example.anonymous.greendao'  
    targetGenDir 'src/main/java'  
}  

android {
    compileSdkVersion 25
    buildToolsVersion "27.0.1"
    defaultConfig {
        applicationId "com.ljm.greendao"
        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'
    compile 'com.android.support.constraint:constraint-layout:1.0.2'
    compile'org.greenrobot:greendao:3.0.1'
    compile'org.greenrobot:greendao-generator:3.0.0'
    testCompile 'junit:junit:4.12'
}

添加數據庫數據的實體類

@Entity  
public class User {  
    @Id  
    private Long id;  
    private String name;  
}  

@Entity:將我們的java普通類變爲一個能夠被greenDAO識別的數據庫類型的實體類
@Id:通過這個註解標記的字段必須是Long類型的,這個字段在數據庫中表示它就是主鍵,並且它默認就是自增的

make project後自動生成數據

這裏寫圖片描述

這是GreenDao自動爲你生成的,路徑就是你在gradle中配置的路徑

增、刪、改、查

數據庫初始化

DaoMaster.DevOpenHelper devOpenHelper = new DaoMaster.DevOpenHelper(MyApplication.getContext(), "my-db", null);    
DaoMaster daoMaster = new DaoMaster(devOpenHelper.getWritableDatabase());    
DaoSession daoSession = daoMaster.newSession();    
UserDao userDao = daoSession.getUserDao();    

my-db是數據庫的名字,自己隨便寫就行。
通過GreenDao生成的代碼,我們可以獲取到實體類的實例,也就是數據庫表的實例,這樣我們才能操作數據庫
一、增加

User user1 = new User(null,"zhangsan");  
userDao.insert(user1); 

二、刪除

1、根據Id刪除

User findUser = userDao.queryBuilder().where(UserDao.Properties.Name.eq("zhangsan")).build().unique();    
if(findUser != null){    
    userDao.deleteByKey(findUser.getId());    
}    

2、刪除全部數據

 userDao.deleteAll();

三、更新、修改

//1.where是查詢條件,
//2.unique()表示查詢結果爲一條數據,若數據不存在,findUser爲null。
User findUser = userDao.queryBuilder().where(UserDao.Properties.Name.eq("zhangsan")).build().unique();    
if(findUser != null) {    
    findUser.setName("lisi");    
    userDao.update(findUser);    
    Toast.makeText(MyApplication.getContext(), "修改成功", Toast.LENGTH_SHORT).show();    
} else {    
    Toast.makeText(MyApplication.getContext(), "用戶不存在", Toast.LENGTH_SHORT).show();    
}    

zhangsan修改成lisi

四、查詢

List<User> userList = userDao.queryBuilder()    
       .where(UserDao.Properties.Id.notEq(0))   
       .limit(5)    
       .build().list(); 

queryBuilder()方法,生成一個查找構造器,可以給構造器添加where條件判斷、按照某某字段排序以及查詢的條數等基本的數據庫操作。list()方法表示查詢的結果爲一個集合.上述代碼查詢的就是ID號不等於999,按升序排序,做多5條,返回List類型

list()所有實體被加載到內存中。其結果通常是一個 ArrayList中,最容易使用。

listLazy()實體被裝入點播存儲器。一旦列表中的一個元素被首次訪問,它被加載並高速緩存以供將來使用。必須關閉。

listLazyUncached()一個“虛擬”實體名單:任何接觸到從數據庫加載其數據的列表元素的結果。必須關閉。

ListIterator()通過懶加載的數據讓你通過迭代的結果的。數據不會被緩存。必須關閉

上面查詢的是一個list這個就是一個單例

User user = userDao.queryBuilder()  
       .where(UserDao.Properties.Id.eq(999)).unique(); 

封裝 封裝 封裝 封裝 封裝 封裝 封裝 封裝 封裝

對代碼進行封裝,以便於多次調用

這裏寫圖片描述

1、MyApplication:返回Context對象

2、DaoManager:初始化數據庫,獲取相應的操作對象

3、EntityManager:對數據庫表的初始化,獲取實體類的操作對象

MyApplication

public class MyApplication extends Application {  
    private static Context mContext;  

    @Override  
    public void onCreate() {  
        super.onCreate();  
        mContext = getApplicationContext();  
    }  

    public static Context getContext() {  
        return mContext;  
    }  
}  

EntityManager

public class EntityManager {
    private static EntityManager entityManager;
    public UserDao userDao;

    /**
     * 創建User表實例
     *
     * @return
     */
    public UserDao getUserDao(){
        userDao = DaoManager.getInstance().getSession().getUserDao();
        return userDao;
    }

    /**
     * 創建單例
     *
     * @return
     */
    public static EntityManager getInstance() {
        if (entityManager == null) {
            entityManager = new EntityManager();
        }
        return entityManager;
    }
}

DaoManager

public class DaoManager {
    private static DaoManager mInstance;
    private DaoMaster mDaoMaster;
    private DaoSession mDaoSession;

    private DaoManager() {
        DaoMaster.DevOpenHelper devOpenHelper = new DaoMaster.DevOpenHelper(MyApplication.getContext(), "my-db", null);
        DaoMaster mDaoMaster = new DaoMaster(devOpenHelper.getWritableDatabase());
        mDaoSession = mDaoMaster.newSession();
    }

    public DaoMaster getMaster() {
        return mDaoMaster;
    }

    public DaoSession getSession() {
        return mDaoSession;
    }

    public static DaoManager getInstance() {
        if (mInstance == null) {
            mInstance = new DaoManager();
        }
        return mInstance;
    }
}

使用以插入爲例子

UserDao userDao = EntityManager.getInstance().getUserDao();  
User user1 = new User(null,"zhangsan");  
userDao.insert(user1);  

DaoManager和EntityManager主要作用是對數據庫和表的初始化工作抽出來作爲複用,在Activity中使用的時候,我們可以直接操作表,不需要在初始化工作了。

所有操作封裝

public class DbService {

    private static DbService instance;
    private static Context appContext;
    private UserDao userDao;

    private DbService() {
    }

    /**
     * 採用單例模式
     * @param context     上下文
     * @return            dbservice
     */
    public static DbService getInstance(Context context) {
        if (instance == null) {
            instance = new DbService();
            if (appContext == null){
                appContext = context.getApplicationContext();
            }

            instance.userDao = EntityManager.getInstance().getUserDao();
        }
        return instance;
    }
    /**
     * 根據用戶id,取出用戶信息
     * @param id           用戶id
     * @return             用戶信息
     */
    public User loadNote(long id) {
        if(!TextUtils.isEmpty(id + "")) {
            return userDao.load(id);
        }
        return  null;
    }

    /**
     * 取出所有數據
     * @return      所有數據信息
     */
    public List<User> loadAllNote(){
        return userDao.loadAll();
    }

    /**
     * 生成按id倒排序的列表
     * @return      倒排數據
     */
    public List<User> loadAllNoteByOrder()
    {
        return userDao.queryBuilder().orderDesc(UserDao.Properties.Id).list();
    }

    /**
     * 根據查詢條件,返回數據列表
     * @param where        條件
     * @param params       參數
     * @return             數據列表
     */
    public List<User> queryNote(String where, String... params){
        return userDao.queryRaw(where, params);
    }


    /**
     * 根據用戶信息,插件或修改信息
     * @param user              用戶信息
     * @return 插件或修改的用戶id
     */
    public long saveNote(User user){
        return userDao.insertOrReplace(user);
    }


    /**
     * 批量插入或修改用戶信息
     * @param list      用戶信息列表
     */
    public void saveNoteLists(final List<User> list){
        if(list == null || list.isEmpty()){
            return;
        }
        userDao.getSession().runInTx(new Runnable() {
            @Override
            public void run() {
                for(int i=0; i<list.size(); i++){
                    User user = list.get(i);
                    userDao.insertOrReplace(user);
                }
            }
        });

    }

    /**
     * 刪除所有數據
     */
    public void deleteAllNote(){
        userDao.deleteAll();
        Toast.makeText(appContext, "刪除成功", Toast.LENGTH_SHORT).show();
    }

    /**
     * 根據id,刪除數據
     * @param id      用戶id
     */
    public void deleteNote(long id){
        userDao.deleteByKey(id);
    }

    /**
     * 根據用戶類,刪除信息
     * @param user    用戶信息類
     */
    public void deleteNote(User user){
        userDao.delete(user);
    }
}

具體使用,以刪除所有數據爲例。

findViewById(R.id.bt_deleteall).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                DbService.getInstance(MainActivity.this).deleteAllNote();
                //DeleteAllData();
            }
        });

具體使用

public class MainActivity extends AppCompatActivity {
    private  UserDao userDao;
    private DaoSession daoSession;
    private DaoMaster daoMaster;
    private DaoMaster.DevOpenHelper devOpenHelper;
    private List<User> userList;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        devOpenHelper = new DaoMaster.DevOpenHelper(MainActivity.this, "my-db", null);
        daoMaster = new DaoMaster(devOpenHelper.getWritableDatabase());
        daoSession = daoMaster.newSession();
        //userDao = daoSession.getUserDao();
        userDao = EntityManager.getInstance().getUserDao();
        findViewById(R.id.bt_insert).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                AddData();
            }
        });

        findViewById(R.id.bt_delete).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                DeleteData();
            }
        });

        findViewById(R.id.bt_update).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                UpdateData();
            }
        });

        findViewById(R.id.bt_query).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                QueryData();
            }
        });

         findViewById(R.id.bt_deleteall).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                DbService.getInstance(MainActivity.this).deleteAllNote();
                //DeleteAllData();
            }
        });

    }

    private void AddData(){
        User user1 = new User(null,"zhangsan");
        userDao.insert(user1);
        Toast.makeText(MainActivity.this, "添加成功", Toast.LENGTH_SHORT).show();
        /*QueryData();
        for(int i = 0;i<userList.size();i++){
            if("zhangsan".equals(userList.get(i).getName())){
                Toast.makeText(MainActivity.this, "用戶已存在", Toast.LENGTH_SHORT).show();
            }else{
                User user1 = new User(null,"zhangsan");
                userDao.insert(user1);
                Toast.makeText(MainActivity.this, "添加成功", Toast.LENGTH_SHORT).show();
            }
        }*/

    }
 private void DeleteAllData() {
        userDao.deleteAll();
        Toast.makeText(MainActivity.this, "刪除成功", Toast.LENGTH_SHORT).show();
    }

    private void DeleteData(){
        User findUser = userDao.queryBuilder().where(UserDao.Properties.Name.eq("zhangsan")).build().unique();
        if(findUser != null){
            userDao.deleteByKey(findUser.getId());
            Toast.makeText(MainActivity.this, "刪除成功", Toast.LENGTH_SHORT).show();
        }
    }

    private void UpdateData(){
        User findUser = userDao.queryBuilder().where(UserDao.Properties.Name.eq("zhangsan")).build().unique();
        if(findUser != null) {
            findUser.setName("lisi");
            userDao.update(findUser);
            Toast.makeText(MainActivity.this, "修改成功", Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(MainActivity.this, "用戶不存在", Toast.LENGTH_SHORT).show();
        }
    }

    private void QueryData(){
        userList = userDao.queryBuilder()
                .where(UserDao.Properties.Id.notEq(0))
                .limit(5)
                .build().list();
        for(int i = 0;i<userList.size();i++){
            System.out.println("_____________i____________"+userList.get(i).getId()+"_______"+userList.get(i).getName());
        }
    }
}

ps:

一、這份代碼只是簡單的入門,代碼中還是存在bug的,重複添加再點刪除的時候會報錯org.greenrobot.greendao.DaoException: Expected unique result, but count was 2,如果在項目中用到,在插入之前先查詢下數據庫,然後再插入,或者刪除的時候根據ID去刪除。
二、代碼封裝過後記得在AndroidManifest中添加MyApplication不然會報空指針異常的。
代碼已上傳 http://download.csdn.net/download/qq_24349695/10240859

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章