首页 > 数据库 >Android家庭记账本开发第四天:SQLite数据库操作

Android家庭记账本开发第四天:SQLite数据库操作

时间:2024-02-19 15:25:04浏览次数:32  
标签:SQLite String 数据库 public cursor 记账 Android null id

SQlite数据库是一个轻量级的数据库,被用在嵌入式设备上,2019年6月还在流行的两大移动终端操作系统,Android和ios都支持这款数据库。

Android SDK中有一个包android.database.sqlite,其中专门对SQLite数据库进行了封装,并提供了一套供android使用的API。

SQLiteOpenHelper 类包含一组用于管理数据库的实用 API。在我们的项目中,实现SQLiteOpenHelper并重写onCreate() 和 onUpgrade()等方法。

当执行数据增删改查需要用到数据库对象时,仅需调用SQLiteOpenHelper 的 getWritableDatabase() 或 getReadableDatabase() 即可获得可读写或者只读数据库对象。 

这里给出记账本中的DBHelper类:

 1 package com.example.myapplication3;
 2 
 3 import android.annotation.SuppressLint;
 4 import android.content.Context;
 5 import android.database.Cursor;
 6 import android.database.sqlite.SQLiteDatabase;
 7 import android.database.sqlite.SQLiteOpenHelper;
 8 
 9 import androidx.annotation.Nullable;
10 
11 import java.util.ArrayList;
12 import java.util.List;
13 
14 public class DBHelper extends SQLiteOpenHelper {
15 
16     private static int DB_VERSION = 1;
17     private static String DB_NAME = "account_daily.db";
18 
19     public DBHelper(Context context) {
20         super(context, DB_NAME ,null, DB_VERSION);
21     }
22 
23     @Override
24     public void onCreate(SQLiteDatabase db) {
25         String sql="create table account(_id integer primary key autoincrement," +//主键
26                 "Title varchar(20)," +//Title
27                 "Date varchar(20)," +//Date
28                 "Money varchar(20))";//Money
29         db.execSQL(sql);
30     }
31 
32     @Override
33     public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
34 
35     }
36     @SuppressLint("Range")
37     public costList getCostListById(int itemId) {
38         SQLiteDatabase db = this.getReadableDatabase();
39         costList item = null;
40 
41         // 查询指定id的记录
42         Cursor cursor = db.query("account", null, "_id = ?", new String[]{String.valueOf(itemId)}, null, null, null);
43 
44         if (cursor != null && cursor.moveToFirst()) {
45             // 构造costList对象
46             item = new costList();
47             item.set_id(cursor.getInt(cursor.getColumnIndex("_id")));
48             item.setTitle(cursor.getString(cursor.getColumnIndex("Title")));
49             item.setDate(cursor.getString(cursor.getColumnIndex("Date")));
50             item.setMoney(cursor.getString(cursor.getColumnIndex("Money")));
51 
52             cursor.close();
53         }
54 
55         db.close();
56 
57         return item;
58     }
59 
60 
61     @SuppressLint("Range")
62     public List<costList> getBillsForDate(String selectedDate) {
63         List<costList> billList = new ArrayList<>();
64         SQLiteDatabase db = this.getReadableDatabase();
65 
66         // 查询 account 表中日期为 selectedDate 的账单数据
67         String[] projection = {"_id", "Title", "Date", "Money"};
68         String selection = "Date = ?";
69         String[] selectionArgs = {selectedDate};
70         Cursor cursor = db.query("account", projection, selection, selectionArgs, null, null, null);
71 
72         // 遍历查询结果,并将每一行数据添加到 billList 中
73         if (cursor != null && cursor.moveToFirst()) {
74             do {
75                 costList bill = new costList();
76                 bill.set_id(cursor.getInt(cursor.getColumnIndex("_id")));
77                 bill.setTitle(cursor.getString(cursor.getColumnIndex("Title")));
78                 bill.setDate(cursor.getString(cursor.getColumnIndex("Date")));
79                 bill.setMoney(cursor.getString(cursor.getColumnIndex("Money")));
80                 billList.add(bill);
81             } while (cursor.moveToNext());
82         }
83 
84         // 关闭 cursor 和数据库连接
85         if (cursor != null) {
86             cursor.close();
87         }
88         db.close();
89 
90         return billList;
91     }
92 
93 }

首先DBHelper类需要继承自SQLiteOpenHelper类以使用父类的方法,我们重写了onCreate方法用于新建数据库表:

String sql="create table account(_id integer primary key autoincrement," +//主键
"Title varchar(20)," +//Title
"Date varchar(20)," +//Date
"Money varchar(20))";//Money 可以看出SQLite数据库语句和mysql数据库语句有很多相似之处,但要注意以下两点:   1. 最大的不同在于创建表时可以不用指定字段类型,Sqlite可以适时的自动转换,但除varchar类型外最好指定类型   2. Sqlite中的主键最名称建议使用_id 我们设置了一个主键_id和账单的标题、日期和金钱,db.execSQL(sql)用于执行我们的数据库语句。 数据库创建完成之后我们同样也写一个对应的数据类型:
 1 package com.example.myapplication3;
 2 
 3 
 4 public class costList  {
 5     private int _id;
 6     private String Title;
 7     private String Date;
 8     private String Money;
 9 
10     public String getMoney() {
11         return Money;
12     }
13 
14     public void setMoney(String money) {
15         Money = money;
16     }
17 
18     public String getDate() {
19         return Date;
20     }
21 
22     public void setDate(String date) {
23         Date = date;
24     }
25 
26     public String getTitle() {
27         return Title;
28     }
29 
30     public void setTitle(String title) {
31         Title = title;
32     }
33 
34     public int get_id() {
35         return _id;
36     }
37 
38     public void set_id(int _id) {
39         this._id = _id;
40     }
41 }

costList类包含简单的get和set方法

 

我们回到DBHelper当中,可以看到在onCreate之前还有一个构造函数,它接受一个Context对象作为参数。Context对象在Android中用于访问应用程序的资源和系统服务,可以理解为上下文环境想进一步了解这里给上链接:https://www.jianshu.com/p/d87314f99a9f 。

在构造函数内部,首先调用了父类SQLiteOpenHelper的构造函数,使用传入的Context对象、数据库名称(DB_NAME)、游标工厂(通常为null,表示使用默认的游标工厂)、数据库版本号(DB_VERSION)作为参数。这里的DB_NAME和DB_VERSION是在该类中定义的常量,分别表示数据库的名称和版本号。通过调用父类的构造函数,实际上是在初始化SQLiteOpenHelper,为后续数据库操作做准备。

后续的两个函数都是功能相关的函数,我们可以看到getCostListById是通过id查找数据库项的一个函数,函数首先新建了一个可读的SQLite数据库,然后新建了一个costList类对象用于返回查找结果,之后便是查询操作,这里有一个Cursor(游标)类用于在数据库查询结果集中进行遍历,并允许以逐行或逐列的方式访问数据。它是一种轻量级的数据容器,通常与SQLite数据库一起使用,用于执行查询操作并获取结果。类似一个结果集。之后就是数据库查询语句

query("account", null, "_id = ?", new String[]{String.valueOf(itemId)}, null, null, null);
  1. 表名 ("account"): 这是要查询的数据库表的名称。在这个例子中,我们希望从名为"account"的表中检索数据。

  2. 要返回的列(null): 第二个参数是要返回的列的数组,如果为null,则表示查询返回所有列。在这里,我们传入了null,表示我们想要返回表中的所有列。

  3. 查询条件 ("_id = ?"): 这是一个查询条件,用于筛选数据。在这个例子中,我们使用了一个占位符("?"),表示我们希望检索"_id"列的值等于特定的itemId。这个查询条件可以防止SQL注入攻击,并且通过占位符的方式,我们可以安全地传入参数值。

  4. 查询条件参数数组 (new String[]{String.valueOf(itemId)}): 这个参数是一个字符串数组,包含了查询条件中的占位符所对应的实际值。在这里,我们使用String.valueOf(itemId)将itemId转换为字符串,并将其作为查询条件的参数传入。

  5. 分组方式 (null): 在此处为null,表示不需要对结果进行分组。

  6. 分组过滤条件 (null): 在此处为null,表示不需要对分组后的结果进行筛选。

  7. 排序方式 (null): 在此处为null,表示不需要对结果进行排序。

这里给出query的原函数:

 1 SQLiteDatabase db = dbHelper.getReadableDatabase();
 2  
 3 //要查询的列名
 4 String[] projection = {
 5     BaseColumns._ID,
 6     FeedEntry.COLUMN_NAME_TITLE,
 7     FeedEntry.COLUMN_NAME_SUBTITLE
 8     };
 9  
10 //查询条件
11 String selection = FeedEntry.COLUMN_NAME_TITLE + " = ?";
12 String[] selectionArgs = { "My Title" };
13  
14 //按照某个列排序
15 String sortOrder =
16    FeedEntry.COLUMN_NAME_SUBTITLE + " DESC";
17  
18 Cursor cursor = db.query(
19     FeedEntry.TABLE_NAME,   // 表明
20     projection,             // 要查询的列数据
21     selection,              // 条件语句
22     selectionArgs,          // 条件语句的值
23     null,                   
24     null,                   
25     sortOrder               // 排序语句
26     );

在查询之后我们通过cursor的方法去获取对应的数据,最后将资源释放。

 至于下面那个根据日期查询对应的账单的方法和这个类似,只是这个是costList的数组类型。

 

当然推荐数据库相关的操作都应该封装到helper当中,我为了简单就没有将方法进行封装,自己可以动手封装一下试试。

标签:SQLite,String,数据库,public,cursor,记账,Android,null,id
From: https://www.cnblogs.com/qmz-znv2/p/18021186

相关文章

  • 踩坑小计-Android Flutter应用设置沉浸式状态栏
    之前写过一篇关于设置Flutter页面沉浸式状态栏的文章。https://www.cnblogs.com/mrhan9941/p/16482604.html主要是基于Flutterboost的原生Android项目的,那时候是在原生Android项目嵌入了FlutterModule。项目重构后已经改为纯Flutter项目,确发现一个小问题,沿用之前的设置沉浸式状......
  • SQLite、MySQL和PostgreSQL的区别
    SQLite、MySQL和PostgreSQL都是广泛使用的开源关系型数据库管理系统(RDBMS),但它们在设计目标、适用场景和功能特性上各有特点:SQLite:简介:SQLite是一个轻量级的嵌入式数据库引擎,它不需要独立服务器进程就可以运行。SQLite数据库文件直接存储在磁盘上,应用程序通过API直接与数据库......
  • andorid开发--记账本(四)
    主要是开发收支页面的每一项与头布局绘制,并且将记录页面的绘制完成头布局绘制,以及每一项的绘制头布局iteam_mainlv-top.xml<?xmlversion="1.0"encoding="utf-8"?><LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:orientation="v......
  • Android家庭记账本开发第三天:MainActivity主界面逻辑文件
    昨天讲了主界面的xml文件的布局,这里讲一下对应的主界面的Java文件,首先上代码:1packagecom.example.myapplication3;23importandroid.annotation.SuppressLint;4importandroid.content.Intent;5importandroid.database.Cursor;6importandroid.databas......
  • 家庭记账本软件
    家庭记账本软件(欲实现功能):家庭财务管理:许多家庭需要有效地管理他们的财务状况,包括收入和支出的记录、统计和分析。该软件提供了一个方便的平台,让家庭成员能够轻松地记录和管理他们的财务信息。方便记录消费:家庭记账本软件可以帮助用户快速记录消费信息,包括支出和收入,避免遗漏和......
  • andorid开发--记账本(三)
    今天简单做了布局的绘制<?xmlversion="1.0"encoding="utf-8"?><RelativeLayoutxmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="ht......
  • Android家庭记账本开发第二天:activity_main布局文件
    本次开发记录是在开发完成之后记录的,所以能写几篇我也不知道,可能没有十篇,将这次的开发记录作为一次知识点复习的机会。开发完成之后的目录如下安卓开发相较于之前进行的Javaweb开发难度要高上不少,因为之前的都是通过tomcat服务器去运行,我们只需要将对应的页面完善好就行,但是安......
  • Android家庭记账本开发第一天:Android studio与gradle安装
    首先记录一下Androidstudio与gradle的安装,工具相较于IDEA和pycharm安装过程很麻烦。官网地址:https://developer.android.google.cn/studio?hl=zh-cn本次安装示例在虚拟机中运行首先在官网中点击下载,得到安装程序,双击打开这里会选择安装位置,自己选择一个安装位置即可,我这里......
  • ## AndroidStudio安装和环境配置
    利用网盘资源,下载所需的sdk和AndroidStudio链接:https://pan.baidu.com/s/1d-7jRWhHwBU8DaustdJvVA提取码:8xec第一步:新建一个androidstudio,在这个文件夹下新建sdk,studio,work,第二步,运行安装包,在资料里面。点击next默认全选,点击next点击IAgree下一步直到安装到你新......
  • Android 未root时 文件的selinux权限和日志查看办法
     getenforce 获取当前SELinux状态cas:/$getenforceEnforcingdmesg可以查看日志,但是没有root权限不能用,会显示cas:/$dmesgdmesg:klogctl:Permissiondeniedhttps://android.stackexchange.com/questions/218223/how-to-fix-dmesg-klogctl-permission-denied-for-nor......