GreenDao 学习笔记 4


简介


这篇将介绍 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;
    }

}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值