如何解决使用表 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;
可用于列出产品及其成分,包括每种成分的成本,例如使用上面的结果是:-
- 例如面包使用 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;
可以使用,结果是:-
基于 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 启动之后):-
-
请注意,尚未包括处理 Spinner 自动选择项目的事实,因此在进行任何选择之前添加了成分(请参阅 regrad 中的 Android Spinner : Avoid onItemSelected calls during initialization 以避免这种情况)。
-
紫色是旋转器
-
青色是食谱的成分列表(成分的总成本,即 100 * 成分成本)。
从旋转器中选择鸡蛋:-
然后选择后(添加鸡蛋):-
成分列表中的LongClick普通面粉:-
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。