GreenDao 学习笔记 4

来源:互联网 发布:苏亚星多媒体教学软件 编辑:程序博客网 时间:2024/05/18 03:40


简介


这篇将介绍 ToMany。


如何实现关联


一对多的时候,只能将主表的 ID 保存在从表中。

一对一呢?
如果为了保持一致性,也将主表的 ID 保存在从表中,则查询语句是 select * from 从表 where  外键 = ? 。
如果采取相反的方式,则查询语句为 select * from 从表 where ID = ?。
效率上没什么区别,而 GreenDao 选择的是第二种。

如果不细究这些,GreenDao 还是有某种一致性,都有由主表发起建立联系,无论是 addToMany,还是 addToOne。



ListViewAdapter.java


package com.example.GreenDaoDemo4;import android.app.Activity;import android.view.LayoutInflater;import android.view.View;import android.view.ViewGroup;import android.widget.BaseAdapter;import android.widget.TextView;import java.util.ArrayList;import java.util.List;public class ListViewAdapter extends BaseAdapter {    private List<Customer> data = new ArrayList<Customer>();    private LayoutInflater layoutInflater;    public ListViewAdapter(Activity activity) {        layoutInflater = activity.getLayoutInflater();    }    @Override    public int getCount() {        return data.size();    }    @Override    public View getView(int position, View convertView, ViewGroup parent) {        Customer customer = data.get(position);        String text = customer.getName();        List<Orders> ordersList = customer.getOrdersList();        for (Orders orders : ordersList) {            text += orders.getName();        }        TextView textView = (TextView) layoutInflater.inflate(R.layout.listview_item, parent, false);        textView.setText(text);        return textView;    }    public List<Customer> getData() {        return data;    }    @Override    public Object getItem(int position) {        return null;    }    @Override    public long getItemId(int position) {        return 0;    }}


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/etCustomerName"                  android:layout_weight="1" android:layout_width="0dp"                  android:layout_height="match_parent"                  android:hint="customer"/>        <EditText android:id="@+id/etOrderName1"                  android:layout_weight="1" android:layout_width="0dp"                  android:layout_height="match_parent"                  android:hint="order1"/>        <EditText android:id="@+id/etOrderName2"                  android:layout_weight="1" android:layout_width="0dp"                  android:layout_height="match_parent"                  android:hint="order2"/>        <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 {    private CustomerDao customerDao;    private OrdersDao ordersDao;    private ListViewAdapter listViewAdapter;    private EditText etCustomerName;    private EditText etOrderName1;    private EditText etOrderName2;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.my_activity);        initDao();        initView();        refreshListView();    }    @Override    public void onClick(View v) {        onBtnAddClick();    }    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();        customerDao = daoSession.getCustomerDao();        ordersDao = daoSession.getOrdersDao();    }    private void initView() {        etCustomerName = (EditText) findViewById(R.id.etCustomerName);        etOrderName1 = (EditText) findViewById(R.id.etOrderName1);        etOrderName2 = (EditText) findViewById(R.id.etOrderName2);        findViewById(R.id.btnAdd).setOnClickListener(this);        ListView listView = (ListView) findViewById(R.id.lvNote);        listViewAdapter = new ListViewAdapter(this);        listView.setAdapter(listViewAdapter);    }    private void refreshListView() {        List<Customer> dataFromDb = customerDao.loadAll();        List<Customer> listViewData = listViewAdapter.getData();        listViewData.clear();        listViewData.addAll(dataFromDb);        listViewAdapter.notifyDataSetChanged();    }    private void onBtnAddClick() {        String customerName = etCustomerName.getText().toString();        String orderName1 = etOrderName1.getText().toString();        String orderName2 = etOrderName2.getText().toString();        Customer customer = new Customer(null, customerName);        customerDao.insert(customer);        Long customerId = customer.getId();        Orders orders1 = new Orders(null, orderName1, customerId);        ordersDao.insert(orders1);        Orders orders2 = new Orders(null, orderName2, customerId);        ordersDao.insert(orders2);        refreshListView();    }}


缓存


public List<Orders> getOrdersList() {        if (ordersList == null) {            if (daoSession == null) {                throw new DaoException("Entity is detached from DAO context");            }            OrdersDao targetDao = daoSession.getOrdersDao();            List<Orders> ordersListNew = targetDao._queryCustomer_OrdersList(id);            synchronized (this) {                if(ordersList == null) {                    ordersList = ordersListNew;                }            }        }        return ordersList;    }

上篇文章提到 GreenDao 默认使用的是懒加载,只有当调用 get 方法时,才会联动查询所关联的表。
当获得查询结果后,会将结果缓存起来,第二次调用 get 方法会返回之前的查询结果。
(这里做法是奇葩啊,每次确实都去查了一次,想干嘛? 第7行)

有时我们希望保持数据的一致性,有 2 种方法。
1. 手动同步,insert 之后对 list add,delete 后对 list remove。
2. 调用 reset 方法,将 list 重新赋值为 null,这样 get 方法就会获得数据库当前的数据了。


惯例,回顾一下那两个问题:
1. close 语句去哪了?
2. 数据库操作是另外开启线程的么?


附 MyDaoGenerator.java


public class MyDaoGenerator {    public static void main(String[] args) throws Exception {        Schema schema = new Schema(1, "com.example.GreenDao4");        Entity customerEntity = addCustomerEntity(schema);        addOrderEntity(schema, customerEntity);        new DaoGenerator().generateAll(schema, "D:\\");    }    private static Entity addCustomerEntity(Schema schema) {        Entity customerEntity = schema.addEntity("Customer");        customerEntity.addIdProperty();        customerEntity.addStringProperty("name").notNull();        return customerEntity;    }    private static Entity addOrderEntity(Schema schema, Entity customerEntity) {        Entity orderEntity = schema.addEntity("Orders");  // order 是关键字        orderEntity.addIdProperty();        orderEntity.addStringProperty("name").notNull();        Property customerIdProperty = orderEntity.addLongProperty("customerId").notNull().getProperty();        customerEntity.addToMany(orderEntity, customerIdProperty);        return orderEntity;    }}



0 0