快速入门GreenDao框架并实现增删改查案例

大家的项目中不可避免的使用到SQLite,为此我们要花费心思编写一个增删改查框架。而一个好的ORM框架则能够给我们带来极大的方便,今天给大家讲解一个非常火热的ORM-GreenDao。

基本概念

GreenDao官网地址:http://greenrobot.org/greendao/

官网对GreenDao的介绍:

       greenDAO is an open source library for Android providing an easy-to-use interface to SQLite to help developers handle data efficiently – relieving developers from dealing with low-level database stuff and saving development time. SQLite is an awesome embedded relational database. Still, writing SQL and parsing query results are quite tedious and time-consuming tasks. greenDAO frees you from these by mapping Java objects to database tables (often called ORM). This way you can store, update, delete, and query for Java objects using a simple object oriented API.

简单的说就是:greenDAO 是一个将对象映射到 SQLite 数据库中的轻量且快速的 ORM 解决方案。

快速入门GreenDao框架并实现增删改查案例_第1张图片

greenDAO 设计的主要目标

  • 一个精简的库
  • 性能最大化
  • 内存开销最小化
  • 易于使用的 APIs
  • 对 Android 进行高度优化

greenDAO 设计的主要特点

  • greenDAO 性能远远高于同类的 ORMLite,具体测试结果可见官网
  • greenDAO 支持 protocol buffer(protobuf) 协议数据的直接存储,如果你通过 protobuf
    协议与服务器交互,将不需要任何的映射。
  • 与 ORMLite 等使用注解方式的 ORM 框架不同,greenDAO 使用「Code
    generation」的方式,这也是其性能能大幅提升的原因。

Dao项目代码生成

快速入门GreenDao框架并实现增删改查案例_第2张图片

DaoMaster:一看名字就知道它是Dao中的最大的官了。它保存了sqlitedatebase对象以及操作DAO classes(注意:不是对象)。其提供了一些创建和删除table的静态方法,其内部类OpenHelper和DevOpenHelper实现了SQLiteOpenHelper并创建数据库的框架。
DaoSession:会话层。操作具体的DAO对象(注意:是对象),比如各种getter方法。
XXXDao:实际生成的某某DAO类,通常对应具体的java类,比如NoteDao等。其有更多的权限和方法来操作数据库元素。
XXXEntity:持久的实体对象。通常代表了一个数据库row的标准java properties。

了解了基本概念后我们开始动手完成一个增删改查的项目案例。

实现过程

1.在 Android 工程中配置「greenDao Generator」模块

在 .src/main 目录下新建一个与 java 同层级的「java-gen」目录,用于存放由 greenDAO 生成的 Bean、DAO、DaoMaster、DaoSession 等类。

快速入门GreenDao框架并实现增删改查案例_第3张图片

配置 Android 工程(app)的 build.gradle,如图分别添加 sourceSets 与 dependencies

快速入门GreenDao框架并实现增删改查案例_第4张图片

1 sourceSets {
2         main {
3             java.srcDirs = ['src/main/java', 'src/main/java-gen']
4         }
5     }
1 compile 'de.greenrobot:greendao:1.3.7'

2.新建「greenDAO Generator」模块 (纯 Java 工程)

通过 File -> New -> New Module -> Java Library -> 填写相应的包名与类名 -> Finish

快速入门GreenDao框架并实现增删改查案例_第5张图片

快速入门GreenDao框架并实现增删改查案例_第6张图片

配置 castielgreendaolb 工程的 build.gradle,添加 dependencie

快速入门GreenDao框架并实现增删改查案例_第7张图片

注意主句话,配置输出路径

 

1 def outputDir = "../app/src/main/java-gen"

 

接着,编写 CastielGreenDao类,注意: 我们的 Java 工程只有一个类,它的内容决定了「GreenDao Generator」的输出,你可以在这个类中通过对象、关系等创建数据库结构,下面我将以注释的形式详细讲解代码内容。

快速入门GreenDao框架并实现增删改查案例_第8张图片

 1 package com.castiel.dao;
 2 
 3 import de.greenrobot.daogenerator.DaoGenerator;
 4 import de.greenrobot.daogenerator.Entity;
 5 import de.greenrobot.daogenerator.Schema;
 6 
 7 public class CastielGreenDao {
 8     public static void main(String args[]) throws Exception {
 9         // 创建了一个用于添加实体(Entity)的模式(Schema)对象。
10         // 两个参数分别代表:数据库版本号与自动生成代码的包路径。
11         Schema schema = new Schema(1, "greendao");
12         schema.setDefaultJavaPackageDao("com.castiel.dao");
13 
14         // 一旦你拥有了一个 Schema 对象后,你便可以使用它添加实体(Entities)了。
15         addNote(schema);
16 
17         // 最后我们将使用 DAOGenerator 类的 generateAll() 方法自动生成代码,此处你需要根据自己的情况更改输出目录(既之前创建的 java-gen)。
18         new DaoGenerator().generateAll(schema, args[0]);
19     }
20 
21     /** * @param schema */
22     private static void addNote(Schema schema) {
23         // 一个实体(类)就关联到数据库中的一张表,此处表名为「Student」(既类名)
24         Entity note = schema.addEntity("Student");
25         // 你也可以重新给表命名
26         // note.setTableName("Student2");
27 
28         // greenDAO 会自动根据实体类的属性值来创建表字段,并赋予默认值
29         // 接下来你便可以设置表中的字段:
30         // 与在 Java 中使用驼峰命名法不同,默认数据库中的命名是使用大写和下划线来分割单词的。
31         note.addIdProperty();
32         note.addStringProperty("sName").notNull();
33         note.addStringProperty("sAge");
34         note.addStringProperty("sSex");
35         note.addStringProperty("sClass");
36     }
37 }

3.生成 DAO 文件(数据库)

执行 generator 工程,如一切正常,你将会在控制台看到如下日志,并且在主工程「java-gen」下会发现生成了DaoMaster、DaoSession、StudentDao、Student共4个类文件。

 1 greenDAO Generator
 2 Copyright 2011-2013 Markus Junginger, greenrobot.de. Licensed under GPL V3.
 3 This program comes with ABSOLUTELY NO WARRANTY
 4 Processing schema version 1...
 5 Written C:\Users\huangshuai\AndroidStudioProjects\CastielGreenDao\app\src\main\java-gen\com\castiel\dao\StudentDao.java
 6 Written C:\Users\huangshuai\AndroidStudioProjects\CastielGreenDao\app\src\main\java-gen\greendao\Student.java
 7 Written C:\Users\huangshuai\AndroidStudioProjects\CastielGreenDao\app\src\main\java-gen\com\castiel\dao\DaoMaster.java
 8 Written C:\Users\huangshuai\AndroidStudioProjects\CastielGreenDao\app\src\main\java-gen\com\castiel\dao\DaoSession.java
 9 Processed 1 entities in 153ms
10 
11 BUILD SUCCESSFUL

构建Android项目实现增删改查

先来张项目结构全景图

快速入门GreenDao框架并实现增删改查案例_第9张图片

再来张项目效果图

快速入门GreenDao框架并实现增删改查案例_第10张图片

在官网中,提供了一段核心初始化代码,推荐将该段代码放在Application中

 

1 helper = new DaoMaster.DevOpenHelper( this, "notes-db", null);
2 db = helper.getWritableDatabase();
3 daoMaster = new DaoMaster(db);
4 daoSession = daoMaster.newSession();
5 noteDao = daoSession.getNoteDao();

 

即:在自己的Application中先创建了一个SQLiteOpenHelper并创建连接到一个具体数据库;再根据具体的datebase创建一个master对象用于;最后通过master创建一个数据库的会话操作。

 

 1 package com.castiel.dao;
 2 
 3 import android.app.Application;
 4 import android.database.sqlite.SQLiteDatabase;
 5 
 6 /** * Created by huangshuai on 2016/5/11. * Email:[email protected] */
 7 public class BaseApplication extends Application {
 8     public DaoSession daoSession;
 9     public SQLiteDatabase db;
10     public DaoMaster.DevOpenHelper helper;
11     public DaoMaster daoMaster;
12 
13     @Override
14     public void onCreate() {
15         super.onCreate();
16         setupDatabase();
17     }
18 
19     private void setupDatabase() {
20         // 通过 DaoMaster 的内部类 DevOpenHelper,你可以得到一个便利的 SQLiteOpenHelper 对象。
21         // 可能你已经注意到了,你并不需要去编写「CREATE TABLE」这样的 SQL 语句,因为 greenDAO 已经帮你做了。
22         // 注意:默认的 DaoMaster.DevOpenHelper 会在数据库升级时,删除所有的表,意味着这将导致数据的丢失。
23         // 所以,在正式的项目中,你还应该做一层封装,来实现数据库的安全升级。
24         helper = new DaoMaster.DevOpenHelper(this, "student", null);
25         db = helper.getWritableDatabase();
26         // 注意:该数据库连接属于 DaoMaster,所以多个 Session 指的是相同的数据库连接。
27         daoMaster = new DaoMaster(db);
28         daoSession = daoMaster.newSession();
29     }
30 
31     public DaoSession getDaoSession() {
32         return daoSession;
33     }
34 
35     public SQLiteDatabase getDb() {
36         return db;
37     }
38 
39 }

 

Activity具体实现

 

  1 package com.castiel.dao;
  2 
  3 import android.app.Activity;
  4 import android.app.Dialog;
  5 import android.database.sqlite.SQLiteDatabase;
  6 import android.os.Bundle;
  7 import android.text.TextUtils;
  8 import android.view.LayoutInflater;
  9 import android.view.View;
 10 import android.widget.Button;
 11 import android.widget.EditText;
 12 import android.widget.ListView;
 13 import android.widget.Toast;
 14 
 15 import java.util.List;
 16 
 17 import de.greenrobot.dao.query.Query;
 18 import greendao.Student;
 19 
 20 /** * Created by huangshuai on 2016/5/11. * Email:[email protected] * GreenDao增删改查实例 */
 21 public class CastielActivity extends Activity implements StudentAdapter.AdapterEnterCallBack{
 22     // 初始化组件
 23     public static final String TAG = "WY";
 24     private List listStudent;
 25     private ListView list;
 26     private EditText etQureyName;
 27     StudentAdapter studentAdapter;
 28     private Button btnAdd,btnQurey;
 29     @Override
 30     public void onCreate(Bundle savedInstanceState) {
 31         super.onCreate(savedInstanceState);
 32         setContentView(R.layout.main_dao);
 33         list = (ListView) findViewById(R.id.dao_list);
 34         btnAdd = (Button) findViewById(R.id.btn_add);
 35         btnQurey = (Button) findViewById(R.id.btn_query);
 36         etQureyName = (EditText) findViewById(R.id.edit_query);
 37         listStudent = getStudentDao().loadAll();// 查询全部数据操作
 38         studentAdapter = new StudentAdapter(CastielActivity.this,listStudent);
 39 
 40         list.setAdapter(studentAdapter);
 41         studentAdapter.setCallback(this);
 42 
 43         btnAdd.setOnClickListener(new View.OnClickListener() {
 44             @Override
 45             public void onClick(View v) {
 46                 dialogAdd();
 47             }
 48         });
 49 
 50         btnQurey.setOnClickListener(new View.OnClickListener() {
 51             @Override
 52             public void onClick(View v) {
 53                 String curCondition = etQureyName.getText().toString().trim();
 54                 if (TextUtils.isEmpty(curCondition)) {
 55                     Toast.makeText(CastielActivity.this,"查询条件不能为空",Toast.LENGTH_SHORT).show();
 56                 } else {
 57                     // Query 类代表了一个可以被重复执行的查询
 58                     Query query = getStudentDao().queryBuilder()
 59                             .where(StudentDao.Properties.SName.eq(curCondition))
 60                             .build();
 61                     // 查询结果以 List 返回
 62                     List students = query.list();
 63                     Toast.makeText(CastielActivity.this,"有" + students.size() + "个条件符合",Toast.LENGTH_SHORT).show();
 64                 }
 65                 etQureyName.setText("");// 查询后重置条件
 66             }
 67         });
 68     }
 69 
 70     /** * 通过 BaseApplication 类提供的 getDaoSession() 获取具体 Dao * @return */
 71     private StudentDao getStudentDao() {
 72         return ((BaseApplication) this.getApplicationContext()).getDaoSession().getStudentDao();
 73     }
 74 
 75     /** * 通过 BaseApplication 类提供的 getDb() 获取具体 db * @return */
 76     private SQLiteDatabase getDb() {
 77         return ((BaseApplication) this.getApplicationContext()).getDb();
 78     }
 79 
 80     /** * 添加操作弹窗 */
 81     protected void dialogAdd() {
 82         final Dialog dataDialog = new Dialog(CastielActivity.this,R.style.myDialogTheme);
 83         LayoutInflater curInfnfalater = LayoutInflater.from(this);
 84         View view = curInfnfalater.inflate(R.layout.my_dialog, null);
 85         Button b_ok,b_cancle;
 86         final EditText etName,etSex,etClass,etAge;
 87         etName = (EditText) view.findViewById(R.id.edit_name);
 88         etSex = (EditText) view.findViewById(R.id.edit_sex);
 89         etClass = (EditText) view.findViewById(R.id.edit_class);
 90         etAge = (EditText) view.findViewById(R.id.edit_age);
 91 
 92 
 93         b_ok = (Button) view.findViewById(R.id.btn_ok);
 94         b_ok.setOnClickListener(new Button.OnClickListener() {
 95             public void onClick(View v) {
 96                 Student ss = new Student(null,etName.getText().toString().trim(),etAge.getText().toString().trim(),etSex.getText().toString().trim(),etClass.getText().toString().trim());
 97                 getStudentDao().insert(ss);
 98                 studentAdapter.addData(ss);
 99                 dataDialog.dismiss();
100             }
101         });
102         b_cancle = (Button) view.findViewById(R.id.btn_cancel);
103         b_cancle.setOnClickListener(new Button.OnClickListener() {
104             public void onClick(View v) {
105                 dataDialog.dismiss();
106             }
107         });
108 
109 
110         dataDialog.setContentView(view);
111         dataDialog.show();
112     }
113 
114     /** * 修改操作弹窗 */
115     protected void dialogModify(final Student curBean) {
116         final Dialog dataDialog = new Dialog(CastielActivity.this,R.style.myDialogTheme);
117         LayoutInflater curInfnfalater = LayoutInflater.from(this);
118         View view = curInfnfalater.inflate(R.layout.my_dialog, null);
119         Button b_ok,b_cancle;
120         final EditText etName,etSex,etClass,etAge;
121         etName = (EditText) view.findViewById(R.id.edit_name);
122         etSex = (EditText) view.findViewById(R.id.edit_sex);
123         etClass = (EditText) view.findViewById(R.id.edit_class);
124         etAge = (EditText) view.findViewById(R.id.edit_age);
125         etName.setText(curBean.getSName());
126         etSex.setText(curBean.getSSex());
127         etClass.setText(curBean.getSClass());
128         etAge.setText(curBean.getSAge());
129 
130         b_ok = (Button) view.findViewById(R.id.btn_ok);
131         b_ok.setOnClickListener(new Button.OnClickListener() {
132             public void onClick(View v) {
133                 Student ss = new Student(curBean.getId(),etName.getText().toString().trim(),etAge.getText().toString().trim(),etSex.getText().toString().trim(),etClass.getText().toString().trim());
134                 getStudentDao().deleteByKey(curBean.getId());
135                 getStudentDao().insert(ss);
136                 studentAdapter.setData(getStudentDao().loadAll());
137                 dataDialog.dismiss();
138             }
139         });
140         b_cancle = (Button) view.findViewById(R.id.btn_cancel);
141         b_cancle.setOnClickListener(new Button.OnClickListener() {
142             public void onClick(View v) {
143                 dataDialog.dismiss();
144             }
145         });
146 
147 
148         dataDialog.setContentView(view);
149         dataDialog.show();
150     }
151 
152     /**菜单弹窗 */
153     protected void dialogMenu(final Student curBean) {
154         final Dialog dataDialog = new Dialog(CastielActivity.this,R.style.myDialogTheme);
155         LayoutInflater curInfnfalater = LayoutInflater.from(this);
156         View view = curInfnfalater.inflate(R.layout.item_dialog, null);
157         Button b_modify,b_del;
158 
159         b_modify = (Button) view.findViewById(R.id.btn_modify);
160         b_modify.setOnClickListener(new Button.OnClickListener() {
161             public void onClick(View v) {
162                 dialogModify(curBean);
163                 dataDialog.dismiss();
164             }
165         });
166         b_del = (Button) view.findViewById(R.id.btn_del);
167         b_del.setOnClickListener(new Button.OnClickListener() {
168             public void onClick(View v) {
169                 // 根据Id删除对应数据
170                 getStudentDao().deleteByKey(curBean.getId());
171                 studentAdapter.setData(getStudentDao().loadAll());
172                 dataDialog.dismiss();
173             }
174         });
175 
176 
177         dataDialog.setContentView(view);
178         dataDialog.show();
179     }
180 
181     @Override
182     public void onEnterClick(Student bean) {
183         dialogMenu(bean);
184     }
185 }

 

列表相关Adapter

 

  1 package com.castiel.dao;
  2 
  3 import android.content.Context;
  4 import android.view.LayoutInflater;
  5 import android.view.View;
  6 import android.view.ViewGroup;
  7 import android.widget.BaseAdapter;
  8 import android.widget.LinearLayout;
  9 import android.widget.TextView;
 10 
 11 import java.util.List;
 12 
 13 import greendao.Student;
 14 
 15 /** * Created by huangshuai on 2016/5/11. * Email:[email protected] * Student列表的Adapter */
 16 public class StudentAdapter extends BaseAdapter {
 17     private AdapterEnterCallBack callback;
 18     private LayoutInflater inflater;
 19     private List list_student;
 20 
 21     public StudentAdapter(Context context, List list_student) {
 22         this.inflater = LayoutInflater.from(context);
 23         this.list_student = list_student;
 24     }
 25 
 26     @Override
 27     public int getCount() {
 28         return list_student.size();
 29     }
 30 
 31     @Override
 32     public Object getItem(int position) {
 33         return list_student.get(position);
 34     }
 35 
 36     @Override
 37     public long getItemId(int position) {
 38         return position;
 39     }
 40 
 41     @Override
 42     public View getView(final int position, View convertView, ViewGroup parent) {
 43         StudentViewHodler sv;
 44         if (convertView == null) {
 45             sv = new StudentViewHodler();
 46             convertView = inflater.inflate(R.layout.list_item, null);
 47             sv.uAge = (TextView) convertView.findViewById(R.id.tv_age);
 48             sv.uName = (TextView) convertView.findViewById(R.id.tv_name);
 49             sv.uSex = (TextView) convertView.findViewById(R.id.tv_sex);
 50             sv.uClass = (TextView) convertView.findViewById(R.id.tv_class);
 51             sv.litem = (LinearLayout) convertView.findViewById(R.id.ll_item);
 52 
 53             convertView.setTag(sv);
 54         } else {
 55             sv = (StudentViewHodler) convertView.getTag();
 56         }
 57 
 58         sv.uSex.setText(list_student.get(position).getSSex());
 59         sv.uName.setText(list_student.get(position).getSName());
 60         sv.uAge.setText(list_student.get(position).getSAge());
 61         sv.uClass.setText(list_student.get(position).getSClass());
 62         sv.litem.setOnClickListener(new View.OnClickListener() {
 63             @Override
 64             public void onClick(View v) {
 65                 if (null != callback) {
 66                     callback.onEnterClick(list_student.get(position));
 67                 }
 68             }
 69         });
 70         return convertView;
 71     }
 72 
 73     public void addData(Student data) {
 74         if (data != null) {
 75             this.list_student.add(data);
 76             notifyDataSetChanged();
 77         }
 78     }
 79 
 80     public void setData(List data) {
 81         if (data != null) {
 82             list_student.clear();
 83             list_student.addAll(data);
 84             notifyDataSetChanged();
 85         }
 86     }
 87 
 88     public class StudentViewHodler {
 89         TextView uName;
 90         TextView uSex;
 91         TextView uAge;
 92         TextView uClass;
 93         LinearLayout litem;
 94     }
 95 
 96     public interface AdapterEnterCallBack {
 97         void onEnterClick(Student bean);
 98     }
 99 
100     public void setCallback(AdapterEnterCallBack callback) {
101         this.callback = callback;
102     }
103 
104 }

 

布局文件实现

item_dialog.xml

1 
2 
3 
4     

list_item.xml

 

 1 
 2 
 3 
 4     
 5 
 6     
 7 
 8     
 9 
10     
11 
12 

 

main_dao.xml

 

 1 
 2 
 3 
 4     
 5 
 6         

 

my_dialog.xml

 

 1 
 2 
 3 
 4     
 5 
 6         
 7 
 8             
 9 
10                 
11 
12                 
13             
14 
15             
16 
17                 
18 
19                 
20             
21         
22 
23         
24 
25             
26 
27                 
28 
29                 
30             
31 
32             
33 
34                 
35 
36                 
37             
38         
39 
40     
41 
42     
43 
44         

 

运行程序,执行增删改查

快速入门GreenDao框架并实现增删改查案例_第11张图片

项目源码链接:http://download.csdn.net/detail/mynameishuangshuai/9518322

参考链接:http://itangqi.me/2015/07/26/orm-greendao-summary/

via: http://blog.csdn.net/mynameishuangshuai/article/details/51386402

 

 

 

 

 

 

 

 

转载于:https://www.cnblogs.com/huolongluo/p/5807629.html

你可能感兴趣的:(快速入门GreenDao框架并实现增删改查案例)