Android開源資料庫 GreenDao實踐

鋸齒流沙發表於2017-12-26

GreenDao是一款物件關係對映(ORM)的開源資料庫框架, 通過將Java物件對映到資料庫表,能夠減輕開發人員處理低階資料庫需求,同時節省開發時間。

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

greendao.png

這是官網給出的GreenDao圖解,通過圖我們很清楚的知道GreenDaojava物件SQLite資料的關係,而GreenDao的出現相當於為SQLite資料庫和java物件搭建了一座橋樑。

言歸正傳,如此優秀的開源框架,我們來實踐一下,下面的圖是實踐的效果圖。

GreenDao.png

這裡實現了資料庫的增刪改查操作。

專案新增GreenDao

1)、project--->build.gradle

GreenDao.png

2)、app—>build.gradle

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

初始化

初始化包括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(一)基本使用》

相關文章