java - 房间 : LiveData One To Many Relation

标签 java android

我有一个包含两个表的数据库。

第一个:queue_incoming

+---------------+
|  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_incoming有很多包。 queue_incoming.id = bag.queue_incoming_id

问题是,我需要将每个queue_incoming记录中的bag的所有记录放到一个List中。

到目前为止,这是代码。 非常感谢任何帮助。

实体: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:QueueIncomingDao.java

@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 QueueIncomingRepository {

    private QueueIncomingDao queueIncomingDao;
    private BagDao bagDao;
    private Context context;
    private ArrayList<BagLotNumberModel> bagLotNumbers;
    private LiveData<List<QueueIncomingEntity>> listLiveData;

    // constructor
    public QueueIncomingRepository(Application application) {

        AppDatabase database = AppDatabase.getInstance(application);

        queueIncomingDao = database.queueIncomingDao();
        listLiveData = queueIncomingDao.getAll();
    }

     // a lot of crud code

     // Handling LiveData
    public LiveData<List<QueueIncomingEntity>> getAll() {
        return listLiveData;
    }
}

View 模型:QueueIncomingViewModel.java

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;
    }
}

Activity :AntamQueueIncomingRoomActivity.java

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

我已经声明过了

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<List<QueueIncoming>> 等查询中更新输出列表

更新:您可以在您的 viewModel 中尝试这个 //先声明

private final MediatorLiveData<List<QueueIncoming>> mObservableProducts;

在dao调用后的构造函数中

mObservableProducts.addSource(products, new Observer<List<UserEntity>>() {
            @Override
            public void onChanged(@Nullable List<QueueIncoming> outputDaoList) {
                mObservableProducts.postValue(outputDaoList);
            }
        });

然后在您的 View 模型中编写一个您可以从 Activity 中观察到的方法

public LiveData<List<QueueIncoming>> getAllList() {
        return mObservableProducts;
    }

关于java - 房间 : LiveData One To Many Relation,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56539762/

相关文章:

Android - 尽管文件存在于数据文件夹中,但找不到该文件?

java - 如何从 Rss 获取图片

java - 无法从 Activity 启动 map View

android - 如何在转到 Activity 'B' 时暂停 Activity 'C'

java - GWT 使用 DOM.clone 克隆一个小部件

Java 枚举(或 int 常量)与 C 枚举

java - 异常覆盖规则

java - 2 个 Java GeneralPath 之间的带状线

java - 没有访问器来设置属性 private Final java.util.Map org.springframework.boot.configurationprocessor.json.JSONObject.nameValuePairs

Android TextView 文本颜色仅在物理设备上错误