Android ORM框架greenDao3.0使用简介

本文转自:http://www.jianshu.com/p/f2737d23cb2a

本例只介绍了 greenDAO 的基本用法与配置,更高级与详细的使用,请参见官方的API文档:http://greenrobot.org/greendao/documentation/javadoc/

greenDao 介绍

在平时的开发过程中,大家一定会或多或少地接触到 SQLite。然而在使用它时,我们往往需要做许多额外的工作,像编写 SQL 语句与解析查询结果等。

greenDAO是一个对象关系映射(ORM)的框架,能够提供一个接口通过操作对象的方式去操作关系型数据库,它能够让你操作数据库时更简单、更方便。


greenDAO

官网:http://greenrobot.org/greendao/
GitHub:https://github.com/greenrobot/greenDAO

之前发布的1.X和2.X版本是比较难用的。需要新建Java Module,然后再项目中配置各个实体的字段等相关属性,然后生成实体以及DAO操作相关的一些类。但是,当你修改了实体中的一些属性,并且这些属性又要在数据库中保存的时候,你会发现每次重新运行generator之前的改变都得重新再来一次。有兴趣的同学可以自行去了解,这里给出个学习链接:http://www.open-open.com/lib/view/open1438065400878.html

关于性能方面,greenDAO 性能远远高于同类的 ORMLite,具体测试结果可见官网:http://greenrobot.org/greendao/features/


性能

实例讲解:

greenDAO3开始使用注解的方式定义实体类(entity),并且是通过安装gradle插件来生成代码。省去了新建项目的繁琐,使用起来也更加简洁明了,我们今天就来讲讲如何使用greenDao3。废话不多说,新手入门直接上Demo代码。


代码结构

完整代码地址:https://github.com/hibernate3/GreenDaoDemo
环境:JDK 1.8,AndroidStudio 2.2.3

配置gradle

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

在gradle的根模块中加入上述代码后,sync project的时候,gradle会自动去maven仓库下载一个gradle的插件,当然了,这个插件就是为greenDAO服务的,用来生成数据库相关的代码。

简单的介绍下通过gradle插件生成数据库代码的步骤:每次在make project之前,它会扫描项目中所有的@Entity文件(greenDAO中数据库的实体类),根据实体类生成DaoSession、DaoMaster以及所有实体类的dao类,生成的文件默认目录为:build/generated/source/greendao,若不想修改生成的路径,可以将此路径设置为资源目录。我们也可以自定义这个路径,下面就来介绍如何在gradle中配置greenDAO的相关属性:

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

在gradle的根模块中加入上述代码,就完成了我们的基本配置了。
schemaVersion---->指定数据库schema版本号,迁移等操作会用到
daoPackage-------->通过gradle插件生成的数据库相关文件的包名,默认为你的entity所在的包名
targetGenDir-------->这就是我们上面说到的自定义生成数据库文件的目录了,可以将生成的文件放到我们的java目录中,而不是build中,这样就不用额外的设置资源目录了

完整的gradle配置代码:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "25.0.1"
    defaultConfig {
        applicationId "com.example.greendaodemo"
        minSdkVersion 15
        targetSdkVersion 23
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

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

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

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:23.4.0'
    testCompile 'junit:junit:4.12'

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

    //ButterKnife
    compile 'com.jakewharton:butterknife:8.4.0'
    annotationProcessor 'com.jakewharton:butterknife-compiler:8.4.0'
}

编写实体类

package com.example.greendaodemo.greendao.entity;

import org.greenrobot.greendao.annotation.Entity;
import org.greenrobot.greendao.annotation.Generated;
import org.greenrobot.greendao.annotation.Id;
import org.greenrobot.greendao.annotation.Transient;
import org.greenrobot.greendao.annotation.Unique;

/**
 * Created by Steven on 16/12/20.
 */
@Entity
public class User {
    @Id
    private Long id;
    @Unique
    private String name;
    @Transient
    private int tempUsageCount;
}

编译项目,User实体类会自动编译,生成get、set方法并且会在com.example.greendaodemo.greendao.gen目录下生成三个文件,DaoMaster 、DaoSession、Dao类:

package com.example.greendaodemo.greendao.entity;

import org.greenrobot.greendao.annotation.Entity;
import org.greenrobot.greendao.annotation.Generated;
import org.greenrobot.greendao.annotation.Id;
import org.greenrobot.greendao.annotation.Transient;
import org.greenrobot.greendao.annotation.Unique;

/**
 * Created by Steven on 16/12/20.
 */
@Entity
public class User {
    @Id
    private Long id;
    @Unique
    private String name;
    @Transient
    private int tempUsageCount;

    public String getName() {
        return this.name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Long getId() {
        return this.id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    @Generated(hash = 873297011)
    public User(Long id, String name) {
        this.id = id;
        this.name = name;
    }
    @Generated(hash = 586692638)
    public User() {
    }
}

自动生成的文件

关于greenDao3的注解

1.实体注解:
@Entity:将我们的java普通类变为一个能够被greenDAO识别的数据库类型的实体类

schema:告知greenDao当前实体属于哪个schema
active:标记一个实体处于活动状态,活动实体有更新、删除和刷新方法
nameInDb:在数据中使用的别名,默认使用的是实体的类名
indexes:定义索引,可以跨越多个列
createInDb:标记创建数据库表

@Entity(
        // 如果你有超过一个的数据库结构,可以通过这个字段来区分
        // 该实体属于哪个结构
        schema = "myschema",

        //  实体是否激活的标志,激活的实体有更新,删除和刷新的方法
        active = true,

        // 确定数据库中表的名称
        // 表名称默认是实体类的名称
        nameInDb = "AWESOME_USERS",

        // Define indexes spanning multiple columns here.
        indexes = {
                @Index(value = "name DESC", unique = true)
        },

        // DAO是否应该创建数据库表的标志(默认为true)
        // 如果你有多对一的表,将这个字段设置为false
        // 或者你已经在GreenDAO之外创建了表,也将其置为false
        createInDb = false
)
public class User {
  ...
}

2.基础属性注解:
@Id :主键 Long型,可以通过@Id(autoincrement = true)设置自增长
@Property:设置一个非默认关系映射所对应的列名,默认是的使用字段名 举例:@Property (nameInDb="name")
@NotNull:设置数据库表当前列不能为空
@Transient :添加次标记之后不会生成数据库表的列

3.索引注解:
@Index:使用@Index作为一个属性来创建一个索引,通过name设置索引别名,也可以通过unique给索引添加约束
@Unique:向数据库列添加了一个唯一的约束

4.关系注解:
@ToOne:定义与另一个实体(一个实体对象)的关系
@ToMany:定义与多个实体对象的关系

初始化数据库

创建GreenDaoManager.java:

package com.example.greendaodemo.greendao;

import com.example.greendaodemo.MainApplication;
import com.example.greendaodemo.greendao.gen.DaoMaster;
import com.example.greendaodemo.greendao.gen.DaoSession;
import com.example.greendaodemo.greendao.gen.UserDao;
/**
 * Created by Steven on 16/12/20.
 */
public class GreenDaoManager {
    private static GreenDaoManager mInstance;
    private DaoMaster mDaoMaster;
    private DaoSession mDaoSession;

    private GreenDaoManager() {
        DaoMaster.DevOpenHelper devOpenHelper = new DaoMaster.DevOpenHelper(MainApplication.getContext(),                "users-db", null);
        mDaoMaster = new DaoMaster(devOpenHelper.getWritableDatabase());
        mDaoSession = mDaoMaster.newSession();
    }

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

    public DaoMaster getMaster() {
        return mDaoMaster;
    }

    public DaoSession getSession() {
        return mDaoSession;
    }

    public DaoSession getNewSession() {
        mDaoSession = mDaoMaster.newSession();
        return mDaoSession;
    }
}

官方推荐将获取 DaoMaster 对象的方法放到 Application 层,这样将避免多次创建生成 Session 对象,不过也可以在代码中写好规避,看个人习惯。

package com.example.greendaodemo;

import android.app.Application;
import android.content.Context;
import com.example.greendaodemo.greendao.GreenDaoManager;

/**
 * Created by Steven on 16/12/20.
 */
public class MainApplication extends Application {
    private static Context mContext;

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

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

增删改查操作

这里就没有用MVP那一套定义interface和presenter那些东西了,直接在Activity中处理业务逻辑了。新手学习简单清晰一点。直接贴上Activity的代码,布局文件和Adapter请在GitHub上查看,这里主要关注业务处理函数:

package com.example.greendaodemo;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;

import com.example.greendaodemo.greendao.GreenDaoManager;
import com.example.greendaodemo.greendao.entity.User;
import com.example.greendaodemo.greendao.gen.UserDao;

import java.util.ArrayList;
import java.util.List;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

public class MainActivity extends AppCompatActivity {
    @BindView(R.id.et_name) EditText mNameET;
    @BindView(R.id.btn_add) Button mAddBtn;
    @BindView(R.id.btn_query) Button mQueryBtn;
    @BindView(R.id.btn_delete) Button mDeleteBtn;
    @BindView(R.id.btn_update) Button mUpdateBtn;
    @BindView(R.id.lv_user) ListView mUserLV;

    private UserAdapter mUserAdapter;
    private List<User> mUserList = new ArrayList<>();

    private UserDao mUserDao;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ButterKnife.bind(this);

        initData();
    }

    private void initData() {
        mUserDao = GreenDaoManager.getInstance().getSession().getUserDao();

        mUserList = GreenDaoManager.getInstance()
                .getSession().getUserDao().queryBuilder().build().list();
        mUserAdapter = new UserAdapter(this, mUserList);
        mUserLV.setAdapter(mUserAdapter);
    }

    //查询
    private void queryUser(String name) {
        List result = mUserDao.queryBuilder()
                .where(UserDao.Properties.Name.eq(name)).build().list();

        Toast.makeText(MainApplication.getContext(), "查询到:" + result.size() + "条结果",
                Toast.LENGTH_SHORT).show();
    }

    //更新
    private void updateUser(String prevName, String newName) {
        User findUser = mUserDao.queryBuilder()
                .where(UserDao.Properties.Name.eq(prevName)).build().unique();
        if (findUser != null) {
            findUser.setName(newName);
            mUserDao.update(findUser);
            Toast.makeText(MainApplication.getContext(), "修改成功", Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(MainApplication.getContext(), "用户不存在", Toast.LENGTH_SHORT).show();
        }

        refreshListView();
    }

    //删除
    private void deleteUser(String name) {
        User findUser = mUserDao.queryBuilder()
                .where(UserDao.Properties.Name.eq(name)).build().unique();
        if(findUser != null) {
            mUserDao.deleteByKey(findUser.getId());
            Toast.makeText(MainApplication.getContext(), "删除成功", Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(MainApplication.getContext(), "用户不存在", Toast.LENGTH_SHORT).show();
        }

        refreshListView();
    }

    //插入
    private void insertUser(Long id, String name) {
        User user = new User(id, name);
        mUserDao.insertOrReplace(user);

        refreshListView();
    }

    private void refreshListView() {
        mNameET.setText("");

        mUserList.clear();
        mUserList.addAll(mUserDao.queryBuilder().build().list());
        mUserAdapter.notifyDataSetChanged();
    }

    @OnClick({R.id.btn_add, R.id.btn_query, R.id.btn_update, R.id.btn_delete})
    public void onButtonsClick(View v) {
        int viewId = v.getId();
        switch (viewId) {
            case R.id.btn_add:
                insertUser(null, mNameET.getText().toString());
                break;
            case R.id.btn_query:
                queryUser(mNameET.getText().toString());
                break;
            case R.id.btn_update:
                updateUser(mNameET.getText().toString(), "" + System.currentTimeMillis());
                break;
            case R.id.btn_delete:
                deleteUser(mNameET.getText().toString());
                break;
            default:
                break;
        }
    }
}

数据库升级

1.修改gradle文件

   首先在module的gradle文件中修改版本号:
   //这里改为最新的版本号 schemaVersion 2

2.修改实体类

@Entity
public class User {
    @Property
    private int age;
    @Property
    private String password;
    @Id
    private Long id;
    @Property(nameInDb = "USERNAME")
    private String username;
    @Property(nameInDb = "NICKNAME")
    private String nickname;
}

重新编译项目运行即可。一般的数据库升级这样就可以了,特殊情况可能需要自己编写数据库迁移脚本

END

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值