美文网首页
【greenDAO3】 项目搭建与增删改查操作【转】

【greenDAO3】 项目搭建与增删改查操作【转】

作者: KtYY | 来源:发表于2018-10-27 09:13 被阅读0次

    最近需要开始一个新的项目了,考虑到既然是新项目了,那么一些常用的框架肯定也要用当下最火的!这次的新项目中涉及到了本地数据存储,很早前有个项目的本地数据库框架用的是ActiveAndroid,github找了下这个框架,发现已经两年多已经没有更新了。然后就想到了一直没有时间去涉及到的greenDAO,github一搜索,哦呦?star有5000+,并且依然保持着很高的更新频率,并且性能远远的高于activeAndroid(见下图),果断选用。


    image.png

    刚开始想偷偷懒,大致浏览了下greenDAO官网后就开始百度一些相关教程(毕竟看中文的速度快啊!!!)。找教程中也看到了很多质量很高的文章,但是看上去都有点怪怪的,感觉和官网的最新版本介绍的完全不是一个东西,主要是在导包以及生成代码的方式。最后发现是因为greenDAO2和3的构建和生成代码的方式变化了不少,所以最后还是老老实实的回去看官文了,废话了这么多,下面开始正题!!

    【一】greenDAO3基本介绍

    greenDAO3开始使用注解的方式定义实体类(entity),并且是通过安装gradle插件来生成代码。之前的版本则是通过建立一个独立的java工程来存放生成的文件。

    【二】导入相关的包

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

    这一步很简单,在gradle的dependencies中导入最新版本的依赖就可以了

    【三】配置gradle

    这一步非常关键,这是整个grennDAO3改变的核心所在了。先加入如下代码

    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.wyk.greendaodemo.greendao.gen'
        targetGenDir 'src/main/java'
    }
    

    在gradle的根模块中加入上述代码,就完成了我们的基本配置了。

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

    贴上完整代码图:


    image.png

    【四】编写entity类

    通过greenDAO3注解的语法来定义我们的一个测试数据库实体类:

    import org.greenrobot.greendao.annotation.Entity;
    import org.greenrobot.greendao.annotation.Id;
    import org.greenrobot.greendao.annotation.Transient;
     
    @Entity
    public class User {
        @Id
        private Long id;
        private String name;
        @Transient
        private int tempUsageCount; // not persisted
    }
    

    @Entity:将我们的java普通类变为一个能够被greenDAO识别的数据库类型的实体类
    @Id:通过这个注解标记的字段必须是Long类型的,这个字段在数据库中表示它就是主键,并且它默认就是自增的

    @Transient:表明这个字段不会被写入数据库,只是作为一个普通的java类字段,用来临时存储数据的,不会被持久化

    接下来让我们点击as中Build菜单栏中的Make Project,make完成之后会发现我们的User类中突然多了好多代码,这就是greenDAO自动为你生成的了,代码如下

    import org.greenrobot.greendao.annotation.Entity;
    import org.greenrobot.greendao.annotation.Id;
    import org.greenrobot.greendao.annotation.Transient;
    import org.greenrobot.greendao.annotation.Generated;
     
    @Entity
    public class User {
        @Id
        private Long id;
        private String name;
        @Transient
        private int tempUsageCount; // not persisted
        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() {
        }
    }
    

    上述生成的代码中包含了构造方法以及每个属性的getter setter方法。除了这个变化,还会发现在我们之前设置的targetGenDir这个目录中多了三个文件,之后所有相关的数据库操作都依靠这三个文件了。

    【五】增删改查操作

    铺垫了这么多,终于能见到我们数据库的核心功能了~

    1.第一步肯定是初始化数据库

    DaoMaster.DevOpenHelper devOpenHelper = new DaoMaster.DevOpenHelper(MyApplication.getContext(), "notes-db", null);
    DaoMaster daoMaster = new DaoMaster(devOpenHelper.getWritableDatabase());
    DaoSession daoSession = daoMaster.newSession();
    UserDao userDao = daoSession.getUserDao();
    

    “notes-db”是我们自定的数据库名字,应为我们之前创建了一个Entity叫做User,所以greenDAO自定帮我们生成的UserDao,拿到了这个UserDao,我们就可以操作User这张表了。
    一个DaoMaster就代表着一个数据库的连接;DaoSession可以让我们使用一些Entity的基本操作和获取Dao操作类,DaoSession可以创建多个,每一个都是属于同一个数据库连接的。

    2.插入数据

    User user = new User(null, "wyk");
    userDao.insert(user);
    

    非常简单,实例化一个User对象,然后调用userDao的insert方法就可以了。将User对象的id设置为null的时候,数据库会自动为其分配自增的id。
    3.查找数据

    List<User> userList = userDao.queryBuilder()
           .where(UserDao.Properties.Id.notEq(999))
           .orderAsc(UserDao.Properties.Id)
           .limit(5)
           .build().list();
    

    通过userDao的queryBuilder()方法,生成一个查找构造器,可以给构造器添加where条件判断、按照某某字段排序以及查询的条数等基本的数据库操作。list()方法表示查询的结果为一个集合.

    4.修改数据

    User findUser = userDao.queryBuilder().where(UserDao.Properties.Name.eq("wyk")).build().unique();
    if(findUser != null) {
        findUser.setName(newName);
        userDao.update(findUser);
        Toast.makeText(MyApplication.getContext(), "修改成功", Toast.LENGTH_SHORT).show();
    } else {
        Toast.makeText(MyApplication.getContext(), "用户不存在", Toast.LENGTH_SHORT).show();
    }
    

    修改数据的第一步是把需要修改的条目给查询出来,然后修改该条目,最后调用userDao的update方法即可。unique()表示查询结果为一条数据,若数据不存在,findUser为null。
    5.删除数据

    User findUser = userDao.queryBuilder().where(UserDao.Properties.Name.eq("wyk")).build().unique();
    if(findUser != null){
        userDao.deleteByKey(findUser.getId());
    }
    

    删除数据和更新数据基本相似,先查询出需要删除的条目,然后调用userDao的deleteByKey将该条目的主键传入即可删除。

    6.自定义sql语句
    
    ChatHistoryDao dao = GreenDaoManager.getInstance().getSession().getChatHistoryDao();
    Cursor cursor = dao.getDatabase().rawQuery("select t.sales_wx_nick_name,t.wx_nick_name,count(*),t.talker_id,t.sales_wx_account from chat_history t group by t.talker_id,t.sales_wx_account order by t.created_at desc", null);
    while (cursor.moveToNext()) {
        String salesWxNickName = cursor.getString(0);
        String clientWxNickName = cursor.getString(1);
        int chatCount = cursor.getInt(2);
        int talkerId = cursor.getInt(3);
        String salesWxAccount = cursor.getString(4);
    }
    

    有的时候需要用到group by或者left join等复杂的语句,可以调用android原生的sqlite去进行查询。

    7.数据库升级

    如果某张表修改了字段,或者新增了一张表,必须要修改build.gradle中的schemaVersion,否则当你升级app的时候,如果进行了数据库操作,会发现列不匹配或者表不存在等问题,直接会导致app闪退。但是如果仅仅是将schemaVersion加1,虽然程序不会崩溃,并且数据表的结构也会更新成功,但是之前表中的数据会全部清空。我们需要进行手动操作来进行数据库里面的数据迁移,大致的思路是:创建临时表(结构与上一版本的表结构相同),将旧数据移到临时表中,删除旧版本的表,创建新版本的表,将临时表中的数据转移到新表中,最后再删除临时表。详细方法见链接:

    http://stackoverflow.com/a/30334668/5995409

    【结尾】greenDAO还有很多高级的功能,比如说给表设置一对一、一对多、多对多的关系以及复用查询语句等等等太多功能,本片文章仅仅做一个入门教学,其余的功能小伙伴们可以去官网教程中自行查阅咯~最后贴上整个demo的主要代码

    
    
    build.gradle
    
    apply plugin: 'com.android.application'
    apply plugin: 'org.greenrobot.greendao'
     
    buildscript {
        repositories {
            mavenCentral()
        }
        dependencies {
            classpath 'org.greenrobot:greendao-gradle-plugin:3.0.0'
        }
    }
     
    greendao {
        schemaVersion 1
        daoPackage 'com.wyk.greendaodemo.greendao.gen'
        targetGenDir 'src/main/java'
    }
     
    android {
        compileSdkVersion 23
        buildToolsVersion "23.0.1"
     
        defaultConfig {
            applicationId "com.wyk.greendaodemo"
            minSdkVersion 14
            targetSdkVersion 23
            versionCode 1
            versionName "1.0"
        }
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            }
        }
    }
     
    dependencies {
        compile fileTree(dir: 'libs', include: ['*.jar'])
        testCompile 'junit:junit:4.12'
        compile 'com.android.support:appcompat-v7:23.0.1'
        compile 'org.greenrobot:greendao:3.0.1'
        compile 'org.greenrobot:greendao-generator:3.0.0'
    }
    
    
    User.java
    
    package com.wyk.greendaodemo.greendao.entity;
     
    import org.greenrobot.greendao.annotation.Entity;
    import org.greenrobot.greendao.annotation.Id;
    import org.greenrobot.greendao.annotation.Transient;
    import org.greenrobot.greendao.annotation.Generated;
     
    @Entity
    public class User {
        @Id
        private Long id;
        private String name;
        @Transient
        private int tempUsageCount; // not persisted
        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() {
        }
    }
    
    
    MainActivity.java
    
    package com.wyk.greendaodemo;
     
    import android.app.Activity;
    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.wyk.greendaodemo.greendao.GreenDaoManager;
    import com.wyk.greendaodemo.greendao.entity.User;
    import com.wyk.greendaodemo.greendao.gen.UserDao;
     
    import java.util.ArrayList;
    import java.util.List;
     
    public class MainActivity extends Activity implements View.OnClickListener {
        private EditText mNameET;
        private Button mAddBtn;
        private ListView mUserLV;
     
        private UserAdapter mUserAdapter;
        private List<User> mUserList = new ArrayList<>();
     
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            initView();
            initData();
        }
     
        private void initView() {
            mNameET = (EditText) findViewById(R.id.et_name);
            mAddBtn = (Button) findViewById(R.id.btn_add);
            mUserLV = (ListView) findViewById(R.id.lv_user);
     
            mAddBtn.setOnClickListener(this);
        }
     
        private void initData() {
            mUserList = GreenDaoManager.getInstance().getSession().getUserDao().queryBuilder().build().list();
            mUserAdapter = new UserAdapter(this, mUserList);
            mUserLV.setAdapter(mUserAdapter);
        }
     
        /**
         * 根据名字更新某条数据的名字
         * @param prevName  原名字
         * @param newName  新名字
         */
        private void updateUser(String prevName,String newName){
            User findUser = GreenDaoManager.getInstance().getSession().getUserDao().queryBuilder()
                    .where(UserDao.Properties.Name.eq(prevName)).build().unique();
            if(findUser != null) {
                findUser.setName(newName);
                GreenDaoManager.getInstance().getSession().getUserDao().update(findUser);
                Toast.makeText(MyApplication.getContext(), "修改成功", Toast.LENGTH_SHORT).show();
            } else {
                Toast.makeText(MyApplication.getContext(), "用户不存在", Toast.LENGTH_SHORT).show();
            }
        }
     
        /**
         * 根据名字删除某用户
         * @param name
         */
        private void deleteUser(String name){
            UserDao userDao = GreenDaoManager.getInstance().getSession().getUserDao();
            User findUser = userDao.queryBuilder().where(UserDao.Properties.Name.eq(name)).build().unique();
            if(findUser != null){
                userDao.deleteByKey(findUser.getId());
            }
        }
     
        /**
         * 本地数据里添加一个User
         * @param id  id
         * @param name  名字
         */
        private void insertUser(Long id, String name) {
            UserDao userDao = GreenDaoManager.getInstance().getSession().getUserDao();
            User user = new User(id, name);
            userDao.insert(user);
            mNameET.setText("");
     
            mUserList.clear();
            mUserList.addAll(userDao.queryBuilder().build().list());
            mUserAdapter.notifyDataSetChanged();
        }
     
        @Override
        public void onClick(View v) {
            int viewId = v.getId();
            switch (viewId){
                case R.id.btn_add:
                    insertUser(null, mNameET.getText().toString());
                    break;
                default:
                    break;
            }
        }
    }
    
    
    activity_main.xml
    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical"
        tools:context="com.wyk.greendaodemo.MainActivity">
     
        <EditText
            android:id="@+id/et_name"
            android:layout_width="match_parent"
            android:layout_height="wrap_content" />
     
        <Button
            android:id="@+id/btn_add"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="add one" />
     
     
        <ListView
            android:id="@+id/lv_user"
            android:layout_width="match_parent"
            android:layout_height="match_parent"/>
    </LinearLayout>
    
    
    GreenDaoManager.java(greenDao管理类)
    package com.wyk.greendaodemo.greendao;
     
    import com.wyk.greendaodemo.MyApplication;
    import com.wyk.greendaodemo.greendao.gen.DaoMaster;
    import com.wyk.greendaodemo.greendao.gen.DaoSession;
     
    /**
     * Created by wyk on 2016/7/12.
     */
    public class GreenDaoManager {
        private static GreenDaoManager mInstance;
        private DaoMaster mDaoMaster;
        private DaoSession mDaoSession;
     
     
        private GreenDaoManager() {
            DaoMaster.DevOpenHelper devOpenHelper = new DaoMaster.DevOpenHelper(MyApplication.getContext(), "notes-db", null);
            DaoMaster 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;
        }
    }
    
    
    MyApplication.java
    package com.wyk.greendaodemo;
     
    import android.app.Application;
    import android.content.Context;
     
    import com.wyk.greendaodemo.greendao.GreenDaoManager;
     
    /**
     * Created by wyk on 2016/7/12.
     */
    public class MyApplication extends Application {
        private static Context mContext;
     
        @Override
        public void onCreate() {
            super.onCreate();
            mContext = getApplicationContext();
            GreenDaoManager.getInstance();
        }
     
        public static Context getContext() {
            return mContext;
        }
    }
    
    UserAdapter.java
    package com.wyk.greendaodemo;
     
    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.wyk.greendaodemo.greendao.entity.User;
     
    import java.util.List;
     
    /**
     * Created by wyk on 2016/7/12.
     */
    public class UserAdapter extends BaseAdapter {
        private List<User> mUserList;
        private Context mContext;
     
        public UserAdapter(Context mContext, List<User> mUserList) {
            this.mUserList = mUserList;
            this.mContext = mContext;
        }
     
        @Override
        public int getCount() {
            return mUserList == null ? 0 : mUserList.size();
        }
     
        @Override
        public Object getItem(int position) {
            return position;
        }
     
        @Override
        public long getItemId(int position) {
            return position;
        }
     
        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder viewHolder = null;
            if (convertView == null) {
                convertView = LayoutInflater.from(mContext).inflate(R.layout.item_user, null);
                viewHolder = new ViewHolder();
                viewHolder.tv_id = (TextView) convertView.findViewById(R.id.tv_id);
                viewHolder.tv_name = (TextView) convertView.findViewById(R.id.tv_name);
                convertView.setTag(viewHolder);
            } else {
                viewHolder = (ViewHolder) convertView.getTag();
            }
     
            User user = mUserList.get(position);
            viewHolder.tv_id.setText(String.valueOf(user.getId()));
            viewHolder.tv_name.setText(user.getName());
     
            return convertView;
        }
     
        class ViewHolder {
            TextView tv_id;
            TextView tv_name;
        }
    }
    

    项目结构

    文章如果有没能解释清楚的地方以及讲错的地方,请及时提出,谢谢!

    作者:nj物是人非
    来源:CSDN
    原文:https://blog.csdn.net/njweiyukun/article/details/51893092
    版权声明:本文为博主原创文章,转载请附上博文链接!

    相关文章

      网友评论

          本文标题:【greenDAO3】 项目搭建与增删改查操作【转】

          本文链接:https://www.haomeiwen.com/subject/idirtqtx.html