Android开源数据库 GreenDao实践

96
作者 lin墨
2017.09.12 18:26 字数 519

GreenDao是一款对象关系映射(ORM)的开源数据库框架, 通过将Java对象映射到数据库表,能够减轻开发人员处理低级数据库需求,同时节省开发时间。

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

greendao.png
greendao.png

这是官网给出的GreenDao图解,通过图我们很清楚的知道GreenDaojava对象SQLite数据的关系,而GreenDao的出现相当于为SQLite数据库和java对象搭建了一座桥梁。

言归正传,如此优秀的开源框架,我们来实践一下,下面的图是实践的效果图。

GreenDao.png
GreenDao.png

这里实现了数据库的增删改查操作。

项目添加GreenDao

1)、project--->build.gradle

GreenDao.png
GreenDao.png

2)、app—>build.gradle

GreenDao.png
GreenDao.png
greendao{
    schemaVersion 1                 //数据库版本号
    daoPackage'com.lwj.greendao.gen'//存放dao的包名
    targetGenDir'src/main/java'     //存放的目录
}

编写实体类

@Entity
public class Student {
    @Id(autoincrement = true)//主键设置为自增的
    private Long id;
    private String name;
    private int age;

    @Generated(hash = 352757281)
    public Student(Long id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    @Generated(hash = 1556870573)
    public Student() {
    }

    public void setId(Long id) {
        this.id = id;
    }

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

    public void setAge(int age) {
        this.age = age;
    }

    public Long getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }
}

其中

@Generated(hash = 352757281)
    public Student(Long id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    @Generated(hash = 1556870573)
    public Student() {
    }

这两个构造不需要手动写,sync project一下自动生成的,包括生成greendao下的greendao配置信息。

GreenDao.png
GreenDao.png

初始化

初始化包括DaoMasterDaoSession和建立数据库等信息。这里我建立一个管理类统一处理。

public class GreenDaoManager {

    private static GreenDaoManager mInstance = null;
    private DaoMaster mDaoMaster;
    private DaoSession mDaoSession;
    private DaoMaster.DevOpenHelper mHelper;
    private SQLiteDatabase db;

    private GreenDaoManager() {
        mHelper = new DaoMaster.DevOpenHelper(BaseApplication.getContext(), "student.db");
        db = mHelper.getWritableDatabase();
        mDaoMaster = new DaoMaster(db);
        mDaoSession = mDaoMaster.newSession();
    }

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


    public DaoSession getDaoSession() {
        return mDaoSession;
    }

    public SQLiteDatabase getDb() {
        return db;
    }

    public void setDaoMaster(DaoMaster daoMaster) {
        mDaoMaster = daoMaster;
    }

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

使用单例模式,不需要每次使用是GreenDao都初始化信息。

public class BaseApplication extends Application {

    private static Context mContext;

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

    /**
     * 获取上下文
     *
     * @return
     */
    public static Context getContext() {
        return mContext;
    }


    public static BaseApplication getInstance() {
        return (BaseApplication) mContext;
    }
}

在Application的onCreate调用管理类的初始化就好了。

实践操作

xml文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="20dp"
    tools:context="com.lwj.uiproject.GreenDaoDBActivity">

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <EditText
            android:id="@+id/edit"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"/>

        <Button
            android:id="@+id/add"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="add"/>
        <Button
            android:id="@+id/update"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="update"/>
    </LinearLayout>

    <ListView
        android:id="@+id/list_db"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginTop="20dp"/>

</LinearLayout>

Activity:

public class GreenDaoDBActivity extends AppCompatActivity {

    private EditText mEditText;
    private Button mAdd;
    private Button mUpdate;
    private ListView mListView;
    private ListAdapter mAdapter;
    private List<String> datas = new ArrayList<>();
    private StudentDao mDao;
    private static Long id = 1L;
    private Student updateInfo = null;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_green_dao_db);

        mDao = GreenDaoManager.getInstance().getDaoSession().getStudentDao();
        initView();
        initListenecr();
        selectAll();
    }

    private void initView() {
        mEditText = (EditText) this.findViewById(R.id.edit);
        mAdd = (Button) this.findViewById(R.id.add);
        mListView = (ListView) this.findViewById(R.id.list_db);
        mUpdate = (Button) this.findViewById(R.id.update);

        mAdapter = new ListAdapter(this, datas);
        mListView.setAdapter(mAdapter);
    }

    /**
     * 监听器初始化
     */
    private void initListenecr() {
        mAdd.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String text = mEditText.getText().toString().trim();
                Log.i("tag", text);
                insert(text);
            }
        });
        mUpdate.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                update();
            }
        });

        mAdapter.setOnItemOnclickListener(new ListAdapter.OnItemOnclickListener() {
            @Override
            public void onClike(String text) {
                deleteAndUpdate(text);
            }
        });
    }


    /**
     * 插入数据
     *
     * @param text 插入数据
     */

    private void insert(String text) {
        try {
            Student s = new Student(id, text, 18);
            Long tagId = id;
            id++;
            mDao.insert(s);
            Log.i("tag", "插入成功");
            mEditText.setText("");
            selectById(tagId);
        } catch (Exception e) {
            e.printStackTrace();
            Log.i("tag", "插入失败");
        }
    }

    /**
     * 根据id查询数据
     *
     * @param id
     */
    private void selectById(Long id) {
        Student s = mDao.load(id);
        if (s != null) {
            datas.add(s.getName());
        }
        mAdapter.notifyDataSetChanged();
    }

    /**
     * 查询该表的所有数据
     */
    private void selectAll() {
        List<Student> mList = mDao.loadAll();
        datas.clear();
        for (Student student : mList) {
            datas.add(student.getName());
        }
        mAdapter.notifyDataSetChanged();
    }

    private void deleteAndUpdate(final String text) {
        List<Student> list = mDao.loadAll();
        for (Student student : list) {
            if (student.getName().equals(text.trim())) {
                updateInfo = student;
                break;
            }
        }

        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        //builder.setIcon(R.drawable.ic_launcher);
        builder.setTitle("选择");
        //    指定下拉列表的显示数据
        final String[] cities = {"删除", "修改"};
        //    设置一个下拉的列表选择项
        builder.setItems(cities, new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                if (which == 0) {
                    delete(updateInfo);
                    updateInfo = null;
                    selectAll();
                } else {
                    mEditText.setText(updateInfo.getName());
                }
            }
        });
        builder.show();

    }

    /**
     * 修改数据表的记录
     */
    private void update() {
        String text = mEditText.getText().toString().trim();
        if (updateInfo != null) {
            try {
                updateInfo.setName(text);
                mDao.update(updateInfo);
                Log.i("tag", "修改成功");
                updateInfo = null;
                mEditText.setText("");
                selectAll();
            } catch (Exception e) {
                e.printStackTrace();
                Log.i("tag", "修改失败");
            }

        }
        Log.i("tag", "没有找到合适的记录修改");

    }

    /**
     * 删除
     *
     * @param s
     */
    private void delete(Student s) {
        try {
            mDao.delete(s);
            Log.i("tag", "删除成功");
        } catch (Exception e) {
            e.printStackTrace();
            Log.i("tag", "删除失败");
        }
    }

}

对于增删改查的操作基本在文件已经注释好了,除了以上的方法来操作数据库,GreenDao还支持使用sql语句来操作数据库,这也是其强大的功能之一。支持对象实体间一对多,多对一的关系。虽然本文没有实践一对多的关系,但是读者可以自己去实践,相信也不会有太大的难度。

关于更加详细的介绍,推荐读者可以读下这系列文章《ORM 框架之 GreenDao(一)基本使用》


欢迎大家关注我的公众号,我会继续努力,分享技术、生活和感悟。

qrcode_for_gh_1b331845e7cc_430.jpg
qrcode_for_gh_1b331845e7cc_430.jpg
android开发