Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/201.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 房间:LiveData一对多关系_Java_Android - Fatal编程技术网

Java 房间:LiveData一对多关系

Java 房间:LiveData一对多关系,java,android,Java,Android,我有一个数据库,里面有两个表 1st:queue\u传入 +---------------+ | column_name | pk +---------------+ |id | 1 |api_id | 0 |driver | 0 |vehicle_number | 0 +---------------+ +------------------+ | column_name | pk +-------------

我有一个数据库,里面有两个表

1st:queue\u传入

+---------------+
|  column_name  | pk   
+---------------+
|id             | 1
|api_id         | 0
|driver         | 0
|vehicle_number | 0
+---------------+
+------------------+
|  column_name     | pk   
+------------------+
|id                | 1
|api_id            | 0
|queue_incoming_id | 0
|driver            | 0
|vehicle_number    | 0
+------------------+
第二桌:包

+---------------+
|  column_name  | pk   
+---------------+
|id             | 1
|api_id         | 0
|driver         | 0
|vehicle_number | 0
+---------------+
+------------------+
|  column_name     | pk   
+------------------+
|id                | 1
|api_id            | 0
|queue_incoming_id | 0
|driver            | 0
|vehicle_number    | 0
+------------------+
两个表之间的关系是一个队列有许多行李。 queue\u incoming.id=bag.queue\u incoming\u id

问题是,我需要将每个队列中的所有行李记录和传入记录合并到一个列表中

到目前为止,这是代码。 我非常感谢你的帮助

Entity:QueueIncomingEntity.java

@Entity(tableName = "queue_incoming")
public class QueueIncomingEntity {

    @PrimaryKey(autoGenerate = true)
    private Long id;

    @ColumnInfo(name = "api_id")
    private Integer ApiId;

    @ColumnInfo(name = "driver")
    private String driver;

    @ColumnInfo(name = "vehicle_number")
    private String vehicleNumber;

    @ColumnInfo(name = "date_unique_number")
    private String dateUniqueNumber;

    @ColumnInfo(name = "unique_number")
    private String uniqueNumber;

    @ColumnInfo(name = "message")
    private String message;

    @ColumnInfo(name = "status")
    private String status;

    @Ignore
    private List<BagEntity> bagEntities; // handle all bags in each queue

    // Constructor
    public QueueIncomingEntity(String driver, String vehicleNumber, String dateUniqueNumber, String uniqueNumber, String message, String status) {
        this.driver = driver;
        this.vehicleNumber = vehicleNumber;
        this.dateUniqueNumber = dateUniqueNumber;
        this.uniqueNumber = uniqueNumber;
        this.message = message;
        this.status = status;
    }

    // Getter Setter

}
@Dao
public interface QueueIncomingDao {

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    long insert(QueueIncomingEntity queueIncomingEntity);

    @Update
    void update(QueueIncomingEntity queueIncomingEntity);

    @Delete
    void delete(QueueIncomingEntity queueIncomingEntity);

    @Query("DELETE FROM queue_incoming")
    void deleteAll();

    @Query("SELECT * FROM queue_incoming WHERE id =:id")
    QueueIncomingEntity findById(long id);

    @Query("SELECT * FROM queue_incoming ORDER BY id DESC")
    LiveData<List<QueueIncomingEntity>> getAll();

    // This is the problem, how to pass this , or how to related this on LiveData
    @Query("SELECT " +
            "bag.id as id," +
            "bag.api_id as apiId," +
            "bag.bag_number as bagNumber," +
            "bag.lot_number as lotNumber," +
            "bag.consignee_name as consigneeName," +
            "bag.allocation_consignee as allocationConsignee," +
            "bag.nett_weight as nettWeight," +
            "bag.gross_weight as grossWeight " +
            "FROM queue_incoming " +
            "LEFT JOIN bag bag ON bag.queue_incoming_id = queue_incoming.id WHERE queue_incoming.id = :id")
    List<QueueIncoming> getAllJoinBags(long id);

    // Inner class to handle method getAllJoinBags
    class QueueIncoming {
        public Long id;
        public Integer apiId;
        public Integer bagNumber;
        public String lotNumber;
        public String consigneeName;
        public String allocationConsignee;
        public Integer nettWeight;
        public Integer grossWeight;

        // Getter Setter
    }

}
public class QueueIncomingViewModel extends AndroidViewModel {

    private QueueIncomingRepository queueIncomingRepository;
    private LiveData<List<QueueIncomingEntity>> listLiveData;

    /**
     * Create constructor matching super
     */
    public QueueIncomingViewModel(@NonNull Application application) {
        super(application);
        queueIncomingRepository = new QueueIncomingRepository(application);
        listLiveData = queueIncomingRepository.getAll();
    }

    public void insert(QueueIncomingEntity queueIncomingEntity) {
        queueIncomingRepository.insert(queueIncomingEntity);
    }

    public void update(QueueIncomingEntity queueIncomingEntity) {
        queueIncomingRepository.update(queueIncomingEntity);
    }

    public void delete(QueueIncomingEntity queueIncomingEntity) {
        queueIncomingRepository.delete(queueIncomingEntity);
    }

    public void deleteAll() {
        queueIncomingRepository.deleteAll();
    }

    public LiveData<List<QueueIncomingEntity>> getListLiveData() {
        return listLiveData;
    }
}
public class AntamQueueIncomingRoomActivity extends AppCompatActivity {

    public static final int ADD_QUEUE_INCOMING = 1;
    public static final int EDIT_QUEUE_INCOMING = 2;
    public static final int EDIT_QUEUE_INCOMING_BAGS = 3;
    public static final int RE_UPLOAD = 4;

    private QueueIncomingViewModel queueIncomingViewModel;

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

        RecyclerView recyclerView = findViewById(R.id.recycler_view_antam_queue_incoming);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        recyclerView.setHasFixedSize(true);

        QueueIncomingAdapter adapter = new QueueIncomingAdapter();
        recyclerView.setAdapter(adapter);

        queueIncomingViewModel = ViewModelProviders.of(this).get(QueueIncomingViewModel.class);
        queueIncomingViewModel.getListLiveData().observe(this, queueIncomingEntities -> {

            adapter.submitList(queueIncomingEntities);

        });

        FloatingActionButton fab = findViewById(R.id.fab);
        fab.setOnClickListener(view -> {
            Intent intent = new Intent(getApplicationContext(), AntamAddEditQueueIncomingRoomActivity.class);
            startActivityForResult(intent, ADD_QUEUE_INCOMING);
        });

        //handling item click on row adapter
        adapter.setOnItemClickListener(new QueueIncomingAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(QueueIncomingEntity queueIncomingEntity) {

                String[] options = {"1. Update Master Incoming", "2. Update Detail Bags", "3. Re-Upload"};
                AlertDialog.Builder builder = new AlertDialog.Builder(AntamQueueIncomingRoomActivity.this);
                builder.setTitle("Menu: " + queueIncomingEntity.getDriver() + " # " + queueIncomingEntity.getVehicleNumber());
                builder.setItems(options, (dialog, which) -> {
                    switch (which) {
                        case 2:
                            Intent intent2 = new Intent(AntamQueueIncomingRoomActivity.this, AntamDialogReUploadIncomingActivity.class);

                            // Data Master
                            intent2.putExtra(AntamDialogReUploadIncomingActivity.EXTRA_ID, Long.valueOf(queueIncomingEntity.getId()));
                            intent2.putExtra(AntamDialogReUploadIncomingActivity.EXTRA_API_ID, queueIncomingEntity.getApiId());

                            // Get Data Detail bags, how ?
                            // Get and passing All bags into new ActivityForResult

                            startActivityForResult(intent2, RE_UPLOAD);
                            break;
                        default:
                            break;
                    }
                });
                builder.show();
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == ADD_QUEUE_INCOMING && resultCode == RESULT_OK) {

            // insert


        } else if (requestCode == EDIT_QUEUE_INCOMING && resultCode == RESULT_OK) {

            Long id = Long.valueOf(data.getLongExtra(AntamAddEditQueueIncomingRoomActivity.EXTRA_ID, -1));

            // Update
            queueIncomingEntity.setId(id);
            queueIncomingViewModel.update(queueIncomingEntity);

            Toast.makeText(this, data.getStringExtra(AntamAddEditQueueIncomingRoomActivity.EXTRA_DRIVER) + " is successfully updated", Toast.LENGTH_SHORT).show();
        } else if (requestCode == RE_UPLOAD) {

        }
    }
}
BagEntity.java

@Entity(tableName = "queue_incoming")
public class QueueIncomingEntity {

    @PrimaryKey(autoGenerate = true)
    private Long id;

    @ColumnInfo(name = "api_id")
    private Integer ApiId;

    @ColumnInfo(name = "driver")
    private String driver;

    @ColumnInfo(name = "vehicle_number")
    private String vehicleNumber;

    @ColumnInfo(name = "date_unique_number")
    private String dateUniqueNumber;

    @ColumnInfo(name = "unique_number")
    private String uniqueNumber;

    @ColumnInfo(name = "message")
    private String message;

    @ColumnInfo(name = "status")
    private String status;

    @Ignore
    private List<BagEntity> bagEntities; // handle all bags in each queue

    // Constructor
    public QueueIncomingEntity(String driver, String vehicleNumber, String dateUniqueNumber, String uniqueNumber, String message, String status) {
        this.driver = driver;
        this.vehicleNumber = vehicleNumber;
        this.dateUniqueNumber = dateUniqueNumber;
        this.uniqueNumber = uniqueNumber;
        this.message = message;
        this.status = status;
    }

    // Getter Setter

}
@Dao
public interface QueueIncomingDao {

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    long insert(QueueIncomingEntity queueIncomingEntity);

    @Update
    void update(QueueIncomingEntity queueIncomingEntity);

    @Delete
    void delete(QueueIncomingEntity queueIncomingEntity);

    @Query("DELETE FROM queue_incoming")
    void deleteAll();

    @Query("SELECT * FROM queue_incoming WHERE id =:id")
    QueueIncomingEntity findById(long id);

    @Query("SELECT * FROM queue_incoming ORDER BY id DESC")
    LiveData<List<QueueIncomingEntity>> getAll();

    // This is the problem, how to pass this , or how to related this on LiveData
    @Query("SELECT " +
            "bag.id as id," +
            "bag.api_id as apiId," +
            "bag.bag_number as bagNumber," +
            "bag.lot_number as lotNumber," +
            "bag.consignee_name as consigneeName," +
            "bag.allocation_consignee as allocationConsignee," +
            "bag.nett_weight as nettWeight," +
            "bag.gross_weight as grossWeight " +
            "FROM queue_incoming " +
            "LEFT JOIN bag bag ON bag.queue_incoming_id = queue_incoming.id WHERE queue_incoming.id = :id")
    List<QueueIncoming> getAllJoinBags(long id);

    // Inner class to handle method getAllJoinBags
    class QueueIncoming {
        public Long id;
        public Integer apiId;
        public Integer bagNumber;
        public String lotNumber;
        public String consigneeName;
        public String allocationConsignee;
        public Integer nettWeight;
        public Integer grossWeight;

        // Getter Setter
    }

}
public class QueueIncomingViewModel extends AndroidViewModel {

    private QueueIncomingRepository queueIncomingRepository;
    private LiveData<List<QueueIncomingEntity>> listLiveData;

    /**
     * Create constructor matching super
     */
    public QueueIncomingViewModel(@NonNull Application application) {
        super(application);
        queueIncomingRepository = new QueueIncomingRepository(application);
        listLiveData = queueIncomingRepository.getAll();
    }

    public void insert(QueueIncomingEntity queueIncomingEntity) {
        queueIncomingRepository.insert(queueIncomingEntity);
    }

    public void update(QueueIncomingEntity queueIncomingEntity) {
        queueIncomingRepository.update(queueIncomingEntity);
    }

    public void delete(QueueIncomingEntity queueIncomingEntity) {
        queueIncomingRepository.delete(queueIncomingEntity);
    }

    public void deleteAll() {
        queueIncomingRepository.deleteAll();
    }

    public LiveData<List<QueueIncomingEntity>> getListLiveData() {
        return listLiveData;
    }
}
public class AntamQueueIncomingRoomActivity extends AppCompatActivity {

    public static final int ADD_QUEUE_INCOMING = 1;
    public static final int EDIT_QUEUE_INCOMING = 2;
    public static final int EDIT_QUEUE_INCOMING_BAGS = 3;
    public static final int RE_UPLOAD = 4;

    private QueueIncomingViewModel queueIncomingViewModel;

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

        RecyclerView recyclerView = findViewById(R.id.recycler_view_antam_queue_incoming);
        recyclerView.setLayoutManager(new LinearLayoutManager(this));
        recyclerView.setHasFixedSize(true);

        QueueIncomingAdapter adapter = new QueueIncomingAdapter();
        recyclerView.setAdapter(adapter);

        queueIncomingViewModel = ViewModelProviders.of(this).get(QueueIncomingViewModel.class);
        queueIncomingViewModel.getListLiveData().observe(this, queueIncomingEntities -> {

            adapter.submitList(queueIncomingEntities);

        });

        FloatingActionButton fab = findViewById(R.id.fab);
        fab.setOnClickListener(view -> {
            Intent intent = new Intent(getApplicationContext(), AntamAddEditQueueIncomingRoomActivity.class);
            startActivityForResult(intent, ADD_QUEUE_INCOMING);
        });

        //handling item click on row adapter
        adapter.setOnItemClickListener(new QueueIncomingAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(QueueIncomingEntity queueIncomingEntity) {

                String[] options = {"1. Update Master Incoming", "2. Update Detail Bags", "3. Re-Upload"};
                AlertDialog.Builder builder = new AlertDialog.Builder(AntamQueueIncomingRoomActivity.this);
                builder.setTitle("Menu: " + queueIncomingEntity.getDriver() + " # " + queueIncomingEntity.getVehicleNumber());
                builder.setItems(options, (dialog, which) -> {
                    switch (which) {
                        case 2:
                            Intent intent2 = new Intent(AntamQueueIncomingRoomActivity.this, AntamDialogReUploadIncomingActivity.class);

                            // Data Master
                            intent2.putExtra(AntamDialogReUploadIncomingActivity.EXTRA_ID, Long.valueOf(queueIncomingEntity.getId()));
                            intent2.putExtra(AntamDialogReUploadIncomingActivity.EXTRA_API_ID, queueIncomingEntity.getApiId());

                            // Get Data Detail bags, how ?
                            // Get and passing All bags into new ActivityForResult

                            startActivityForResult(intent2, RE_UPLOAD);
                            break;
                        default:
                            break;
                    }
                });
                builder.show();
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == ADD_QUEUE_INCOMING && resultCode == RESULT_OK) {

            // insert


        } else if (requestCode == EDIT_QUEUE_INCOMING && resultCode == RESULT_OK) {

            Long id = Long.valueOf(data.getLongExtra(AntamAddEditQueueIncomingRoomActivity.EXTRA_ID, -1));

            // Update
            queueIncomingEntity.setId(id);
            queueIncomingViewModel.update(queueIncomingEntity);

            Toast.makeText(this, data.getStringExtra(AntamAddEditQueueIncomingRoomActivity.EXTRA_DRIVER) + " is successfully updated", Toast.LENGTH_SHORT).show();
        } else if (requestCode == RE_UPLOAD) {

        }
    }
}
我以前已经申报过了

import android.arch.persistence.room.ColumnInfo;
import android.arch.persistence.room.Entity;
import android.arch.persistence.room.ForeignKey;
import android.arch.persistence.room.PrimaryKey;

@Entity(
        tableName = "bag",
        foreignKeys = {
                @ForeignKey(
                        entity = QueueIncomingEntity.class,
                        parentColumns = "id",
                        childColumns = "queue_incoming_id",
                        onDelete = ForeignKey.CASCADE
                ),

                @ForeignKey(
                        entity = QueueContainerStuffingEntity.class,
                        parentColumns = "id",
                        childColumns = "queue_container_stuffing_id"
                )
        }
)
public class BagEntity {

    @PrimaryKey(autoGenerate = true)
    private Long id;

    @ColumnInfo(name = "api_id")
    private Long ApiId;

    @ColumnInfo(name = "queue_incoming_id", index = true)
    private Long queueIncomingId;

    @ColumnInfo(name = "queue_container_stuffing_id", index = true)
    private Long queueContainerStuffingId;

    @ColumnInfo(name = "bag_number")
    private Integer bagNumber;

    @ColumnInfo(name = "lot_number")
    private String lotNumber;

    @ColumnInfo(name = "consignee_name")
    private String consigneeName;

    @ColumnInfo(name = "allocation_consignee")
    private String allocationConsignee;

    @ColumnInfo(name = "nett_weight")
    private Integer nettWeight;

    @ColumnInfo(name = "gross_weight")
    private Integer grossWeight;


    public BagEntity(Long ApiId, Integer bagNumber, String lotNumber, String consigneeName, String allocationConsignee, Integer nettWeight, Integer grossWeight, Long queueIncomingId, Long queueContainerStuffingId) {
        this.ApiId = ApiId;
        this.bagNumber = bagNumber;
        this.lotNumber = lotNumber;
        this.consigneeName = consigneeName;
        this.allocationConsignee = allocationConsignee;
        this.nettWeight = nettWeight;
        this.grossWeight = grossWeight;
        this.queueIncomingId = queueIncomingId;
        this.queueContainerStuffingId = queueContainerStuffingId;
    }

    // Getter Setter


}

我想您错过了BagEntity.java中的@ForeignKey@ForeignKey将连接两个表,因此如果有任何表更新,将触发实时数据

第二件事是输出列表不是活动数据类型。您必须在查询中更新输出列表,如
LiveData

更新:您可以在viewModel中尝试此功能 //先申报

private final MediatorLiveData<List<QueueIncoming>> mObservableProducts;
私有的LiveData mObservableProducts;
在dao调用之后的构造函数中

mObservableProducts.addSource(products, new Observer<List<UserEntity>>() {
            @Override
            public void onChanged(@Nullable List<QueueIncoming> outputDaoList) {
                mObservableProducts.postValue(outputDaoList);
            }
        });
mObservableProducts.addSource(products,newobserver()){
@凌驾
更改后的公共void(@Nullable List outputDaoList){
mObservableProducts.postValue(outputDaoList);
}
});
并在viewmodel中编写一个可以从活动中观察的方法

public LiveData<List<QueueIncoming>> getAllList() {
        return mObservableProducts;
    }
public LiveData getAllList(){
退回可维修产品;
}

实际问题是什么?JoinQuery问题还是singleQuery liveData问题?请看我的活动中我更新了我的答案。也许你能得到帮助好的,让我先查一下