【Android - 框架】之GreenDao的使用

时间:2022-10-19 11:11:20

  上一篇博客(【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工程来专门生成必要的代码。

【Android - 框架】之GreenDao的使用

缺点: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,如下图:

【Android - 框架】之GreenDao的使用

(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() ,如下图所示:

【Android - 框架】之GreenDao的使用

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

【Android - 框架】之GreenDao的使用

(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、运行结果如下图所示:

【Android - 框架】之GreenDao的使用

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

【Android - 框架】之GreenDao的使用的更多相关文章

  1. Android中的GreenDao框架修改数据库的存储路径

    目前android中比较热门的数据库框架有greenDAO.OrmLite.AndrORM,其中我比较喜欢用GreenDao,其运行效率最高,内存消耗最少,性能最佳.具体怎么使用GreenDao,网上 ...

  2. Android开发数据库之第三方ORM框架(GreenDao)

    移动APP追求追求功能实现的同一时候,用户体验很重要.開始APP的同一时候.要时刻的切换开发人员的角色,如你开发的时候.是 站在APP的开发角色,处于生产者的位置:当你測试的时候.你应该把自己放在用户 ...

  3. Android 框架简介--Java环境&lpar;转&rpar;

    ==========================上=========================== 这里简单的介绍了Android的java环境基础,在后面一节中会结合具体的实例来理解这一节 ...

  4. 【Android - 框架】之Retrofit&plus;RxJava的使用

    前几天分别对Retrofit和RxJava进行了总结,这个帖子打算把Retrofit结合RxJava使用的方法总结以下.有还不了解Retrofit或RxJava的朋友可以参考下面的帖子学习~ [And ...

  5. IOS 与ANDROID框架及应用开发模式对照一

    IOS 和ANDROID操作系统都是眼下流行的移动操作系统,被移动终端和智能设备大量採用,两者都採用了先进的软件技术进行设计,为了方便应用开发两者都採用了先进的设计模式. 两者在框架设计上都採用了什么 ...

  6. Kotlin的扩展函数:扩展Android框架(KAD 08)

    作者:Antonio Leiva 时间:Jan 11, 2017 原文链接:https://antonioleiva.com/extension-functions-kotlin/ 扩展函数是Kotl ...

  7. App 组件化&sol;模块化之路——Android 框架组件&lpar;Android Architecture Components&rpar;使用指南

    面对越来越复杂的 App 需求,Google 官方发布了Android 框架组件库(Android Architecture Components ).为开发者更好的开发 App 提供了非常好的样本. ...

  8. 【Android 系统开发】Android框架 与 源码结构

    一. Android 框架 Android框架层级 : Android 自下 而 上 分为 4层; -- Linux内核层; -- 各种库 和 Android运行环境层; -- 应用框架层; -- 应 ...

  9. IOS 与ANDROID框架及应用开发模式对比一

    IOS 和ANDROID操作系统都是目前流行的移动操作系统,被移动终端和智能设备大量采用,两者都采用了先进的软件技术进行设计,为了方便应用开发两者都采用了先进的设计模式.两者在框架设计上都采用了什么技 ...

随机推荐

  1. 使用gulp-connect实现web服务器

    安装插件安装gulp-connect插件,安装命令如下 npm install --save-dev gulp-connect 定义web服务,gulpfile.js代码 var gulp = req ...

  2. 使用boost的asio,io&lowbar;service无法初始化

    今天用vs编一个用asio写的程序,发现在tcp::acceptor::open()失败,查了好久,发现是acceptor绑定的io_service没有正确的初始化,又查了半天,发现是需要加一个预编译 ...

  3. 非常简单的XML解析(SAX解析、pull解析)

    这里只是把解析的数据当日志打出来了 非常简单的xml解析方式 package com.example.demo.service; import java.io.IOException; import ...

  4. C与Python变量的区别

    C中变量有类型,代表一定内存. 而Python变量只是封装过的指针,没有类型.如果不指向对象,就没有意义,更谈不上类型. python中 a=b,和C中 a=b是完全不同的两个操作.前者只是指针(引用 ...

  5. SSIS包配置动态配置数据库连接

    动态连接数据库便于维护 用SSIS包配置实现 1.控制流页签 - 右键 - 包配置 2.配置xml文件 3.指定连接属性:ServerName.UserName.Password 测试: 1.配置错误 ...

  6. android 4&period;4&period;3 css hack 写法

    最近发现android在4.4.3上面出现很多怪异的现象,现在虽然没有找到原因和解决方案,但是突然间找到一个css hack写法: button{ display:none; width:$rem*4 ...

  7. Spring MVC核心技术

    目录 异常处理 类型转换器 数据验证 文件上传与下载 拦截器 异常处理 Spring MVC中, 系统的DAO, Service, Controller层出现异常, 均通过throw Exceptio ...

  8. FFmpeg源代码简单分析:avformat&lowbar;alloc&lowbar;output&lowbar;context2&lpar;&rpar;

    ===================================================== FFmpeg的库函数源代码分析文章列表: [架构图] FFmpeg源代码结构图 - 解码 F ...

  9. Linux运维笔记-日常操作命令总结(3)

    文本操作:sed sed是一个很好的文件处理工具,本身是一个管道命令,主要是以行为单位进行处理,可以将数据行进行替换.删除.新增.选取等特定工作. sed命令行格式为: sed [-nefri] ‘c ...

  10. Java,JavaScript,jQuery,jSP,js

    js是javascript文件的文件后缀,就像 a.txt 这个.txt是后缀一样 jsp是jsp网页文件的后缀,而jsp是java web 的表现层的一种技术 jquery 是一个函数库,基于jav ...