前言
在平时的开发过程中,大家一定会或多或少地接触到 SQLite。然而在使用它时,我们往往需要做许多额外的工作,像编写 SQL 语句与解析查询结果等。所以,适用于 Android 的ORM 框架也就孕育而生了,现在市面上主流的框架有 OrmLite、SugarORM、Active Android、Realm 与 GreenDAO。而今天的主角便是 greenDAO,下面,我将详解地介绍如何在 Android Studio 上使用 greenDAO,并结合代码总结一些使用过程中的心得。
greenDao的主要特点
- greenDAO 性能远远高于同类的 ORMLite,具体测试结果可见官网
- greenDAO 支持 protocol buffer(protobuf) 协议数据的直接存储,如果你通过 protobuf 协议与服务器交互,将不需要任何的映射。
- 与 ORMLite 等使用注解方式的 ORM 框架不同,greenDAO 使用「Code generation」的方式,这也是其性能能大幅提升的原因。
一,在Anroid工程中
1.在 .src/main 目录下新建一个与 java 同层级的「java-gen」目录,用于存放由 greenDAO 生成的 Bean、DAO、DaoMaster、DaoSession 等类。
2.配置 Android 工程(app)的 build.gradle,如图分别添加 sourceSets 与dependencies。
二,在Java工程中
1.通过 File -> New -> New Module -> Java Library -> 填写相应的包名与类名 -> Finish.
2.配置 Java 工程(lib)的 build.gradle,如图添加 dependencies。
3.编写 MyClass 类。以下为主要代码:
public class MyClass {
public static void main(String[] args) throws Exception {
// 两个参数分别代表:数据库版本号与自动生成代码的包路径。
Schema schema = new Schema(1, "com.gmrz.greendaodemo.dao");
addNote(schema);
new DaoGenerator().generateAll(schema, "../GreenDaoDemo/app/src/main/java-gen");
}
private static void addNote(Schema schema) {
Entity note = schema.addEntity("Note");
note.addIdProperty();
note.addStringProperty("text").notNull();
note.addStringProperty("comment");
note.addDateProperty("date");
}
}
4.执行 MyClass 工程,如一切正常,你将会在控制台看到如下日志,并且在主工程「java-gen」下会发现生成了DaoMaster、DaoSession、NoteDao、Note共4个类文件。
三,回到Android工程中
这里,创建一个 MainActivity 类,用于测试 greenDAO 的增、删、查功能。
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical">
<EditText
android:id="@+id/editTextNote"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Enter a note you want to add or query"
android:inputType="text"/>
<LinearLayout
android:id="@+id/linearLayout1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<Button
android:id="@+id/btn_add"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="onBtnClick"
android:text="Add"/>
<Button
android:id="@+id/btn_query"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:onClick="onBtnClick"
android:text="Query"/>
</LinearLayout>
<ListView
android:id="@android:id/list"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
</LinearLayout>
MainActivity
package com.gmrz.greendaodemo;
import android.app.ListActivity;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.CursorAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.Toast;
import com.gmrz.greendaodemo.dao.Note;
import com.gmrz.greendaodemo.dao.NoteDao;
import com.gmrz.greendaodemo.utils.ApplicationUtil;
import java.text.DateFormat;
import java.util.Date;
import java.util.List;
import de.greenrobot.dao.query.Query;
import de.greenrobot.dao.query.QueryBuilder;
public class MainActivity extends ListActivity {
private String TAG = MainActivity.class.getSimpleName();
private EditText mEditText;
private Cursor mCursor;
private SimpleCursorAdapter mAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
initData();
}
public void onBtnClick(View view) {
switch (view.getId()) {
case R.id.btn_add:
addNote();
break;
case R.id.btn_query:
queryNote();
break;
default:
break;
}
}
@Override
protected void onListItemClick(ListView l, View v, int position, long id) {
// 删除操作,可以通过「id」也可以一次性删除所有 getNoteDao().deleteAll();
getNoteDao().deleteByKey(id);
Toast.makeText(this, "Deleted note, ID: " + id, Toast.LENGTH_SHORT).show();
mCursor.requery();
}
private void queryNote() {
String noteText = mEditText.getText().toString().trim();
mEditText.setText("");
if (TextUtils.isEmpty(noteText)) {
Toast.makeText(this, "please enter a note to query", Toast.LENGTH_SHORT).show();
} else {
// Query 类代表了一个可以被重复执行的查询
Query query = getNoteDao().queryBuilder()
.where(NoteDao.Properties.Text.eq(noteText))
.orderAsc(NoteDao.Properties.Date)
.build();
// 查询结果以 List 返回
List list = query.list();
Toast.makeText(this, "There have " + list.size() + " records", Toast.LENGTH_SHORT).show();
}
// 在 QueryBuilder 类中内置两个 Flag 用于方便输出执行的 SQL 语句与传递参数的值
QueryBuilder.LOG_SQL = true;
QueryBuilder.LOG_VALUES = true;
}
private void addNote() {
String noteText = mEditText.getText().toString().trim();
mEditText.setText("");
DateFormat df = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM);
String comment = "Added on " + df.format(new Date());
if (TextUtils.isEmpty(noteText)) {
Toast.makeText(this, "please enter a note to add", Toast.LENGTH_SHORT).show();
} else {
// 插入操作,简单到只要你创建一个 Java 对象
Note note = new Note(null, noteText, comment, new Date());
getNoteDao().insert(note);
mCursor.requery();
Log.d(TAG, "Inserted new note, ID: " + note.getId());
}
}
private void initData() {
String columnName = NoteDao.Properties.Text.columnName;
String orderBy = columnName + "COLLATE LOCALIZED ASC";
mCursor = getDb().query(getNoteDao().getTablename(), getNoteDao().getAllColumns(), null, null, null, null, orderBy);
String[] formDatas = {columnName, NoteDao.Properties.Comment.columnName};
int[] to = {android.R.id.text1, android.R.id.text2};
mAdapter = new SimpleCursorAdapter(this, android.R.layout.simple_expandable_list_item_2, mCursor, formDatas, to, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
setListAdapter(mAdapter);
}
private void initView() {
mEditText = (EditText) findViewById(R.id.editTextNote);
}
private SQLiteDatabase getDb() {
return ApplicationUtil.getDb();
}
private NoteDao getNoteDao() {
return ApplicationUtil.getDaoSession().getNoteDao();
}
}
运行结果: