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

使用表 1 数据 SQLite Android Studio 馈送表 2

如何解决使用表 1 数据 SQLite Android Studio 馈送表 2

我正在尝试创建一个烘焙销售费用的应用程序,我可以在其中单独输入烘焙过程中使用的成分的值,然后使用每个配方中的成分值输入每个产品的值,所以我可以看到我可以卖多少才能获得丰厚的利润。 我有一个数据库方法处理我的第一个表(保存、删除、更新、搜索...),但我不能让我的第二个表 (TABLE_RECEITA) 使用我的第一个表 (TABLE_PRODUTO) 中已经存在的数据,补充我的食谱。
我想用我的第一个表格列中的数据为我的第二个表格的列提供数据,只通过根据使用的数量进行除法来更改数量和价值的数据。 我曾尝试使用外键和微调器,但没有成功,但很有可能我做错了什么。

我的数据库

import requestIp from 'request-ip'

export default async function myRoute(
  req: NextApiRequest,res: NextApiResponse
) {
  const detectedIp = requestIp.getClientIp(req)
}

使用第一张桌子上保存的原料保存我的食谱(第二张桌子)的活动:

package com.myapplication.umdocededaisy;

import android.annotation.SuppressLint;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.sqliteDatabase;
import android.database.sqlite.sqliteOpenHelper;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;

public class MyDatabase extends sqliteOpenHelper {

    List<MateriaPrima> listaProduto = new ArrayList<>();
    List<Receita> listaReceita = new ArrayList<>();

    private final Context context;
    private static final String DATABASE_NAME = "BancodoceDaisy.db";
    private static final int DATABASE_VERSION = 9;

    //Estruturas das Tabelas do banco de dados:

    //Tabela dos produtos - materia prima **(FirsT TABLE)**:
    private static final String TABLE_PRODUTO = "materia_prima";
    private static final String COLUMN_CODIGO = "codigo";
    private static final String COLUMN_PRODUTO = "produto";
    private static final String COLUMN_VALOR = "valor";
    private static final String COLUMN_QTD = "quantidade";
    private static final String COLUMN_TIPO = "tipo";
    //------------------------------------------------------
    //Tabela de receitas/massas - **(SECOND TABLE)**:
    private static final String TABLE_RECEITA = "receitas";
    private static final String COLUMN_TITULO = "titulo";
    private static final String COLUMN_ITEM1 = "item1";
    private static final String COLUMN_ITEM2 = "item2";
    private static final String COLUMN_ITEM3 = "item3";
    private static final String COLUMN_ITEM4 = "item4";
    private static final String COLUMN_ITEM5 = "item5";
    private static final String COLUMN_ITEM6 = "item6";
    private static final String COLUMN_ITEM7 = "item7";
    private static final String COLUMN_ITEM8 = "item8";
    private static final String COLUMN_ITEM9 = "item9";
    private static final String COLUMN_ITEM10 = "item10";
    private static final String COLUMN_ITEM11 = "item11";
    private static final String COLUMN_ITEM12 = "item12";
    private static final String COLUMN_ITEM13 = "item13";
    private static final String COLUMN_ITEM14 = "item14";
    private static final String COLUMN_VALOR1 = "valor1";
    private static final String COLUMN_VALOR2 = "valor2";
    private static final String COLUMN_VALOR3 = "valor3";
    private static final String COLUMN_VALOR4 = "valor4";
    private static final String COLUMN_VALOR5 = "valor5";
    private static final String COLUMN_VALOR6 = "valor6";
    private static final String COLUMN_VALOR7 = "valor7";
    private static final String COLUMN_VALOR8 = "valor8";
    private static final String COLUMN_VALOR9 = "valor9";
    private static final String COLUMN_VALOR10 = "valor10";
    private static final String COLUMN_VALOR11 = "valor11";
    private static final String COLUMN_VALOR12 = "valor12";
    private static final String COLUMN_VALOR13 = "valor13";
    private static final String COLUMN_VALOR14 = "valor14";
    private static final String COLUMN_QTD1 = "qtd1";
    private static final String COLUMN_QTD2 = "qtd2";
    private static final String COLUMN_QTD3 = "qtd3";
    private static final String COLUMN_QTD4 = "qtd4";
    private static final String COLUMN_QTD5 = "qtd5";
    private static final String COLUMN_QTD6 = "qtd6";
    private static final String COLUMN_QTD7 = "qtd7";
    private static final String COLUMN_QTD8 = "qtd8";
    private static final String COLUMN_QTD9 = "qtd9";
    private static final String COLUMN_QTD10 = "qtd10";
    private static final String COLUMN_QTD11 = "qtd11";
    private static final String COLUMN_QTD12 = "qtd12";
    private static final String COLUMN_QTD13 = "qtd13";
    private static final String COLUMN_QTD14 = "qtd14";


    MyDatabase(Context context) {
        super(context,DATABASE_NAME,null,DATABASE_VERSION);
        this.context = context;
    }

    @Override
    public void onCreate(sqliteDatabase db) {
        String query = "CREATE TABLE "+ TABLE_PRODUTO +
                " (" + COLUMN_CODIGO + " INTEGER PRIMARY KEY AUTOINCREMENT," +
                COLUMN_PRODUTO + " TEXT," +
                COLUMN_VALOR + " FLOAT," +
                COLUMN_QTD + " FLOAT," +
                COLUMN_TIPO + " TEXT); ";
        db.execsql(query);

        String query2 = "CREATE TABLE "+ TABLE_RECEITA +
                " (" + COLUMN_TITULO + " TEXT PRIMARY KEY," + COLUMN_ITEM1 + "TEXT," + COLUMN_ITEM2 + " TEXT," +
                COLUMN_ITEM3 + " TEXT," + COLUMN_ITEM4 + " TEXT," + COLUMN_ITEM5 + " TEXT," + COLUMN_ITEM6 + " TEXT," +
                COLUMN_ITEM7 + " TEXT," + COLUMN_ITEM8 + " TEXT," + COLUMN_ITEM9 + " TEXT," + COLUMN_ITEM10 + " TEXT," +
                COLUMN_ITEM11 + " TEXT," + COLUMN_ITEM12 + " TEXT," + COLUMN_ITEM13 + " TEXT," + COLUMN_ITEM14 + " TEXT," +
                COLUMN_VALOR1 + "FLOAT," + COLUMN_VALOR2 + "FLOAT," +COLUMN_VALOR3 + "FLOAT," + COLUMN_VALOR4 + "FLOAT," +
                COLUMN_VALOR5 + "FLOAT," + COLUMN_VALOR6 + "FLOAT," + COLUMN_VALOR7 + "FLOAT," + COLUMN_VALOR8 + "FLOAT," +
                COLUMN_VALOR9 + "FLOAT," + COLUMN_VALOR10 + "FLOAT," + COLUMN_VALOR11 + "FLOAT," + COLUMN_VALOR12 + "FLOAT," +
                COLUMN_VALOR13 + "FLOAT," + COLUMN_VALOR14 + "FLOAT," + COLUMN_QTD1 + "FLOAT," +
                COLUMN_QTD1 + "FLOAT," + COLUMN_QTD2 + "FLOAT," + COLUMN_QTD3 + "FLOAT," + COLUMN_QTD4 + "FLOAT," +
                COLUMN_QTD5 + "FLOAT," + COLUMN_QTD6 + "FLOAT," + COLUMN_QTD7 + "FLOAT," + COLUMN_QTD8 + "FLOAT," +
                COLUMN_QTD9 + "FLOAT," + COLUMN_QTD10 + "FLOAT," + COLUMN_QTD11 + "FLOAT," + COLUMN_QTD12 + "FLOAT," +
                COLUMN_QTD13 + "FLOAT," + COLUMN_QTD14 + "FLOAT); ";
                db.execsql(query2);
    }

    @Override
    public void onUpgrade(sqliteDatabase db,int oldVersion,int newVersion) {
        db.execsql("DROP TABLE IF EXISTS " + TABLE_PRODUTO);
        db.execsql("DROP TABLE IF EXISTS " + TABLE_RECEITA);
        onCreate(db);
    }

    void addProduto(MateriaPrima materiaPrima) {
        sqliteDatabase db = this.getWritableDatabase();
        ContentValues cv = new ContentValues();

        cv.put(COLUMN_PRODUTO,materiaPrima.getProduto());
        cv.put(COLUMN_VALOR,materiaPrima.getValor());
        cv.put(COLUMN_QTD,materiaPrima.getQuantidade());
        cv.put(COLUMN_TIPO,materiaPrima.getTipo());

        long result = db.insert(TABLE_PRODUTO,cv);
        if (result == -1) {
            Toast.makeText(context,R.string.strFailed,Toast.LENGTH_SHORT).show();
        }else {
            Toast.makeText(context,R.string.sTraddSucess,Toast.LENGTH_SHORT).show();
        }
        db.close();
    }

    void addReceita(Receita receita) {
        sqliteDatabase db = this.getWritableDatabase();
        ContentValues cv = new ContentValues();

        cv.put(COLUMN_TITULO,receita.getTitulo());
        cv.put(COLUMN_ITEM1,receita.getItem1());
        cv.put(COLUMN_ITEM2,receita.getItem2());
        cv.put(COLUMN_ITEM3,receita.getItem3());
        cv.put(COLUMN_ITEM4,receita.getItem4());
        cv.put(COLUMN_ITEM5,receita.getItem5());
        cv.put(COLUMN_ITEM6,receita.getItem6());
        cv.put(COLUMN_ITEM7,receita.getItem7());
        cv.put(COLUMN_ITEM8,receita.getItem8());
        cv.put(COLUMN_ITEM9,receita.getItem9());
        cv.put(COLUMN_ITEM10,receita.getItem10());
        cv.put(COLUMN_ITEM11,receita.getItem11());
        cv.put(COLUMN_ITEM12,receita.getItem12());
        cv.put(COLUMN_ITEM13,receita.getItem13());
        cv.put(COLUMN_ITEM14,receita.getItem14());
        cv.put(COLUMN_VALOR1,receita.getValor1());
        cv.put(COLUMN_VALOR2,receita.getValor2());
        cv.put(COLUMN_VALOR3,receita.getValor3());
        cv.put(COLUMN_VALOR4,receita.getValor4());
        cv.put(COLUMN_VALOR5,receita.getValor5());
        cv.put(COLUMN_VALOR6,receita.getValor6());
        cv.put(COLUMN_VALOR7,receita.getValor7());
        cv.put(COLUMN_VALOR8,receita.getValor8());
        cv.put(COLUMN_VALOR9,receita.getValor9());
        cv.put(COLUMN_VALOR10,receita.getValor10());
        cv.put(COLUMN_VALOR11,receita.getValor11());
        cv.put(COLUMN_VALOR12,receita.getValor12());
        cv.put(COLUMN_VALOR13,receita.getValor13());
        cv.put(COLUMN_VALOR14,receita.getValor14());
        cv.put(COLUMN_QTD1,receita.getQtd1());
        cv.put(COLUMN_QTD2,receita.getQtd2());
        cv.put(COLUMN_QTD3,receita.getQtd3());
        cv.put(COLUMN_QTD4,receita.getQtd4());
        cv.put(COLUMN_QTD5,receita.getQtd5());
        cv.put(COLUMN_QTD6,receita.getQtd6());
        cv.put(COLUMN_QTD7,receita.getQtd7());
        cv.put(COLUMN_QTD8,receita.getQtd8());
        cv.put(COLUMN_QTD9,receita.getQtd9());
        cv.put(COLUMN_QTD10,receita.getQtd10());
        cv.put(COLUMN_QTD11,receita.getQtd11());
        cv.put(COLUMN_QTD12,receita.getQtd12());
        cv.put(COLUMN_QTD13,receita.getQtd13());
        cv.put(COLUMN_QTD14,receita.getQtd14());

        long result = db.   insert(TABLE_RECEITA,Toast.LENGTH_SHORT).show();
        }
        db.close();
    }

    public List<MateriaPrima> buscaProduto() {
        String[] columns = {COLUMN_CODIGO,COLUMN_PRODUTO,COLUMN_VALOR,COLUMN_QTD,COLUMN_TIPO};
        sqliteDatabase db = getReadableDatabase();
        @SuppressLint("Recycle") Cursor cursor = db.query(TABLE_PRODUTO,columns,null);

        while (cursor.movetoNext()) {
            int index1 = cursor.getColumnIndex(COLUMN_CODIGO);
            int codigo = cursor.getInt(index1);
            int index2 = cursor.getColumnIndex(COLUMN_PRODUTO);
            String produto = cursor.getString(index2);
            int index3 = cursor.getColumnIndex(COLUMN_VALOR);
            float valor = cursor.getFloat(index3);
            int index4 = cursor.getColumnIndex(COLUMN_QTD);
            float quantidade = cursor.getFloat(index4);
            int index5 = cursor.getColumnIndex(COLUMN_TIPO);
            String tipo = cursor.getString(index5);
            MateriaPrima produtos = new MateriaPrima(codigo,produto,valor,quantidade,tipo);
            listaProduto.add(produtos);
        }
        return listaProduto;
    }

    public List<Receita> buscaReceita() {
        String[] columns = {COLUMN_TITULO,COLUMN_ITEM1,COLUMN_TIPO};
        sqliteDatabase db = getReadableDatabase();
        @SuppressLint("Recycle") Cursor cursor = db.query(TABLE_RECEITA,null);

        while (cursor.movetoNext()) {
            int index1 = cursor.getColumnIndex(COLUMN_TITULO);
            String titulo = cursor.getString(index1);
            int index2 = cursor.getColumnIndex(COLUMN_ITEM1);
            String item1 = cursor.getString(index2);
            /*int index3 = cursor.getColumnIndex(COLUMN_VALOR);
            float valor = cursor.getFloat(index3);
            int index4 = cursor.getColumnIndex(COLUMN_QTD);
            float quantidade = cursor.getFloat(index4);
            int index5 = cursor.getColumnIndex(COLUMN_TIPO);
            String tipo = cursor.getString(index5);*/
            Receita receitas = new Receita(titulo,item1); //,tipo);
            listaReceita.add(receitas);
        }
        return listaReceita;
    }

    void updateData(String row_id,String produto,String valor,String quantidade,String tipo){
        sqliteDatabase db = this.getWritableDatabase();
        ContentValues cv = new ContentValues();
        cv.put(COLUMN_PRODUTO,produto);
        cv.put(COLUMN_VALOR,valor);
        cv.put(COLUMN_QTD,quantidade);
        cv.put(COLUMN_TIPO,tipo);

        long result = db.update(TABLE_PRODUTO,cv,"codigo=?",new String[]{row_id});
        if(result == -1){
            Toast.makeText(context,Toast.LENGTH_SHORT).show();
        } else{
            Toast.makeText(context,R.string.strSucess,Toast.LENGTH_SHORT).show();
        }

        db.close();
    }

   
    void deleteOneRow(String row_id){
        sqliteDatabase db = this.getWritableDatabase();
        long result = db.delete(TABLE_PRODUTO,new String[]{row_id});
        if(result== -1){
            Toast.makeText(context,Toast.LENGTH_SHORT).show();
        }

    }

    void deleteallData() {
        sqliteDatabase db = this.getWritableDatabase();
        db.execsql("DELETE FROM " + TABLE_PRODUTO);
        db.close();
    }
}

我不知道如何编写代码来保存这些更改,我不知道是否必须在数据库插入方法上或仅在此处更改某些内容,因为我的插入方法的编写方式与我的第一个表。

我的 AddProduto(我在第一张桌子上保存我的配料):

package com.myapplication.umdocededaisy;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;

public class AddItem extends AppCompatActivity {
    EditText et_produto,et_valor,et_qtd,et_sqtd,et_tipo,et_stipo;
    Button btnIncluir;
    String produto,tipo;
    List<MateriaPrima> listaProdutos;
    Spinner spinner;
    MyDatabase myDB = new MyDatabase(this);

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

        //Declarações objetos:
        et_produto = findViewById(R.id.et_produto);
        et_valor = findViewById(R.id.et_valor);
        et_qtd = findViewById(R.id.et_qtd);
        et_sqtd = findViewById(R.id.et_sqtd);
        et_tipo = findViewById(R.id.et_tipo);
        et_stipo = findViewById(R.id.et_stipo);
        btnIncluir = findViewById(R.id.btnIncluir);
        spinner = findViewById(R.id.spinner);

        //Chamada de Métodos:
        getAndSetIntentData();
        loadSpinnerData();
        loadSpinner();


        //Botões:
        //Save Button to Second Table:
        btnIncluir.setonClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Receita receita = new Receita();
                

                myDB.addReceita(receita);
            }
        });
    }

    void getAndSetIntentData() {
        if (getIntent().hasExtra("produto") && getIntent().hasExtra("valor") &&
                getIntent().hasExtra("quantidade") && getIntent().hasExtra("tipo")){
            //Getting data:
            produto = getIntent().getStringExtra("produto");
            valor = getIntent().getStringExtra("valor");
            quantidade = getIntent().getStringExtra("quantidade");
            tipo = getIntent().getStringExtra("tipo");

            //Setting data:
            et_produto.setText(produto);
            et_valor.setText(valor);
            et_qtd.setText(quantidade);
            et_tipo.setText(tipo);
            et_stipo.setText(tipo);

        }else{
            Toast.makeText(this,R.string.strData0,Toast.LENGTH_SHORT).show();
        }
    }

谁能帮帮我? 我到处找,但没有发现任何可以适用于我的案例的东西。 提前致谢。

解决方法

我不知道如何编写代码来保存这些更改,

您的数据库设计似乎引入了复杂性,这会使在第二个表中插入和检索数据变得相当复杂。

从外观上看,您的第二个表由许多列组成,其中的关系可以替换重复的列(材料/成分),并且添加这样的关系可能会简化问题。

为了了解这一点,您有材料(成分),例如牛奶面粉糖等。一种成分可以用于许多食谱,而一个食谱可以使用多种成分。因此,您可能希望食谱和成分之间存在多对多关系。

所以我建议你考虑一个允许你拥有多对多关系的映射表,所以 3 个表而不是 2 个。也许考虑以下:-

CREATE TABLE IF NOT EXISTS materia_prima (codigo INTEGER PRIMARY KEY /* AUTOINCREMENT */,produto TEXT,VALOR FLOAT,QTD FLOAT,TIPO TEXT);
CREATE TABLE IF NOT EXISTS receitas (TITULO TEXT PRIMARY KEY);
CREATE TABLE IF NOT EXISTS receitas_materia (
    titulo_map TEXT REFERENCES receitas(titulo) ON DELETE CASCADE ON UPDATE CASCADE,materia_map INTEGER REFERENCES materia_prima(codigo) ON DELETE CASCADE ON UPDATE CASCADE,receitas_materia_qtd FLOAT,PRIMARY KEY(titulo_map,materia_map));
  • materia_prima 表原样(除了不需要低效的 AUTOINCREMENT,因此已被注释掉)
  • 收据表已大大简化(只有 1 列)
  • receitas_materia 表是映射表,用于表示配方使用了一种成分。
    • 已添加外键约束(REFERENCES 子句)以强制执行参照完整性。
    • ON DELETE/UPDATE 表示将更改从父级传播到子级。
  • 添加了第三列以表示配方使用的数量。

因此进一步添加以下数据:-

首先是一些成分,包括它们的每次测量成本:-

INSERT INTO materia_prima VALUES 
    (null,'Plain Flour',0.54,1,'Gram'),(null,'SR Flour',0.55,'Eggs',1.34,'Each'),'Milk',0.2,'MilliLitre'),'Sugar',0.65,'Gram');

第二部分食谱:-

INSERT INTO receitas VALUES ('Bread'),('Cake'),('Scone');

现在食谱中使用的成分(只是面包和蛋糕):-

INSERT INTO receitas_materia VALUES 
    ('Bread',1 /*map to Plain Flour*/,200 /* uses 200 grams */),('Bread',3,2),4,50),5,10),('Cake',2,400),3),100),300)
;
  • 因此,而不是许多列以及尝试确定哪些列中的内容的复杂性。您只需根据需要为每个食谱添加尽可能多的成分(并让查询完成工作)。

查询如:-

SELECT *,valor * receitas_materia_qtd AS cost 

从 receitas JOIN receitas_materia ON receitas_materia.titulo_map = receitas.titulo JOIN materia_prima ON materia_prima.codigo = receitas_materia.materia_map;

可用于列出产品及其成分,包括每种成分的成本,例如使用上面的结果是:-

enter image description here

  • 例如面包使用 200 克糖,每克成本为 0.54,因此面包的糖成本为 108。

您似乎想要每件商品的总成本,因此查询类似于:-

SELECT titulo,group_concat(produto||' ('||receitas_materia_qtd||' '||tipo||')') AS materias,sum(valor * receitas_materia_qtd) AS total_cost 
FROM receitas JOIN receitas_materia ON receitas_materia.titulo_map = receitas.titulo JOIN materia_prima ON materia_prima.codigo = receitas_materia.materia_map
GROUP BY titulo;

可以使用,结果是:-

enter image description here

基于 Android 的示例

以下是一个基本示例,它允许通过微调器将成分添加到配方中。还列出了当前的成分,允许长按成分也可以删除该成分。

该示例使用了更易于使用的光标适配器。

首先是 MyDatabase,它使用建议的设计并包含各种方法:-

public class MyDatabase extends SQLiteOpenHelper {

    private static final String DATABASE_NAME = "BancoDoceDaisy.db";
    private static final int DATABASE_VERSION = 9;
    SQLiteDatabase db;

    public static final String TABLE_PRODUTO = "materia_prima";
    public static final String COLUMN_PRODUTO_CODIGO = BaseColumns._ID; /*CHANGED Use the standard Android ID column name */
    public static final String COLUMN_PRODUTO = "produto";
    public static final String COLUMN_VALOR = "valor";
    public static final String COLUMN_QTD = "quantidade";
    public static final String COLUMN_TIPO = "tipo";

    public static final String TABLE_RECEITA = "receitas";
    public static final String COLUMN_RECEITA_CODIGO = BaseColumns._ID;
    public static final String COLUMN_TITULO = "titulo";

    public static final String TABLE_RECEITA_MATERIA_MAP = TABLE_RECEITA + "_" + TABLE_PRODUTO + "_map";
    public static final String COLUMN_RECEITA_MAP = TABLE_RECEITA + "_map";
    public static final String COLUMN_PRODUTO_MAP = TABLE_PRODUTO + "_map";
    public static final String COLUMN_RECEITA_QTD = TABLE_RECEITA + "_" + COLUMN_QTD;
    public static final String DERIVED_COLUMN_COST = "cost";
    private static final String cost_calculate = TABLE_PRODUTO + "." + COLUMN_VALOR + " * " + TABLE_RECEITA_MATERIA_MAP + "." + COLUMN_RECEITA_QTD + " AS " + DERIVED_COLUMN_COST;
    public static final String DERIVED_COLUMN_TOTAL_COST = "total_cost";
    private static final String total_cost_calculate = "SUM(" +  TABLE_PRODUTO + "." + COLUMN_VALOR + " * " + TABLE_RECEITA_MATERIA_MAP + "." + COLUMN_QTD + ") AS " + DERIVED_COLUMN_TOTAL_COST;
    private final String join_receitamateria_map =
            " JOIN " + TABLE_RECEITA_MATERIA_MAP +
                    " ON " + TABLE_RECEITA + "." + COLUMN_RECEITA_CODIGO +
                    " = " + TABLE_RECEITA_MATERIA_MAP + "." + COLUMN_RECEITA_MAP;
    private final String join_produto =
            " JOIN " + TABLE_PRODUTO +
                    " ON " + TABLE_RECEITA_MATERIA_MAP + "." + COLUMN_PRODUTO_MAP +
                    " = " + TABLE_PRODUTO + "." + COLUMN_PRODUTO_CODIGO;

    private static final String fkey_options = " ON DELETE CASCADE ON UPDATE CASCADE ";

    private static volatile MyDatabase instance = null;

    private MyDatabase(@Nullable Context context) {
        super(context,DATABASE_NAME,null,DATABASE_VERSION);
        db = this.getWritableDatabase();
    }

    public static MyDatabase getDatabaseInstance(Context context) {
        if (instance == null) {
            instance = new MyDatabase(context);
        }
        return instance;
    }

    @Override
    public void onCreate(SQLiteDatabase db) {

        String query = "CREATE TABLE "+ TABLE_PRODUTO +
                " (" + COLUMN_PRODUTO_CODIGO + " INTEGER PRIMARY KEY," +
                COLUMN_PRODUTO + " TEXT," +
                COLUMN_VALOR + " FLOAT," +
                COLUMN_QTD + " FLOAT," +
                COLUMN_TIPO + " TEXT); ";
        db.execSQL(query);
        query = "CREATE TABLE IF NOT EXISTS " + TABLE_RECEITA + "(" +
                COLUMN_RECEITA_CODIGO + " INTEGER PRIMARY KEY," +  /* ADDED to make things simpler android wise */
                COLUMN_TITULO + " TEXT UNIQUE" +
                ")";
        db.execSQL(query);
        query = "CREATE TABLE IF NOT EXISTS "  +TABLE_RECEITA_MATERIA_MAP + "(" +
                COLUMN_RECEITA_MAP + " INTEGER REFERENCES " + TABLE_RECEITA + "(" + COLUMN_PRODUTO_CODIGO + ")" + fkey_options  + "," +
                COLUMN_PRODUTO_MAP + " INTEGER REFERENCES " + TABLE_PRODUTO + "(" + COLUMN_RECEITA_CODIGO + ")" + fkey_options + "," +
                COLUMN_RECEITA_QTD + " FLOAT," +
                "PRIMARY KEY(" + COLUMN_RECEITA_MAP + "," + COLUMN_PRODUTO_MAP + ")" +
                ")";
        db.execSQL(query);

    }

    @Override
    public void onUpgrade(SQLiteDatabase db,int i,int i1) {

    }

    public long insertProduto(String produto,Float valor,Float qtd,String tipo) {
        ContentValues cv = new ContentValues();
        cv.put(COLUMN_PRODUTO,produto);
        cv.put(COLUMN_VALOR,valor);
        cv.put(COLUMN_QTD,qtd);
        cv.put(COLUMN_TIPO,tipo);
        return db.insert(TABLE_PRODUTO,cv);
    }

    public long insertReceita(String titulo) {
        ContentValues cv = new ContentValues();
        cv.put(COLUMN_TITULO,titulo);
        return db.insert(TABLE_RECEITA,cv);
    }

    public long insertReceitaMateria(long receitaMap,long produtoMap,Float qtd) {
        ContentValues cv = new ContentValues();
        cv.put(COLUMN_RECEITA_MAP,receitaMap);
        cv.put(COLUMN_PRODUTO_MAP,produtoMap);
        cv.put(COLUMN_RECEITA_QTD,qtd);
        return db.insert(TABLE_RECEITA_MATERIA_MAP,cv);
    }

    public int deleteMateriaFromReceita(long receita,long produtoCodigo) {
        return  db.delete(TABLE_RECEITA_MATERIA_MAP,COLUMN_RECEITA_MAP + " =? AND " + COLUMN_PRODUTO_MAP + "=?",new String[]{String.valueOf(receita),String.valueOf(produtoCodigo)});
    }

    public Cursor getProduto() {
        return db.query(TABLE_PRODUTO,null);
    }
    public Cursor getReceita() {
        return db.query(TABLE_RECEITA,null);
    }
    public Cursor getReceitaProduto(Long receita) {
        return db.query(
                TABLE_RECEITA + join_receitamateria_map + join_produto,new String[]{"*",cost_calculate},TABLE_RECEITA_MATERIA_MAP + "." + COLUMN_RECEITA_MAP + "=?",new String[]{receita.toString()},null);
    }

    public String getReceitanameByCodigo(long codigo) {
        String rv = "NOT KNOWN";
        Cursor csr =db.query(TABLE_RECEITA,new String[]{COLUMN_TITULO},COLUMN_RECEITA_CODIGO + "=?",new String[]{String.valueOf(codigo)},null);
        if (csr.moveToFirst()) {
            rv = csr.getString(csr.getColumnIndex(COLUMN_TITULO));
        }
        csr.close();
        return rv;
    }

}

接下来是一个初始活动 MainActivity(设计为只运行一次),它添加了一些材料/产品(成分)和一些空白(无成分)receitas(食谱)。之后调用 AddProduto 活动,将 Cake 配方传递给活动:-

public class MainActivity extends AppCompatActivity {

    MyDatabase db;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        db = MyDatabase.getDatabaseInstance(this);

        db.insertProduto("Plain Flour",0.54F,1F,"Grams");
        db.insertProduto("SR Flour",0.55F,"Grams");
        db.insertProduto("Eggs",1.34F,1f,"Each");
        db.insertProduto("Milk",0.2F,"ml");
        db.insertProduto("Sugar",0.65F,"Grams");

        db.insertReceita("Bread");
        long selectedId = db.insertReceita("Cake");
        db.insertReceita("Scone");

        Intent intent = new Intent(this,AddProduto.class);
        intent.putExtra(MyDatabase.TABLE_RECEITA,selectedId);
        startActivity(intent);
    }
}

最后是 AddProduto 活动。这有一个允许选择成分的微调器。选择一种成分会将该成分添加到配方中,然后会刷新配方中的成分以显示添加的成分。如果长按成分列表中的某个成分,则会将其从配方中删除。

请注意,仅包含非常基本的管理。例如实际上,微调器中的成分应该排除配方中已有的成分。

为了演示/示例的简单/简洁,配料的数量/数量设置为 100:-

public class AddProduto extends AppCompatActivity {

    TextView receita;
    Spinner materia_add;
    ListView materia_in;
    SimpleCursorAdapter adapter_list,adapter_spinner;
    MyDatabase db;
    Cursor csr_add,csr_in;
    long current_receita;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_add_produto);
        db = MyDatabase.getDatabaseInstance(this);

        receita = this.findViewById(R.id.Receita);
        current_receita = this.getIntent().getLongExtra(MyDatabase.TABLE_RECEITA,0);
        receita.setText(db.getReceitanameByCodigo(current_receita));
        materia_add = this.findViewById(R.id.materia_add);
        materia_in = this.findViewById(R.id.materia_in);
        setOrRefreshSpinner();
        setOrRefreshReceitaList();

    }

    // Handling the Spinner
    private void setOrRefreshSpinner() {
        csr_add = db.getProduto();
        if (adapter_spinner == null) {
            adapter_spinner = new SimpleCursorAdapter(
                    this,android.R.layout.simple_list_item_2,csr_add,new String[]{MyDatabase.COLUMN_PRODUTO,MyDatabase.COLUMN_VALOR},new int[]{android.R.id.text1,android.R.id.text2},0
            );
            materia_add.setAdapter(adapter_spinner);
            materia_add.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
                @Override
                public void onItemSelected(AdapterView<?> adapterView,View view,long l) {
                    db.insertReceitaMateria(current_receita,l,100F); // Made up value for demo
                    setOrRefreshReceitaList(); // Update the List of materia in the receita
                }

                @Override
                public void onNothingSelected(AdapterView<?> adapterView) {

                }
            });
        } else {
            adapter_spinner.swapCursor(csr_add);
        }
    }

    // Handling the recipe ListView
    private void setOrRefreshReceitaList() {
        csr_in = db.getReceitaProduto(current_receita);
        if (adapter_list == null) {
            adapter_list = new SimpleCursorAdapter(
                    this,csr_in,MyDatabase.DERIVED_COLUMN_COST},0
            );
            materia_in.setAdapter(adapter_list);
            materia_in.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
                @Override
                public boolean onItemLongClick(AdapterView<?> adapterView,long l) {
                    db.deleteMateriaFromReceita(current_receita,l);
                    setOrRefreshReceitaList();
                    return true;
                }
            });
        } else {
            adapter_list.swapCursor(csr_in);
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        csr_in.close();
        csr_add.close();
    }
}

结果

第一次运行时会显示 AddProduto 活动(在 MainActivity 启动之后):-

enter image description here

  • 请注意,尚未包括处理 Spinner 自动选择项目的事实,因此在进行任何选择之前添加了成分(请参阅 regrad 中的 Android Spinner : Avoid onItemSelected calls during initialization 以避免这种情况)。

  • 紫色是旋转器

  • 青色是食谱的成分列表(成分的总成本,即 100 * 成分成本)。

从旋转器中选择鸡蛋:-

enter image description here

然后选择后(添加鸡蛋):-

enter image description here

成分列表中的LongClick普通面粉:-

enter image description here

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