• 【Android


      上一篇博客(【Android - 框架】之ORMLite的使用)中介绍了ORMLite的基本使用,今天我们来研究以下GreenDao的使用。

      GreenDao和ORMLite一样,都是基于ORM(Object Relation Mapping,对象关系映射)的用于操作Sqlite数据库的第三方框架。ORM简单来说就是把数据库中的数据映射成Java中的一个Bean类,便于操作。GreenDao是greenrobot公司的产品。这个公司的另一个非常成功的框架是EventBus,是一个很好的“订阅/发布”的事件处理框架。

      好了,闲话不说,下面来简单介绍以下GreenDao这个框架。

    1、GreenDao和ORMLite的比较

    ORMLite:

    优点:ORMLite最大的优点是简单,容易上手。
    缺点:ORMLite是基于反射机制工作的,而反射是非常耗时的,因此这便成为了ORMLite的一个缺点,也是GreenDao最针对ORMLite的一点。

    GreenDao:

    优点:效率很高。下面是GreenDao官网上的一张图,将GreenDao的各方面与其他的框架做比较。从图中可以非常清晰的看到,GreenDao在增、改、查方面都比其他框架快出一大截,尤其是查询。这是因为,GreenDao本身底层使用的不是反射,而是有一个Java工程来专门生成必要的代码。

    缺点:GreenDao的缺点是学习成本高。这个框架不像ORMLite那样简单易上手,使用GreenDao之前需要配置一大堆参数,即它封装的不是很完整。

    从上面的比较来看,如果项目对数据库操作的效率要求非常高,那么我们可以考虑使用GreenDao,否则,我们还是使用简单易上手的ORMLite吧。

    2、配置GreenDao

    1、在主Module的build.gradle中配置GreenDao的一些参数,加入GreenDao的依赖以及SourceSets。具体代码如下:

    apply plugin: 'com.android.application'
    
    android {
        compileSdkVersion 24
        buildToolsVersion "24.0.2"
        defaultConfig {
            applicationId "com.example.itgungnir.testgreendao"
            minSdkVersion 11
            targetSdkVersion 24
            versionCode 1
            versionName "1.0"
            testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        }
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            }
        }
        // -------------------下面加入的代码-----------------------
        sourceSets {
            main {
                java.srcDirs = ['src/main/java', 'src/main/java-gen']
            }
        }
        // -------------------上面加入的代码-----------------------
    }
    
    dependencies {
        compile fileTree(include: ['*.jar'], dir: 'libs')
        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:24.2.1'
        testCompile 'junit:junit:4.12'
        // -------------------下面加入的代码-----------------------
        compile 'org.greenrobot:greendao:3.2.0'
        // -------------------上面加入的代码-----------------------
    }

    2、在同一个Project中创建一个JAVA项目,具体步骤如下:

    (1)依次点击 File -> New -> New Module ,选择Java Library,点击Next,如下图:

    (2)Library Name和Java Class Name随意写,我在这里写的Library Name是generator,Class Name是MyGenerator。写完后点击Finish按钮。

    (3)在generator项目的build.gradle中添加GreenDao的Generator的依赖,代码如下:

    apply plugin: 'java'
    
    dependencies {
        compile fileTree(include: ['*.jar'], dir: 'libs')
        compile 'org.greenrobot:greendao-generator:3.2.0'
    }
    
    sourceCompatibility = "1.7"
    targetCompatibility = "1.7"

      关于GreenDao的更多配置信息的设置,大家可以到  这里  查看。

    (4)在主项目中main文件夹下(与java文件夹同级)的地方新建一个文件夹,命名为java-gen,GreenDao中自动生成的Dao、DaoMaster、Session以及Bean都将放到这个文件夹中。

    (5)在MyGenerator中编写初始化数据库的代码,具体代码如下,注释完整清晰,这里就不再赘述了:

    import org.greenrobot.greendao.generator.DaoGenerator;
    import org.greenrobot.greendao.generator.Entity;
    import org.greenrobot.greendao.generator.Property;
    import org.greenrobot.greendao.generator.Schema;
    
    public class MyGenerator {
        private static Entity user;
        private static Entity article;
    
        public static void main(String args[]) {
            try {
                // 第一个参数:数据库版本号;第二个参数:将生成的实体类放到哪个包下
                Schema schema = new Schema(3, "bean");
                // 将生成的DaoMaster、DaoSession和Dao类放到哪个包下
                schema.setDefaultJavaPackageDao("dao");
                // 将单元测试文件放到哪个包下
                schema.setDefaultJavaPackageTest("test");
                // 初始化数据表
                initUserTable(schema);
                initArticleTable(schema);
                // 开始自动生成代码
                new DaoGenerator().generateAll(schema, "app/src/main/java-gen");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        private static void initUserTable(Schema schema) {
            user = schema.addEntity("UserBean"); // 表名
            user.setTableName("user"); // 可以对表重命名
            user.addIdProperty().autoincrement();// 添加主键字段
            user.addStringProperty("name"); // 添加一个字符串类型的字段,名为name
            user.addBooleanProperty("gender"); // 添加一个布尔类型的字段,名为gender
            user.addIntProperty("age"); // 添加一个整形字段,名为age
        }
    
        private static void initArticleTable(Schema schema) {
            article = schema.addEntity("ArticleBean");
            article.setTableName("article");
            article.addIdProperty().autoincrement();
            article.addStringProperty("title");
            // 添加外键user_id,与user表关联,指向user表的主键字段
            Property user_id = article.addLongProperty("user_id").getProperty();
            article.addToOne(user, user_id);
        }
    }

      这张表中有一个外键,即Article表中有一个User表的id的外键依赖。想知道更多关于外键的问题,大家可以去  这里  查看。

      另外需要注意的是,如果想要对数据表或其中信息进行修改,除了需要添加字段、减少字段、添加表或删除表之外,还需要修改Schema对象中的版本号。比如我对这个数据库做了两次修改,因此当前的数据库版本号是3。

    (6)编辑完MyGenerator类之后,我们需要运行这个类。选择这个类之后右键选择 Run XXX.main() ,如下图所示:

            如果运行正常,则会在java-gen文件夹下生成一些类,如下图所示:

     

    (7)如果顺利完成了以上步骤,那么下一步我们就要开始写具体的操作数据库的代码了。

    3、写代码操作数据库

      我们想要完成这样一个需求:对用户表中的数据进行查询,显示到界面中的ListView中,在右上角有一个 添加 按钮,当我们点击这个按钮的时候会向数据库中添加一条数据;当我们长按ListView中的某一项时,会从数据库中删除这条数据。

      下面是具体的代码。

    1、数据库管理类:

      我们可以直接使用GreenDao为我们自动生成的DaoMaster.OpenHelper,但最推荐的方法是我们用一个类来继承这个类,这样在数据库版本变更的时候就可以对数据库进行一些改进。我们定义一个MyDatabaseHelper,代码如下:

    import android.content.Context;
    import android.database.sqlite.SQLiteDatabase;
    
    import dao.DaoMaster;
    
    /**
     * 封装的数据库管理类
     */
    public class MyDatabaseHelper extends DaoMaster.OpenHelper {
    
        public MyDatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory) {
            super(context, name, factory);
        }
    
        @Override
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
            switch (oldVersion) {
                case 1:
                    // 当数据库更新时进行的操作
                    break;
            }
        }
    }

    2、自定义Dao类:

      虽然GreenDao给我们自动生成了一个UserBeanDao类,但是我们有些需求是复合的,无法直接通过这个类中提供的方法进行操作,因此我们需要自己创建一个类来对数据等进行管理。定义一个MyDaoHelper类,其中封装了这张表中常用的操作方法,代码如下:

    import android.content.Context;
    import android.database.sqlite.SQLiteDatabase;
    import android.text.TextUtils;
    
    import com.example.itgungnir.testgreendao.SharedData;
    import com.example.itgungnir.testgreendao.db.MyDatabaseHelper;
    
    import org.greenrobot.greendao.AbstractDao;
    import org.greenrobot.greendao.query.QueryBuilder;
    
    import java.util.List;
    
    import bean.UserBean;
    import dao.DaoMaster;
    import dao.DaoSession;
    import dao.UserBeanDao;
    
    public class MyDaoHelper {
        private static MyDaoHelper instance;
        private UserBeanDao dao;
    
        private MyDaoHelper(Context context) {
            try {
                MyDatabaseHelper helper = new MyDatabaseHelper(context, SharedData.DATABASE_NAME, null);
                SQLiteDatabase db = helper.getWritableDatabase();
                DaoMaster daoMaster = new DaoMaster(db);
                DaoSession session = daoMaster.newSession();
                dao = session.getUserBeanDao();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        public static MyDaoHelper getInstance(Context context) {
            if (instance == null) {
                instance = new MyDaoHelper(context);
            }
            return instance;
        }
    
        public void addData(UserBean bean) {
            if (dao != null && bean != null) {
                dao.insertOrReplace(bean);
            }
        }
    
        public void deleteData(long id) {
            if (dao != null && !TextUtils.isEmpty(id + "")) {
                dao.deleteByKey(id);
            }
        }
    
        public UserBean getDataById(long id) {
            if (dao != null && !TextUtils.isEmpty(id + "")) {
                return dao.load(id);
            }
            return null;
        }
    
        public List<UserBean> getAllData() {
            if (dao != null) {
                return dao.loadAll();
            }
            return null;
        }
    
        public long getTotalCount() {
            if (dao == null) {
                return 0;
            }
            QueryBuilder<UserBean> qb = dao.queryBuilder();
            return qb.buildCount().count();
        }
    
        public void deleteAll() {
            if (dao != null) {
                dao.deleteAll();
            }
        }
    }

    3、MainActivity中的代码如下:

    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.view.View;
    import android.widget.AdapterView;
    import android.widget.Button;
    import android.widget.ListView;
    
    import com.example.itgungnir.testgreendao.adapter.UserAdapter;
    import com.example.itgungnir.testgreendao.dao.MyDaoHelper;
    
    import java.util.List;
    
    import bean.UserBean;
    import dao.UserBeanDao;
    
    public class MainActivity extends AppCompatActivity {
        private Button add;
        private ListView lv;
    
        private MyDaoHelper userDao;
    
        private List userList;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            // 初始化控件
            add = (Button) findViewById(R.id.id_main_btn_add);
            lv = (ListView) findViewById(R.id.id_main_lv_lv);
        }
    
        @Override
        protected void onResume() {
            super.onResume();
            initBDTables();
            initViews();
            initEvents();
        }
    
        private void initBDTables() {
            // 初始化两个Dao类
            userDao = MyDaoHelper.getInstance(MainActivity.this);
            // 删除数据表中的所有数据
            userDao.deleteAll();
            // 向用户表中添加数据
            userDao.addData(new UserBean(1L, "张三", true, 20));
            userDao.addData(new UserBean(2L, "李四", false, 21));
            userDao.addData(new UserBean(3L, "王五", true, 22));
        }
    
        private void initViews() {
            // 从数据库中取出所有用户信息
            userList = userDao.getAllData();
            // 适配ListView数据
            UserAdapter adapter = new UserAdapter(MainActivity.this, userList);
            lv.setAdapter(adapter);
        }
    
        private void initEvents() {
            // 点击add按钮(添加)时触发的事件
            add.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    // 添加一条数据
                    userDao.addData(new UserBean(((UserBean) userList.get(userList.size() - 1)).getId() + 1, "新用户",
                            ((int) (Math.random() * 1000 + 1)) % 2 == 0 ? true : false, (int) (Math.random() * 20 + 20)));
                    initViews();
                }
            });
            // 当长按ListView中的某一项时触发的事件
            lv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
                @Override
                public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
                    // 删除长按的Item
                    userDao.deleteData(((UserBean) userList.get(position)).getId());
                    initViews();
                    return true;
                }
            });
        }
    }

      这里追加一个ListView的适配器类UserAdapter类中的代码:

    import android.content.Context;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.BaseAdapter;
    import android.widget.TextView;
    
    import com.example.itgungnir.testgreendao.R;
    
    import java.util.List;
    
    import bean.UserBean;
    
    /**
     * MainActivity中展示用户信息的ListView的适配器
     */
    public class UserAdapter extends BaseAdapter {
        private List list;
        private LayoutInflater inflater;
    
        public UserAdapter(Context context, List list) {
            this.list = list;
            this.inflater = LayoutInflater.from(context);
        }
    
        @Override
        public int getCount() {
            return list.size();
        }
    
        @Override
        public Object getItem(int position) {
            return list.get(position);
        }
    
        @Override
        public long getItemId(int position) {
            return position;
        }
    
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder = null;
            if (convertView == null) {
                holder = new ViewHolder();
                convertView = inflater.inflate(R.layout.listitem_users, parent, false);
                holder.name = (TextView) convertView.findViewById(R.id.id_useritem_name);
                holder.gender = (TextView) convertView.findViewById(R.id.id_useritem_gender);
                holder.age = (TextView) convertView.findViewById(R.id.id_useritem_age);
                convertView.setTag(holder);
            } else {
                holder = (ViewHolder) convertView.getTag();
            }
            UserBean user = (UserBean) getItem(position);
            holder.name.setText(user.getName());
            holder.gender.setText(user.getGender() == true ? "男" : "女");
            holder.age.setText(user.getAge() + "");
            return convertView;
        }
    
        private static class ViewHolder {
            TextView name;
            TextView gender;
            TextView age;
        }
    }

    5、运行结果如下图所示:

      以上就是对GreenDao框架的简单介绍,希望对大家有帮助~

  • 相关阅读:
    【vue开发问题-解决方法】(十一)数据双向绑定导致修改数据格式原数据绑定出错
    【JavaScript】使用url下载文件,解决chrome浏览器自动识别图片打开问题。
    我的转行之路(电气转IT)------2018阿里校招面经
    关于Class.getResource和ClassLoader.getResource的路径问题
    protected修饰符详解
    为什么i=i++后,i的值不变(深入解析)
    Java中的初始化详细解析
    再谈抽象类(感觉理解的更深了)
    数据类型总结(干货)
    Java的接口和抽象类深入理解
  • 原文地址:https://www.cnblogs.com/itgungnir/p/6210972.html
Copyright © 2020-2023  润新知