微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何使用Room库根据外键在recyclerview中显示数据

如何解决如何使用Room库根据外键在recyclerview中显示数据

使用 sqlite 后,我遇到了 Room 库,它极大地促进了我的应用程序的工作,但是我在对 Recyclerview 中显示的数据进行排序时遇到了问题,我想知道如何才能使我的数据列表仅使用特定的 forgein 键可见车。

这是我正在处理的两个表:

CREATE TABLE `cars` (`car_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,`car_brand` TEXT,`car_model` TEXT,`engine_capacity` REAL NOT NULL,`horse_power` INTEGER NOT NULL,`inspection_date` TEXT,`insurance_date` TEXT,`year_made` INTEGER NOT NULL)

CREATE TABLE `fuels` (`fuel_id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,`fuel_type` TEXT,`fuel_amount` REAL NOT NULL,`fuel_cost` REAL NOT NULL,`mileage` INTEGER NOT NULL,`fuel_date` TEXT,`fueled_car_id` INTEGER NOT NULL,FOREIGN KEY(`fueled_car_id`) REFERENCES `cars`(`car_id`) ON UPDATE NO ACTION ON DELETE CASCADE )

目前它看起来像这样,在我输入列表时,我可以看到每个项目,而不是具有正确 forgein 密钥的项目:

图片 1 - list of cars
图片 2 - list of refueling

汽车 1 - 加油 1,2,3,4
汽车 2 - 加油 1,4
汽车 3 - 加油 1,4

我想完成这样的事情:

汽车 1 - 加油 1,3
汽车 2 - 加油 2
汽车 3 - 加油 4

Fuel.java

@Entity(tableName = "fuels",foreignKeys = @ForeignKey(entity = Car.class,parentColumns = "car_id",childColumns = "fueled_car_id",onDelete = CASCADE))
public class Fuel {

    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "fuel_id")
    private int fuelId;
    @ColumnInfo(name = "fuel_type")
    private String fuelType;
    @ColumnInfo(name = "fuel_amount")
    private float fuelAmount;
    @ColumnInfo(name = "fuel_cost")
    private float fuelCost;
    private int mileage;
    @ColumnInfo(name = "fuel_date")
    private String fuelDate;
    @ColumnInfo(name = "fueled_car_id",index = true)
    private int fueledCarId;

                 
    //constructor & getters/setters

Car.java

@Entity(tableName = "cars")
public class Car {

    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "car_id")
    private int carId;
    @ColumnInfo(name = "car_brand")
    private String carBrand;
    @ColumnInfo(name = "car_model")
    private String carModel;
    @ColumnInfo(name = "engine_capacity")
    private float engineCapacity;
    @ColumnInfo(name = "horse_power")
    private int horsePower;
    @ColumnInfo(name = "inspection_date")
    private String inspectionDate;
    @ColumnInfo(name = "insurance_date")
    private String insuranceDate;
    @ColumnInfo(name = "year_made")
    private int yearMade;

                     
    //constructor & getters/setters

FuelDAO.java

@Dao
public interface FuelDAO {

    @Transaction
    @Query("SELECT * FROM fuels")
    LiveData<List<Fuel>> getAllFuels();

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    void insertFuel(Fuel fuel);
    @Update
    void updateFuel(Fuel fuel);
    @Delete
    void deleteFuel(Fuel fuel);

}

FuelRepository.java

public class FuelRepository {

    private final FuelDAO fuelDAO;
    private final LiveData<List<Fuel>> allFuels;

    public FuelRepository(Application application) {
        CarList db = CarList.getDatabase(application);
        fuelDAO = db.fuelDAO();
        allFuels = fuelDAO.getAllFuels();
    }

    public LiveData<List<Fuel>> getAllFuels() {
        return allFuels;
    }

    //insert,update and delete methods

viewmodel.java

public class viewmodel extends Androidviewmodel {
    private final CarRepository repositoryCar;
    private final FuelRepository repositoryFuel;
    private final LiveData<List<Car>> allCars;
    private final LiveData<List<Fuel>> allFuels;

    public viewmodel(@NonNull Application application) {
        super(application);
        repositoryCar = new CarRepository(application);
        repositoryFuel = new FuelRepository(application);
        allCars = repositoryCar.getAllCars();
        allFuels = repositoryFuel.getAllFuels();
    }

    //Car repository
    public LiveData<List<Car>> getAllCars() {
        return allCars;
    }

    //Fuel repository

    public LiveData<List<Fuel>> getAllFuels() {
        return allFuels;
    }

FuelActivity.java

public class FuelActivity extends AppCompatActivity {

    public static final int ADD_FUEL_REQUEST = 1;
    private viewmodel viewmodel;
    private RecyclerView fuelRecycler;
    private RecyclerFuelAdapter RecyclerFuelAdapter;
    private linearlayoutmanager parentLayout;
    private Button goToAddFuelBtn;

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

        fuelRecycler = findViewById(R.id.fuelRecycler);
        goToAddFuelBtn = findViewById(R.id.goToAddServiceBtn);

        goToAddFuelBtn.setonClickListener(v -> {
            Intent intent = new Intent(this,AddFuelActivity.class);
            startActivityForResult(intent,ADD_FUEL_REQUEST);
        });
        
        viewmodel = new viewmodelProvider(this,viewmodelProvider.AndroidviewmodelFactory
        .getInstance(this.getApplication()))
        .get(viewmodel.class);
        viewmodel.getAllFuels().observe(this,fuels -> RecyclerFuelAdapter.setFuels(fuels));

        createAdapter();
    }

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

        Intent intentFuel = getIntent();
        int value = intentFuel.getIntExtra(String.valueOf(ProfileActivity.EXTRA_ID),1);

        if (requestCode == ADD_FUEL_REQUEST && resultCode == RESULT_OK) {
            String fuelType = dataFuel.getStringExtra(AddFuelActivity.EXTRA_FUEL_TYPE);
            float fuelAmount = dataFuel.getFloatExtra(AddFuelActivity.EXTRA_FUEL_AMOUNT,1);
            float fuelCost = dataFuel.getFloatExtra(AddFuelActivity.EXTRA_FUEL_COST,1);
            int mileage = dataFuel.getIntExtra(AddFuelActivity.EXTRA_MILEAGE,1);
            String fuelDate = dataFuel.getStringExtra(AddFuelActivity.EXTRA_FUEL_DATE);

            Fuel fuel = new Fuel(fuelType,fuelAmount,fuelCost,mileage,fuelDate,value);

            viewmodel viewmodel = new viewmodel(getApplication());
            viewmodel.insertFuel(fuel);
            Toast.makeText(this,"Refuel added!",Toast.LENGTH_SHORT).show();
        } else {
            Toast.makeText(this,"Refuel not added!",Toast.LENGTH_SHORT).show();
        }
    }

    private void createAdapter() {
        RecyclerFuelAdapter = new RecyclerFuelAdapter();
        fuelRecycler.setAdapter(RecyclerFuelAdapter);
        parentLayout = new linearlayoutmanager(this);
        fuelRecycler.setLayoutManager(parentLayout);
    }

RecyclerFuelAdapter.java

public class RecyclerFuelAdapter extends RecyclerView.Adapter<RecyclerFuelAdapter.MyViewHolder> {

    private List<Fuel> fuels = new ArrayList<>();

    @NonNull
    @Override
    public RecyclerFuelAdapter.MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent,int viewType) {
        View itemView = LayoutInflater.from(parent.getContext())
                .inflate(R.layout.list_fuel,parent,false);
        return new MyViewHolder(itemView);
    }

    @Override
    public void onBindViewHolder(@NonNull RecyclerFuelAdapter.MyViewHolder holder,int position) {

        Fuel currentFuel = fuels.get(position);
        String fuelAmount = currentFuel.getFuelAmount() + " L";
        String fuelCost = currentFuel.getFuelCost() + " PLN";

        holder.fuelTypeTv.setText(String.valueOf(currentFuel.getFuelType()));
        holder.fuelAmountTv.setText(fuelAmount);
        holder.fuelCostTv.setText(fuelCost);
        holder.mileageTv.setText(String.valueOf(currentFuel.getMileage()));
        holder.fuelDateTv.setText(String.valueOf(currentFuel.getFuelDate()));
    }

    @Override
    public int getItemCount() {
        return fuels.size();
    }

    public void setFuels(List<Fuel> fuels) {
        this.fuels = fuels;
        notifyDataSetChanged();
    }

    public class MyViewHolder extends RecyclerView.ViewHolder {

        private TextView fuelTypeTv,fuelAmountTv,fuelCostTv,mileageTv,fuelDateTv;

        public MyViewHolder(@NonNull View view) {
            super(view);

            fuelTypeTv = view.findViewById(R.id.fuelTypeTv);
            fuelAmountTv = view.findViewById(R.id.fuelAmountTv);
            fuelCostTv = view.findViewById(R.id.fuelCostTv);
            mileageTv = view.findViewById(R.id.mileageTv);
            fuelDateTv = view.findViewById(R.id.serviceDateTv);
        }
    }
}

sqlite 的数据库浏览器中,我可以看到数据已正确添加,并且“fueled_car_id”与我输入的“car_id”相同,但问题在于对其进行排序。

我尝试在 DAO 类中进行查询并创建 POJO 类,但我无法完全理解它的语法,因此最终无法正常工作并出现以下错误

无法弄清楚如何从游标读取此字段

不确定如何将 Cursor 转换为该方法的返回类型

预先感谢您的帮助

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?