SQLite 和 SQLiteDatabase 的使用
实验七:SQLite 和 SQLiteDatabase 的使用
7.1 实验目的
本次实验的目的是让大家熟悉 Android 中对数据库进行操作的相关的接口、类等。SQLiteDatabase 这个是在 android 中数据库操作使用最频繁的一个类。通过它可以实现数据库的创建或打开、创建表、插入数据、删除数据、查询数据、修改数据等操作。
7.2 实验要求
- 实现便签管理小例程。
- 创建项目并熟悉文件目录结构
- 实现便签增删改查功能的实验步骤
7.3 实验内容
【练习 7.1】 便签管理小例程
步骤 1: 项目结构
创建一个名为"便签管理系统"的Android项目,包含以下文件和文件夹:
activity_main.xml(启动窗体)insertinfo.xml(新增便签窗体)showinfo.xml(查看便签信息窗体)manageflag.xml(便签管理窗体)MainActivity.java(主活动)InsertFlag.java(新增便签活动)ShowInfo.java(查看便签信息活动)ManageFlag.java(便签管理活动)DBOpenHelper.java(数据库帮助类)FlagDao.java(便签数据访问类)flag.java(便签实体类)AndroidManifest.xml(清单文件)
步骤 2: 配置布局文件
-
activity_main.xml (启动窗体)
-
包含两个按钮:
btnflaginfo(查看便签信息) 和btninsertinfo(添加便签)<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="fill_parent"android:layout_height="fill_parent"android:orientation="vertical"><LinearLayoutandroid:id="@+id/linearLayout1"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_weight="0.06"android:orientation="vertical"><RelativeLayoutandroid:layout_width="match_parent"android:layout_height="wrap_content"><Buttonandroid:id="@+id/btnflaginfo"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="便签信息"android:textColor="#8C6931"android:textSize="20dp" /><Buttonandroid:id="@+id/btninsertinfo"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_toRightOf="@id/btnflaginfo"android:text="添加便签"android:textColor="#8C6931"android:textSize="20dp" /></RelativeLayout></LinearLayout> </LinearLayout>
-
-
Insertinfo.xml (新增便签窗体)
-
包含一个文本框
txtFlag用于输入便签内容 -
包含两个按钮:
btnflagSave(保存) 和btnflagCancel(取消)<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/itemflag"android:layout_width="fill_parent"android:layout_height="fill_parent"android:orientation="vertical"><LinearLayoutandroid:layout_width="fill_parent"android:layout_height="fill_parent"android:layout_weight="3"android:orientation="vertical"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:gravity="center_horizontal"android:text="新增便签"android:textColor="#000000"android:textSize="40sp"android:textStyle="bold" /></LinearLayout><LinearLayoutandroid:layout_width="fill_parent"android:layout_height="fill_parent"android:layout_weight="1"android:orientation="vertical"><RelativeLayoutandroid:layout_width="fill_parent"android:layout_height="fill_parent"android:padding="5dp"><TextViewandroid:id="@+id/tvFlag"android:layout_width="350dp"android:layout_height="wrap_content"android:layout_alignParentRight="true"android:text="请输入便签,最多输入 200 字"android:textColor="#8C6931"android:textSize="23sp" /><EditTextandroid:id="@+id/txtFlag"android:layout_width="350dp"android:layout_height="400dp"android:layout_below="@id/tvFlag"android:gravity="top"android:singleLine="false" /></RelativeLayout></LinearLayout><LinearLayoutandroid:layout_width="fill_parent"android:layout_height="fill_parent"android:layout_weight="3"android:orientation="vertical"><RelativeLayoutandroid:layout_width="fill_parent"android:layout_height="fill_parent"android:padding="10dp"><Buttonandroid:id="@+id/btnflagCancel"android:layout_width="80dp"android:layout_height="wrap_content"android:layout_alignParentRight="true"android:layout_marginLeft="10dp"android:text="取消" /><Buttonandroid:id="@+id/btnflagSave"android:layout_width="80dp"android:layout_height="wrap_content"android:layout_toLeftOf="@id/btnflagCancel"android:maxLength="200"android:text="保存" /></RelativeLayout></LinearLayout> </LinearLayout>
-
-
showinfo.xml (查看便签信息窗体)
- 包含一个文本视图
textView1和一个列表视图lvinfo用于展示便签信息
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"><TextViewandroid:id="@+id/textView1"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="便签信息"android:textSize="20dp" /><LinearLayoutandroid:id="@+id/linearLayout2"android:layout_width="match_parent"android:layout_height="wrap_content"android:layout_weight="0.94"android:orientation="vertical"><ListViewandroid:id="@+id/lvinfo"android:layout_width="match_parent"android:layout_height="match_parent"android:scrollbarAlwaysDrawVerticalTrack="true" /></LinearLayout> </LinearLayout> - 包含一个文本视图
-
manageflag.xml (便签管理窗体)
- 包含一个文本框
txtFlagManage和两个按钮:btnFlagManageEdit(修改) 和btnFlagManageDelete(删除)
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/flagmanage"android:layout_width="fill_parent"android:layout_height="fill_parent"android:orientation="vertical"><LinearLayoutandroid:layout_width="fill_parent"android:layout_height="fill_parent"android:layout_weight="3"android:orientation="vertical"><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:gravity="center_horizontal"android:text="便签管理"android:textColor="#000000"android:textSize="40sp"android:textStyle="bold" /></LinearLayout><LinearLayoutandroid:layout_width="fill_parent"android:layout_height="fill_parent"android:layout_weight="1"android:orientation="vertical"><RelativeLayoutandroid:layout_width="fill_parent"android:layout_height="fill_parent"android:padding="5dp"><TextViewandroid:id="@+id/tvFlagManage"android:layout_width="350dp"android:layout_height="wrap_content"android:layout_alignParentRight="true"android:text="请输入便签,最多输入 200 字"android:textColor="#8C6931"android:textSize="23sp" /><EditTextandroid:id="@+id/txtFlagManage"android:layout_width="350dp"android:layout_height="400dp"android:layout_below="@id/tvFlagManage"android:gravity="top"android:singleLine="false" /></RelativeLayout></LinearLayout><LinearLayoutandroid:layout_width="fill_parent"android:layout_height="fill_parent"android:layout_weight="3"android:orientation="vertical"><RelativeLayoutandroid:layout_width="fill_parent"android:layout_height="fill_parent"android:padding="10dp"><Buttonandroid:id="@+id/btnFlagManageDelete"android:layout_width="80dp"android:layout_height="wrap_content"android:layout_alignParentRight="true"android:layout_marginLeft="10dp"android:text="删除" /><Buttonandroid:id="@+id/btnFlagManageEdit"android:layout_width="80dp"android:layout_height="wrap_content"android:layout_toLeftOf="@id/btnFlagManageDelete"android:maxLength="200"android:text="修改" /></RelativeLayout></LinearLayout> </LinearLayout> - 包含一个文本框
步骤 3: 配置活动文件
-
MainActivity.java
- 初始化界面和按钮
- 为按钮添加点击事件,分别跳转到
ShowInfo和InsertFlag活动
package com.example.notemanagementsystem.activity;import android.os.Bundle; import android.app.Activity; import android.content.Intent; import android.view.Menu; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button;import com.wenlong.DBLab.activity.R;public class MainActivity extends Activity {Button btnflaginfo, btninsertinfo;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);btnflaginfo = (Button) findViewById(R.id.btnflaginfo);btninsertinfo = (Button) findViewById(R.id.btninsertinfo);btnflaginfo.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent(MainActivity.this, ShowInfo.class);startActivity(intent);}});btninsertinfo.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent(MainActivity.this, InsertFlag.class);startActivity(intent);}});}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.main, menu);return true;} } -
InsertFlag.java
- 处理新增便签的界面逻辑
- 获取输入的便签内容,保存到数据库,并显示相应的提示信息
package com.example.notemanagementsystem;import android.app.Activity; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.Toast;import com.example.notemanagementsystem.DAO.FlagDao; import com.example.notemanagementsystem.model.flag;public class InsertFlag extends Activity {EditText txtFlag;// 创建 EditText 组件对象Button btnflagSaveButton;// 创建 Button 组件对象Button btnflagCancelButton;// 创建 Button 组件对象@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.insertinfo);txtFlag = (EditText) findViewById(R.id.txtFlag);btnflagSaveButton = (Button) findViewById(R.id.btnflagSave);btnflagCancelButton = (Button) findViewById(R.id.btnflagCancel);btnflagSaveButton.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {String strFlag = txtFlag.getText().toString();// 获取便签文本框的值if (!strFlag.isEmpty()) {// 判断获取FlagDao flagDAO = new FlagDao(InsertFlag.this);// 创建FlagDAO 对象flag flag = new flag(flagDAO.getMaxId() + 1, strFlag);// 创建 Tb_flag 对象flagDAO.add(flag);// 添加便签信息// 弹出信息提示Toast.makeText(InsertFlag.this, "〖新增便签〗数据添加成功!",Toast.LENGTH_SHORT).show();} else {Toast.makeText(InsertFlag.this, "请输入便签!",Toast.LENGTH_SHORT).show();}}});btnflagCancelButton.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {finish();}});} } -
ShowInfo.java
- 展示所有便签信息的界面逻辑
- 使用
ListView显示便签列表,点击某一项跳转到ManageFlag活动
package com.example.notemanagementsystem;import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ArrayAdapter; import android.widget.ListView; import android.widget.TextView;import com.example.notemanagementsystem.DAO.FlagDao; import com.example.notemanagementsystem.model.flag;import java.util.List;public class ShowInfo extends Activity {public static final String FLAG = "id";// 定义一个常量,用来作为请求码ListView lvinfo;// 创建 ListView 对象String[] strInfos = null;// 定义字符串数组,用来存储收入信息ArrayAdapter<String> arrayAdapter = null;// 创建 ArrayAdapter 对象@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.showinfo);lvinfo = (ListView) findViewById(R.id.lvinfo);FlagDao flaginfo = new FlagDao(ShowInfo.this);// 创建 FlagDAO 对象// 获取所有便签信息,并存储到 List 泛型集合中List<flag> listFlags = flaginfo.getScrollData(0,(int) flaginfo.getCount());strInfos = new String[listFlags.size()];// 设置字符串数组的长度int n = 0;// 定义一个开始标识for (flag tb_flag : listFlags) {// 将便签相关信息组合成一个字符串,存储到字符串数组的相应位置strInfos[n] = tb_flag.getid() + "|" + tb_flag.getFlag();if (strInfos[n].length() > 15)// 判断便签信息的长度是否大于 15strInfos[n] = strInfos[n].substring(0, 15) + "……";// 将位置大于 15之后的字符串用……代替n++;// 标识加 1}arrayAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, strInfos);lvinfo.setAdapter(arrayAdapter);lvinfo.setOnItemClickListener(new OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> parent, View view, int position,long id) {String strInfo = String.valueOf(((TextView) view).getText());// 记录单击的项信息String strid = strInfo.substring(0, strInfo.indexOf('|'));// 从项信息中截取编号Intent intent = null;// 创建 Intent 对象intent = new Intent(ShowInfo.this, ManageFlag.class);// 使用 FlagManage 窗口初始化 Intent 对象intent.putExtra(FLAG, strid);// 设置要传递的数据startActivity(intent);// 执行 Intent,打开相应的 Activity}});} } -
ManageFlag.java
- 处理便签管理的界面逻辑
- 获取传递的便签id,显示该便签内容,可进行编辑和删除操作
package com.example.notemanagementsystem;import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.Toast;import com.example.notemanagementsystem.DAO.FlagDao; import com.example.notemanagementsystem.model.flag;public class ManageFlag extends Activity {EditText txtFlag;// 创建 EditText 对象Button btnEdit, btnDel;// 创建两个 Button 对象String strid;// 创建字符串,表示便签的 id@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.manageflag);txtFlag = (EditText) findViewById(R.id.txtFlagManage);btnEdit = (Button) findViewById(R.id.btnFlagManageEdit);btnDel = (Button) findViewById(R.id.btnFlagManageDelete);Intent intent = getIntent();// 创建 Intent 对象Bundle bundle = intent.getExtras();// 获取便签 idstrid = bundle.getString(ShowInfo.FLAG);// 将便签 id 转换为字符串final FlagDao flagDAO = new FlagDao(ManageFlag.this);// 创建 FlagDAO 对象txtFlag.setText(flagDAO.find(Integer.parseInt(strid)).getFlag());// 为修改按钮设置监听事件btnEdit.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {flag tb_flag = new flag();// 创建 Tb_flag 对象tb_flag.setid(Integer.parseInt(strid));// 设置便签 idtb_flag.setFlag(txtFlag.getText().toString());// 设置便签值flagDAO.update(tb_flag);// 修改便签信息// 弹出信息提示Toast.makeText(ManageFlag.this, "〖便签数据〗修改成功!",Toast.LENGTH_SHORT).show();}});// 为删除按钮设置监听事件btnDel.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {flagDAO.detele(Integer.parseInt(strid));// 根据指定的 id 删除便签信息Toast.makeText(ManageFlag.this, "〖便签数据〗删除成功!",Toast.LENGTH_SHORT).show();}});} }
步骤 4: 配置数据库相关文件
-
DBOpenHelper.java
- 创建数据库,定义便签信息表结构
package com.example.notemanagementsystem.DAO;import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper;public class DBOpenHelper extends SQLiteOpenHelper {private static final int VERSION = 1;// 定义数据库版本号private static final String DBNAME = "flag.db";// 定义数据库名public DBOpenHelper(Context context) {super(context, DBNAME, null, VERSION);}@Overridepublic void onCreate(SQLiteDatabase db) // 创建数据库{db.execSQL("create table tb_flag (_id integer primary key,flag varchar(200)) ");// 创建便签信息表}@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) // 覆写基类的 onUpgrade方法,以便数据库版本更新{} } -
FlagDao.java
- 提供对便签表的增删改查操作
- 包含获取便签总记录数和最大编号的方法
package com.example.notemanagementsystem.DAO;import java.util.ArrayList; import java.util.List;import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase;import com.example.notemanagementsystem.DAO.DBOpenHelper; import com.example.notemanagementsystem.model.flag;public class FlagDao {private DBOpenHelper helper;// 创建 DBOpenHelper 对象private SQLiteDatabase db;// 创建 SQLiteDatabase 对象public FlagDao(Context context)// 定义构造函数{helper = new DBOpenHelper(context);// 初始化 DBOpenHelper 对象}/*** 添加便签信息** @param tb_flag*/public void add(flag flag) {db = helper.getWritableDatabase();// 初始化 SQLiteDatabase 对象db.execSQL("insert into tb_flag (_id,flag) values (?,?)", new Object[]{flag.getid(), flag.getFlag()});// 执行添加便签信息操作}/*** 更新便签信息** @param tb_flag*/public void update(flag tb_flag) {db = helper.getWritableDatabase();// 初始化 SQLiteDatabase 对象db.execSQL("update tb_flag set flag = ? where _id = ?", new Object[]{tb_flag.getFlag(), tb_flag.getid()});// 执行修改便签信息操作}/*** 查找便签信息** @param id* @return*/public flag find(int id) {db = helper.getWritableDatabase();// 初始化 SQLiteDatabase 对象Cursor cursor = db.rawQuery("select _id,flag from tb_flag where _id = ?",new String[]{String.valueOf(id)});// 根据编号查找便签信息,并存储到 Cursor 类中if (cursor.moveToNext())// 遍历查找到的便签信息{// 将遍历到的便签信息存储到 Tb_flag 类中return new flag(cursor.getInt(cursor.getColumnIndex("_id")), cursor.getString(cursor.getColumnIndex("flag")));}return null;// 如果没有信息,则返回 null}/*** 刪除便签信息** @param ids*/public void detele(Integer... ids) {if (ids.length > 0)// 判断是否存在要删除的 id{StringBuffer sb = new StringBuffer();// 创建 StringBuffer 对象for (int i = 0; i < ids.length; i++)// 遍历要删除的 id 集合{sb.append('?').append(',');// 将删除条件添加到 StringBuffer 对象中}sb.deleteCharAt(sb.length() - 1);// 去掉最后一个“,“字符db = helper.getWritableDatabase();// 创建 SQLiteDatabase 对象// 执行删除便签信息操作db.execSQL("delete from tb_flag where _id in (" + sb + ")",(Object[]) ids);}}/*** 获取便签信息** @param start 起始位置* @param count 每页显示数量* @return*/public List<flag> getScrollData(int start, int count) {List<flag> lisTb_flags = new ArrayList<flag>();// 创建集合对象db = helper.getWritableDatabase();// 初始化 SQLiteDatabase 对象// 获取所有便签信息Cursor cursor = db.rawQuery("select * from tb_flag limit ?,?",new String[]{String.valueOf(start), String.valueOf(count)});while (cursor.moveToNext())// 遍历所有的便签信息{// 将遍历到的便签信息添加到集合中lisTb_flags.add(new flag(cursor.getInt(cursor.getColumnIndex("_id")), cursor.getString(cursor.getColumnIndex("flag"))));}return lisTb_flags;// 返回集合}/*** 获取总记录数** @return*/public long getCount() {db = helper.getWritableDatabase();// 初始化 SQLiteDatabase 对象Cursor cursor = db.rawQuery("select count(_id) from tb_flag", null);// 获取便签信息的记录数if (cursor.moveToNext())// 判断 Cursor 中是否有数据{return cursor.getLong(0);// 返回总记录数}return 0;// 如果没有数据,则返回 0}/*** 获取便签最大编号** @return*/public int getMaxId() {db = helper.getWritableDatabase();// 初始化 SQLiteDatabase 对象Cursor cursor = db.rawQuery("select max(_id) from tb_flag", null);// 获取便签信息表中的最大编号while (cursor.moveToLast()) {// 访问 Cursor 中的最后一条数据return cursor.getInt(0);// 获取访问到的数据,即最大编号}return 0;// 如果没有数据,则返回 0} } -
flag.java
- 定义便签实体类,包含编号和便签内容
package com.example.notemanagementsystem.model;public class flag {private int _id;// 存储便签编号private String flag;// 存储便签信息public flag()// 默认构造函数{super();}// 定义有参构造函数,用来初始化便签信息实体类中的各个字段public flag(int id, String flag) {super();this._id = id;// 为便签号赋值this.flag = flag;// 为便签信息赋值}public int getid()// 设置便签编号的可读属性{return _id;}public void setid(int id)// 设置便签编号的可写属性{this._id = id;}public String getFlag()// 设置便签信息的可读属性{return flag;}public void setFlag(String flag)// 设置便签信息的可写属性{this.flag = flag;} }
步骤 5: 配置清单文件
-
AndroidManifest.xml
- 配置主活动为
MainActivity - 配置其他三个活动:
ShowInfo,InsertFlag,ManageFlag
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.wenlong.DBLab.activity"android:versionCode="1"android:versionName="1.0"><uses-sdkandroid:minSdkVersion="8"android:targetSdkVersion="18" /><applicationandroid:allowBackup="true"android:icon="@drawable/ic_launcher"android:label="@string/app_name"android:theme="@style/AppTheme"><activityandroid:name="com.example.notemanagementsystem.MainActivity"android:label="@string/app_name"><intent-filter><action android:name="android.intent.action.MAIN" /><category android:name="android.intent.category.LAUNCHER" /></intent-filter></activity><activityandroid:name="com.example.notemanagementsystem.ShowInfo"android:icon="@drawable/ic_launcher"android:label="便签信息"></activity><activityandroid:name="com.example.notemanagementsystem.InsertFlag"android:icon="@drawable/ic_launcher"android:label="添加便签"></activity><activityandroid:name="com.example.notemanagementsystem.ManageFlag"android:icon="@drawable/ic_launcher"android:label="便签管理"></activity></application> </manifest> - 配置主活动为
步骤 6: 运行与测试
1.文档结构

2.运行效果


【拓展题】编写 Android 项目,实现商品库存数据库管理小系统。
步骤一:创建新的 Android 项目
- 打开 Android Studio。
- 选择 “File” -> “New” -> “New Project…”。
- 在弹出的对话框中,输入项目名称为 “InventoryManagementSystem”,选择语言为 Java,选择 “Phone and Tablet” -> “Empty Activity”,然后点击 “Finish”。
步骤二:创建数据库帮助类(DBOpenHelper)
在项目中创建一个用于管理数据库的帮助类。
DBOpenHelper.java
package com.example.inventorymanagementsystem.database;import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;public class DBOpenHelper extends SQLiteOpenHelper {private static final String DB_NAME = "inventory.db";private static final int DB_VERSION = 1;public DBOpenHelper(Context context) {super(context, DB_NAME, null, DB_VERSION);}@Overridepublic void onCreate(SQLiteDatabase db) {// 创建商品表db.execSQL("CREATE TABLE IF NOT EXISTS products (" +"_id INTEGER PRIMARY KEY AUTOINCREMENT," +"name TEXT," +"quantity INTEGER," +"price REAL)");}@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {// 数据库升级操作}
}
步骤三:创建商品实体类(Product)
创建一个用于表示商品的实体类。
Product.java
package com.example.inventorymanagementsystem.model;public class Product {private int id;private String name;private int quantity;private double price;public Product() {}public Product(String name, int quantity, double price) {this.name = name;this.quantity = quantity;this.price = price;}// Getter and setter methods
}
步骤四:创建商品数据操作类(ProductDAO)
创建一个用于执行商品数据操作的类。
ProductDAO.java
package com.example.inventorymanagementsystem.database;import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import com.example.inventorymanagementsystem.model.Product;
import java.util.ArrayList;
import java.util.List;public class ProductDAO {private SQLiteDatabase db;public ProductDAO(Context context) {DBOpenHelper dbHelper = new DBOpenHelper(context);db = dbHelper.getWritableDatabase();}public long addProduct(Product product) {ContentValues values = new ContentValues();values.put("name", product.getName());values.put("quantity", product.getQuantity());values.put("price", product.getPrice());return db.insert("products", null, values);}public List<Product> getAllProducts() {List<Product> productList = new ArrayList<>();Cursor cursor = db.query("products", null, null, null, null, null, null);while (cursor.moveToNext()) {Product product = new Product();product.setId(cursor.getInt(cursor.getColumnIndex("_id")));product.setName(cursor.getString(cursor.getColumnIndex("name")));product.setQuantity(cursor.getInt(cursor.getColumnIndex("quantity")));product.setPrice(cursor.getDouble(cursor.getColumnIndex("price")));productList.add(product);}cursor.close();return productList;}// 添加其他数据库操作方法,如更新商品信息、删除商品等
}
步骤五:创建商品管理界面(MainActivity)
在 res/layout 文件夹中创建一个用于显示商品列表和添加商品的界面布局文件。
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context=".MainActivity"><ListViewandroid:id="@+id/listViewProducts"android:layout_width="match_parent"android:layout_height="match_parent"android:divider="@android:color/darker_gray"android:dividerHeight="1dp" /><Buttonandroid:id="@+id/btnAddProduct"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Add Product"android:layout_alignParentBottom="true"android:layout_alignParentEnd="true"android:layout_margin="16dp"/>
</RelativeLayout>
activity_add_product.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"android:orientation="vertical"android:padding="16dp"><EditTextandroid:id="@+id/edtProductName"android:layout_width="match_parent"android:layout_height="wrap_content"android:hint="商品名称" /><EditTextandroid:id="@+id/edtProductQuantity"android:layout_width="match_parent"android:layout_height="wrap_content"android:inputType="number"android:hint="数量" /><EditTextandroid:id="@+id/edtProductPrice"android:layout_width="match_parent"android:layout_height="wrap_content"android:inputType="numberDecimal"android:hint="价格" /><Buttonandroid:id="@+id/btnAddProduct"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="添加商品" />
</LinearLayout>
MainActivity.java
package com.example.inventorymanagementsystem;import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import androidx.appcompat.app.AppCompatActivity;
import com.example.inventorymanagementsystem.database.ProductDAO;
import com.example.inventorymanagementsystem.model.Product;
import java.util.List;public class MainActivity extends AppCompatActivity {private ListView listViewProducts;private Button btnAddProduct;private ProductDAO productDAO;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);listViewProducts = findViewById(R.id.listViewProducts);btnAddProduct = findViewById(R.id.btnAddProduct);productDAO = new ProductDAO(this);updateProductList();btnAddProduct.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent(MainActivity.this, AddProductActivity.class);startActivity(intent);}});}private void updateProductList() {List<Product> productList = productDAO.getAllProducts();ArrayAdapter<Product> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, productList);listViewProducts.setAdapter(adapter);}
}
AddProductActivity.java
package com.example.inventorymanagementsystem;import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;import androidx.appcompat.app.AppCompatActivity;
import com.example.inventorymanagementsystem.database.ProductDAO;
import com.example.inventorymanagementsystem.model.Product;public class AddProductActivity extends AppCompatActivity {private EditText edtProductName, edtProductQuantity, edtProductPrice;private Button btnAddProduct;private ProductDAO productDAO;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_add_product);edtProductName = findViewById(R.id.edtProductName);edtProductQuantity = findViewById(R.id.edtProductQuantity);edtProductPrice = findViewById(R.id.edtProductPrice);btnAddProduct = findViewById(R.id.btnAddProduct);productDAO = new ProductDAO(this);btnAddProduct.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {addProduct();}});}private void addProduct() {// 获取用户输入的商品信息String productName = edtProductName.getText().toString();String quantityStr = edtProductQuantity.getText().toString();String priceStr = edtProductPrice.getText().toString();if (!productName.isEmpty() && !quantityStr.isEmpty() && !priceStr.isEmpty()) {int quantity = Integer.parseInt(quantityStr);double price = Double.parseDouble(priceStr);// 创建商品对象Product newProduct = new Product(productName, quantity, price);// 将商品添加到数据库long result = productDAO.addProduct(newProduct);if (result != -1) {Toast.makeText(AddProductActivity.this, "商品添加成功", Toast.LENGTH_SHORT).show();finish(); // 关闭当前界面} else {Toast.makeText(AddProductActivity.this, "商品添加失败", Toast.LENGTH_SHORT).show();}} else {Toast.makeText(AddProductActivity.this, "请填写完整的商品信息", Toast.LENGTH_SHORT).show();}}
}
步骤六:运行效果

相关文章:
SQLite 和 SQLiteDatabase 的使用
实验七:SQLite 和 SQLiteDatabase 的使用 7.1 实验目的 本次实验的目的是让大家熟悉 Android 中对数据库进行操作的相关的接口、类等。SQLiteDatabase 这个是在 android 中数据库操作使用最频繁的一个类。通过它可以实现数据库的创建或打开、创建表、插入数据、删…...
Dempster-Shafer(D-S)证据理论的基本定义和详细分析,优点,缺点,应用!!(系列1)
文章目录 前言一、D-S证据理论的应用:二、D-S证据理论的优点:三、D-S证据理论的缺陷:四、D-S组合规则:总结 前言 Dempster-Shafer(D-S)证据理论是一种不精确推理理论,也称为Dempster/Shafer证据…...
Leetcode—15.三数之和【中等】
2023每日刷题(四十一) Leetcode—15.三数之和 实现代码 class Solution { public:vector<vector<int>> threeSum(vector<int>& nums) {sort(nums.begin(), nums.end());vector<vector<int>> ans;int i, j, k;int s,…...
3、Qt使用windeploy工具打包可执行文件
新建一个文件夹,把要打包的可执行文件exe拷贝过来 点击输入框,复制一下文件夹路径 点击电脑左下角,找到Qt文件夹, 点击打开 “Qt 5.12.0 for Desktop” (我安装的是Qt 5.12.0版本) 输入“cd bin”ÿ…...
[DFS深度优先搜索]集合里的乘法
集合里的乘法 题目描述 给定一个目标数T和一个整数集合S,判断是否存在S的一个非空子集,子集中的数相乘的积为T。 关于输入 输入为两行。 第一行为目标数T,和S中的元素个数N,以空格隔开。 第二行为S中的N个元素,以空…...
K8s 中 Pod OOMKilled 原因
目录 Exit Code 137 解决方案 JVM 感知 cgroup 限制 使用 JDK9 的容器感知机制尝试 问题分析 容器内部感知 CGroup 资源限制 在 Java10 中,改进了容器集成 JVM 参数 MaxDirectMemorySize -XX:MaxDirectMemorySize 的默认值是什么? 其他获取 ma…...
为什么程序员最应该学习的是运营与销售,而不是技术?
大概几个月前,我加入了某副业交流群。这里人才很多,不光是传统意义上的程序员,也有公司老板、偏门大佬、产品经理等。 群里的聊天主题就是搞钱俩字,大家讨论着如何搞钱,分享每日收益情况,以及自己做的产品等…...
MySql数据库常用指令(五)多表连接
MySql数据库常用指令(五)多表连接 一、内连接,或等值连接二、左连接三、右连接 实际应用中,我们常常要连接几个不同的MySQL表,因此在 SELECT, UPDATE 和 DELETE 语句中使用 Mysql 的 JOIN 来联合多表查询 INNER JOIN(内…...
Centos7使用rpm安装mysql 5.7.43
Centos7使用rpm安装mysql 5.7.43 1、下载rpm包 wget https://downloads.mysql.com/archives/get/p/23/file/mysql-5.7.43-1.el7.x86_64.rpm-bundle.tar2、解压并安装 tar xf mysql-5.7.43-1.el7.x86_64.rpm-bundle.tar yum -y install mysql-*3、按需修改mysql配置 #注意&a…...
补充:如何提高selenium的运行速度?
已经通读该专栏文章的同学,或许对UI自动化测试有了一定的掌握,细心的同学肯定会发现一个问题,当用例量达到一定程度时,对于整体用例的执行速度肯定不会很满意。除了应用多线程运行用例的方式加快速度,有没有其他的方法呢? 今天告诉大家,方法是有的!也是本人新学的。即…...
使用Python+Redis实现文章投票网站后端功能
1.实现投票功能,2.创建文章数据,3.对文章进行排序。 实现投票功能 实现投票功能,要注重文章的时效性与投票的公平性,所以需要给投票功能加上一些约束条件: 文章发布满一个星期后&…...
SpringBoot 环境使用 Redis + AOP + 自定义注解实现接口幂等性
目录 一、前言二、主流实现方案介绍2.1、前端按钮做加载状态限制(必备)2.2、客户端使用唯一标识符2.3、服务端通过检测请求参数进行幂等校验(本文使用) 三、代码实现3.1、POM3.2、application.yml3.3、Redis配置类3.4、自定义注解…...
Leetcode—18.四数之和【中等】
2023每日刷题(四十一) Leetcode—18.四数之和 实现代码 class Solution { public:vector<vector<int>> fourSum(vector<int>& nums, int target) {vector<vector<int>> ans;sort(nums.begin(), nums.end());int n …...
springsecurity6配置二
一、springsecurity6自定义认证异常处理器 1.1 AuthenticationEntryPointImpl.java package com.school.information.core.security.handler;import com.alibaba.fastjson.JSON; import com.school.information.enums.result.ResultStatusEnum; import com.school.informatio…...
php如何对比浮点数大小(bccomp函数)
第一部分,常规例子: 例1:左边比右边小,结果:-1 //示例,左边比右边小返回值:-1 $price1 2.14; $price2 3.14; $result bccomp($price1, $price2, 2); echo 对比结果:.$result;//…...
服务号和订阅号哪个好
服务号和订阅号有什么区别?服务号转为订阅号有哪些作用?在推送频率上来看,服务号每月能推送四条消息,而订阅号可以每天(24小时)推送一条消息。如果企业开通公众号的目的是提供服务,例如售前资讯…...
面试问题--智能指针
什么是智能指针? 当你在编写程序时,可能需要在运行时动态分配内存来存储数据。在传统的C中,你可能会使用 new 和 delete 操作符来手动管理内存。但是这样容易出现一些问题,比如忘记释放内存导致内存泄漏,或者释放了之…...
向量机SVM原理理解和实战
目录 概念场景导入 点到超平面的距离公式 最大间隔的优化模型 硬间隔、软间隔和非线性 SVM 用 SVM 如何解决多分类问题 1. 一对多法 2. 一对一法 SVM主要原理和特点 原理 优点 缺点 支持向量机模型分类 SVM实战如何进行乳腺癌检测 数据集 字段含义 代码实现 参…...
什么是 Node.js?
在 Node.js 出现之前,最常见的 JavaScript 运行时环境是浏览器,也叫做 JavaScript 的宿主环境。浏览器为 JavaScript 提供了 DOM API,能够让 JavaScript 操作浏览器环境(JS 环境)。 2009 年初 Node.js 出现了…...
系列九、声明式事务(xml方式)
一、概述 声明式事务(declarative transaction management)是Spring提供的对程序事务管理的一种方式,Spring的声明式事务顾名思义就是采用声明的方式来处理事务。这里所说的声明,是指在配置文件中声明,用在Spring配置文件中声明式的处理事务来…...
java_网络服务相关_gateway_nacos_feign区别联系
1. spring-cloud-starter-gateway 作用:作为微服务架构的网关,统一入口,处理所有外部请求。 核心能力: 路由转发(基于路径、服务名等)过滤器(鉴权、限流、日志、Header 处理)支持负…...
脑机新手指南(八):OpenBCI_GUI:从环境搭建到数据可视化(下)
一、数据处理与分析实战 (一)实时滤波与参数调整 基础滤波操作 60Hz 工频滤波:勾选界面右侧 “60Hz” 复选框,可有效抑制电网干扰(适用于北美地区,欧洲用户可调整为 50Hz)。 平滑处理&…...
聊聊 Pulsar:Producer 源码解析
一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台,以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中,Producer(生产者) 是连接客户端应用与消息队列的第一步。生产者…...
【Java_EE】Spring MVC
目录 Spring Web MVC 编辑注解 RestController RequestMapping RequestParam RequestParam RequestBody PathVariable RequestPart 参数传递 注意事项 编辑参数重命名 RequestParam 编辑编辑传递集合 RequestParam 传递JSON数据 编辑RequestBody …...
NLP学习路线图(二十三):长短期记忆网络(LSTM)
在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...
06 Deep learning神经网络编程基础 激活函数 --吴恩达
深度学习激活函数详解 一、核心作用 引入非线性:使神经网络可学习复杂模式控制输出范围:如Sigmoid将输出限制在(0,1)梯度传递:影响反向传播的稳定性二、常见类型及数学表达 Sigmoid σ ( x ) = 1 1 +...
Caliper 配置文件解析:config.yaml
Caliper 是一个区块链性能基准测试工具,用于评估不同区块链平台的性能。下面我将详细解释你提供的 fisco-bcos.json 文件结构,并说明它与 config.yaml 文件的关系。 fisco-bcos.json 文件解析 这个文件是针对 FISCO-BCOS 区块链网络的 Caliper 配置文件,主要包含以下几个部…...
浪潮交换机配置track检测实现高速公路收费网络主备切换NQA
浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求,本次涉及的主要是收费汇聚交换机的配置,浪潮网络设备在高速项目很少,通…...
基于Java+MySQL实现(GUI)客户管理系统
客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息,对客户进行统一管理,可以把所有客户信息录入系统,进行维护和统计功能。可通过文件的方式保存相关录入数据,对…...
人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式
今天是关于AI如何在教学中增强学生的学习体验,我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育,这并非炒作,而是已经发生的巨大变革。教育机构和教育者不能忽视它,试图简单地禁止学生使…...
