简介
上篇已经提到 GreenDao 带来的很多便利,
这篇将介绍 GreenDao 的 To-One。
MyDaoGenerator.java
public class MyDaoGenerator {
public static void main(String[] args) throws Exception {
Schema schema = new Schema(1, "com.example.GreenDao3");
Entity pictureEntity = addPictureEntity(schema);
addPersonEntity(schema, pictureEntity);
new DaoGenerator().generateAll(schema, "D:\\");
}
private static Entity addPictureEntity(Schema schema) {
Entity pictureEntity = schema.addEntity("Picture");
pictureEntity.addIdProperty();
pictureEntity.addStringProperty("name").notNull();
return pictureEntity;
}
private static Entity addPersonEntity(Schema schema, Entity pictureEntity) {
Entity personEntity = schema.addEntity("Person");
personEntity.addIdProperty();
personEntity.addStringProperty("name").notNull();
Property pictureIProperty = personEntity.addLongProperty("pictureId").getProperty();
personEntity.addToOne(pictureEntity, pictureIProperty);
return personEntity;
}
}
关键代码是 27 和 28 行,将属性 pictureIdProperty 与实体 pictrueEntity 绑定起来。
至于为什么是 addLongPerperty,这是因为 addIdProperty 内部实现使用的是长整型。
my_activity.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout android:layout_width="match_parent"
android:layout_height="50dp"
android:orientation="horizontal">
<EditText android:id="@+id/etPersonName"
android:layout_weight="1" android:layout_width="0dp"
android:layout_height="match_parent"
android:hint="人名"/>
<EditText android:id="@+id/etPictureName"
android:layout_weight="1" android:layout_width="0dp"
android:layout_height="match_parent"
android:hint="画名"/>
<Button android:id="@+id/btnAdd"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:text="添加"/>
</LinearLayout>
<ListView android:id="@+id/lvNote"
android:layout_width="match_parent"
android:layout_height="0dp" android:layout_weight="1"/>
</LinearLayout>
MyActivity.java
public class MyActivity extends Activity implements View.OnClickListener, AdapterView.OnItemClickListener {
private PersonDao personDao;
private PictureDao pictureDao;
private ListViewAdapter listViewAdapter;
private EditText etPersonName;
private EditText etPictureName;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.my_activity);
initDao();
initView();
refreshListView();
}
@Override
public void onClick(View v) {
onBtnAddClick();
}
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
onListViewItemClick(position);
}
private void initDao() {
DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(this, "person-db", null);
SQLiteDatabase db = helper.getWritableDatabase();
DaoMaster daoMaster = new DaoMaster(db);
DaoSession daoSession = daoMaster.newSession();
personDao = daoSession.getPersonDao();
pictureDao = daoSession.getPictureDao();
personDao.deleteAll();
pictureDao.deleteAll();
}
private void initView() {
etPersonName = (EditText) findViewById(R.id.etPersonName);
etPictureName = (EditText) findViewById(R.id.etPictureName);
findViewById(R.id.btnAdd).setOnClickListener(this);
ListView listView = (ListView) findViewById(R.id.lvNote);
listViewAdapter = new ListViewAdapter(this);
listView.setAdapter(listViewAdapter);
listView.setOnItemClickListener(this);
}
private void refreshListView() {
List<Person> dataFromDb = personDao.loadAll();
List<Person> listViewData = listViewAdapter.getData();
listViewData.clear();
listViewData.addAll(dataFromDb);
listViewAdapter.notifyDataSetChanged();
}
private void onBtnAddClick() {
String personName = etPersonName.getText().toString();
String pictureName = etPictureName.getText().toString();
if (personName.equals("") || pictureName.equals("")) {
return;
}
Picture picture = new Picture(null, pictureName);
pictureDao.insert(picture);<span style="white-space:pre"> </span>// insert行为会为实例 picture 取得 id
Person person = new Person();
person.setName(personName);
person.setPicture(picture);
personDao.insert(person);
refreshListView();
}
private void onListViewItemClick(int position) {
Person person = listViewAdapter.getData().get(position);
personDao.delete(person);
pictureDao.delete(person.getPicture());
Log.e("result", personDao.loadAll().size() + "");
Log.e("result", pictureDao.loadAll().size() + "");
refreshListView();
}
}
好像 GreenDao 是不支持联级保存和删除的。
对 Person 和 Picture 的修改都是独立的,只是通过一个 ID 维系着他们的纽带。
而且只有调用 update() 才能将改动写入数据库。
懒加载
默认情况,GreenDao 使用的是懒加载,就是说 loadAll 返回实体列表时不会牵连到其他表的查询。
public Picture getPicture() {
Long __key = this.pictureId;
if (picture__resolvedKey == null || !picture__resolvedKey.equals(__key)) {
if (daoSession == null) {
throw new DaoException("Entity is detached from DAO context");
}
PictureDao targetDao = daoSession.getPictureDao();
Picture pictureNew = targetDao.load(__key);
synchronized (this) {
picture = pictureNew;
picture__resolvedKey = __key;
}
}
return picture;
}
只有当调用 getPicture 时才会去联动查询,GreenDao 的联级好像只有在这里体现。
除此之外,无论是保存、更新、还是删除,只能自己来实现联级。
顺便一提,之前的两个问题
1. close 语句去哪了?
2. Dao 层操作是另外开启线程的么?