【Android】数据存储之SQLite数据库知识总结

news/2025/3/14 17:54:33/

文章目录

  • SQL
    • 数据类型
    • 创建表格
    • 删除表格
    • 修改表格
  • 数据库管理器SQLiteDatabase
    • 数据库的创建与删除
  • SQLiteOpenHelper
    • 使用步骤
      • 新建数据库操作类
      • 增删改查方法
      • 使用 SQLite 数据库
      • 版本更新
  • 相关知识点
    • ContentValues 类
    • Cursor

SQL

SQL本质上是一种编程语言,它的学名叫作"结构化查询语言”(全称为structured QueryLanguage,简称SQL)。不过SQL语言并非通用的编程语言,它专用于数据库的访问和处理,更像是一种操作命令,所以常说SQL语句而不说SQL代码。

数据类型

SQLite 主要支持以下几种数据类型:

  • INTEGER:用于存储整型数据,通常用于存储布尔值(0 表示 false1 表示 true)。
  • REAL:用于存储浮点数。
  • TEXT:用于存储字符串数据。
  • BLOB:用于存储二进制大对象。

创建表格

CREATE IF NOT EXISTS 表格名称;

CREATE TABLE IF NOT EXISTS table_name (column1 datatype constraints,column2 datatype constraints,...
);

删除表格

DROP TABLE IF EXISTS user_info

修改表格

ALTER TABLE user info ADD COLUMN phone VARCHAR;

数据库管理器SQLiteDatabase

QLiteDatabase是SQLite的数据库管理类,它提供了若干操作数据表的API

  • 管理类,用于数据库层面的操作
  1. openDatabase:打开指定路径的数据库,
  2. isOpen:判断数据库是否已打开。
  3. close:关闭数据库。
  4. getVersion:获取数据库的版本号。
  5. setVersion:设置数据库的版本号,
  • 事务类,用于事务层面的操作。
  1. beginTransaction:开事务。
  2. setTransactionSuccessful:设置事务的成功标志。
  3. endTransaction:结束事务。
  • 数据处理类,用于数据表层面的操作。
  1. execSQL:执行拼接好的SQL控制语句。
  2. delete:删除符合条件的记录。
  3. update:更新符合条件的记录。
  4. insert:插入一条记录。
  5. query:执行查询操作,返回结果集的游标。
  6. rawQuery:执行拼接好的SQL查询语句,返回结果集的游标。

数据库的创建与删除

使用openOrCreateDatabasedeleteDatabase

image-20240731161828251

java">public class MainActivity extends AppCompatActivity implements View.OnClickListener {private String mDatabaseName;private TextView tv1;private Button btn1;private Button btn2;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);btn1 = findViewById(R.id.button1);btn2 = findViewById(R.id.button2);tv1 = findViewById(R.id.textView1);btn1.setOnClickListener(this);btn2.setOnClickListener(this);//生成数据库完整路径mDatabaseName = getFilesDir() + "/test.db";}@Overridepublic void onClick(View v) {String desc;if (v.getId() == R.id.button1) {//创建或打开数据库,不存在就创建SQLiteDatabase db = openOrCreateDatabase(mDatabaseName, Context.MODE_PRIVATE, null);desc = String.format("数据库%s创建%s", db.getPath(), (db == null) ? "失败" : "成功");tv1.setText(desc);} else if (v.getId() == R.id.button2) {boolean result = deleteDatabase(mDatabaseName);desc = String.format("数据库%s删除%s", mDatabaseName, (result) ? "成功" : "失败");tv1.setText(desc);}}
}

SQLiteOpenHelper

SQLiteOpenHelper类:用于创建或打开数据库的辅助类
SQLiteOpenHelper类是一个抽象类,包含两个重要的方法:

  • onCreate(SQLiteDatabase db):新建数据库时调用

  • onUpgrade(SQLiteDatabase db,int oldVersion,int newVersion):数据库版本升级时调用

image-20240730201510116

使用步骤

  1. 新建一个继承自SQLiteOpenHelper的数据库操作类,提示重写onCreateonUpgrade两个方法
  2. 封装保证数据库安全的必要方法。
  3. 提供对表记录进行增加、删除、修改、查询的操作方法。

新建数据库操作类

实现效果:

Screenshot_2024-07-31-19-13-42-327_com.example.sq

java">public class UserDBHelper extends SQLiteOpenHelper {private static final String DB_NAME = "user.db";private static final int DB_VERSION = 1;public UserDBHelper(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {super(context, DB_NAME, null, DB_VERSION);// 该类的构造方法由于参数太多,我们可以在`super()`中传入自己设置的固定参数// context: 上下文对象,用于访问应用环境// DB_NAME: 数据库名称// null: 游标工厂,可以为null,表示使用默认的游标工厂// DB_VERSION: 数据库版本号,用于管理数据库的版本和升级}// 创建数据库,执行建表语句@Overridepublic void onCreate(SQLiteDatabase db) {String sql = "";db.execSQL(sql);}@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {}
}

进一步补充:

java">public class UserDBHelper extends SQLiteOpenHelper {private static final String DB_NAME = "user.db";private static final String TABLE_NAME = "user_info";private static final int DB_VERSION = 1;private static UserDBHelper mHelper = null;private SQLiteDatabase mRDB = null;private SQLiteDatabase mWDB = null;private UserDBHelper(Context context) {super(context, DB_NAME, null, DB_VERSION);// 该类的构造方法由于参数太多,我们可以在`super()`中传入自己设置的固定参数// context: 上下文对象,用于访问应用环境// DB_NAME: 数据库名称// null: 游标工厂,可以为null,表示使用默认的游标工厂// DB_VERSION: 数据库版本号,用于管理数据库的版本和升级}//利用单例模式获取数据库帮助器的唯一实例public static UserDBHelper getInstance(Context context) {if (mHelper == null) {mHelper = new UserDBHelper(context);}return mHelper;}// 打开数据库的读链接public SQLiteDatabase openReadLink() {if (mRDB == null || !mRDB.isOpen()) {mRDB = mHelper.getReadableDatabase();}return mRDB;}// 打开数据库的写链接public SQLiteDatabase openWriteLink() {if (mWDB == null || !mWDB.isOpen()) {mWDB = mHelper.getWritableDatabase();}return mWDB;}//关闭数据库链接public void closeLink() {if (mWDB != null && mWDB.isOpen()) {mWDB.close();mWDB = null;}if (mRDB != null && mRDB.isOpen()) {mRDB.close();mRDB = null;}}// 创建数据库,执行建表语句@Overridepublic void onCreate(SQLiteDatabase db) {String sql = "CREATE TABLE IF NOT EXISTS " + TABLE_NAME + " (" +"id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, " +"name TEXT NOT NULL, " +"age INTEGER NOT NULL, " +"height REAL NOT NULL, " +"weight REAL NOT NULL);";db.execSQL(sql);}@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {}
}

增删改查方法

java">public class UserDBHelper extends SQLiteOpenHelper {private static final String DB_NAME = "user.db";private static final String TABLE_NAME = "user_info";private static final int DB_VERSION = 1;private static UserDBHelper mHelper = null;private SQLiteDatabase mRDB = null;private SQLiteDatabase mWDB = null;private UserDBHelper(Context context) {super(context, DB_NAME, null, DB_VERSION);// 该类的构造方法由于参数太多,我们可以在`super()`中传入自己设置的固定参数// context: 上下文对象,用于访问应用环境// DB_NAME: 数据库名称// null: 游标工厂,可以为null,表示使用默认的游标工厂// DB_VERSION: 数据库版本号,用于管理数据库的版本和升级}//利用单例模式获取数据库帮助器的唯一实例public static UserDBHelper getInstance(Context context) {if (mHelper == null) {mHelper = new UserDBHelper(context);}return mHelper;}// 打开数据库的读链接public SQLiteDatabase openReadLink() {if (mRDB == null || !mRDB.isOpen()) {mRDB = mHelper.getReadableDatabase();}return mRDB;}// 打开数据库的写链接public SQLiteDatabase openWriteLink() {if (mWDB == null || !mWDB.isOpen()) {mWDB = mHelper.getWritableDatabase();}return mWDB;}//关闭数据库链接public void closeLink() {if (mWDB != null && mWDB.isOpen()) {mWDB.close();mWDB = null;}if (mRDB != null && mRDB.isOpen()) {mRDB.close();mRDB = null;}}// 创建数据库,执行建表语句@Overridepublic void onCreate(SQLiteDatabase db) {String sql = "CREATE TABLE IF NOT EXISTS " + TABLE_NAME + " (" +"id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, " +"name TEXT NOT NULL, " +"age INTEGER NOT NULL, " +"height REAL NOT NULL, " +"weight REAL NOT NULL);";db.execSQL(sql);}@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {}public long insert(User user) {ContentValues values = new ContentValues();values.put("name", user.getName());values.put("age", user.getAge());values.put("height", user.getHeight());values.put("weight", user.getWeight());return mWDB.insert(TABLE_NAME, null, values);}public long delete(String name) {return mWDB.delete(TABLE_NAME, "name = ?", new String[]{name});}public long update(User user) {ContentValues values = new ContentValues();values.put("name", user.getName());values.put("age", user.getAge());values.put("height", user.getHeight());values.put("weight", user.getWeight());return mWDB.update(TABLE_NAME, values, "name = ?", new String[]{user.getName()});}public List<User> queryAll() {List<User> list = new ArrayList<>();Cursor cursor = mRDB.query(TABLE_NAME, null, null, null, null, null, null);while(cursor.moveToNext()){User user = new User();user.setId(cursor.getInt(0));user.setName(cursor.getString(1));user.setAge(cursor.getInt(2));user.setHeight(cursor.getLong(3));user.setWeight(cursor.getFloat(4));list.add(user);}return list;}
}

使用 SQLite 数据库

java">public class SecondActivity extends AppCompatActivity implements View.OnClickListener {private EditText editName, editAge, editHeight, editWeight;private Button btnAdd, btnDelete, btnUpdate, btnQuery;private SQLiteDatabase db;private UserDBHelper mDBHelper;private TextView textView2;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_second);textView2 = findViewById(R.id.textView2);editName = findViewById(R.id.editName);editAge = findViewById(R.id.editAge);editHeight = findViewById(R.id.editHeight);editWeight = findViewById(R.id.editWeight);btnAdd = findViewById(R.id.buttonAdd);btnDelete = findViewById(R.id.buttonDelete);btnUpdate = findViewById(R.id.buttonUpdate);btnQuery = findViewById(R.id.buttonQuery);btnAdd.setOnClickListener(this);btnDelete.setOnClickListener(this);btnUpdate.setOnClickListener(this);}@Overrideprotected void onStart() {super.onStart();//获得数据库帮助器示例mDBHelper = UserDBHelper.getInstance(this);//打开数据库帮助器读写连接mDBHelper.openWriteLink();mDBHelper.openReadLink();}@Overrideprotected void onStop() {super.onStop();// 关闭数据库帮助器读写连接mDBHelper.closeLink();}@Overridepublic void onClick(View v) {String name = editName.getText().toString();int age = Integer.parseInt(editAge.getText().toString());long height = Long.parseLong(editHeight.getText().toString());float weight = Float.parseFloat(editWeight.getText().toString());if (v.getId() == R.id.buttonAdd) {User user = new User(name, age, height, weight);if (mDBHelper.insert(user) > 0) {Toast.makeText(this, "添加成功", Toast.LENGTH_SHORT).show();}} else if (v.getId() == R.id.buttonDelete) {if (mDBHelper.delete(name) > 0) {Toast.makeText(this, "删除成功", Toast.LENGTH_SHORT).show();}} else if (v.getId() == R.id.buttonUpdate) {User user = new User(name, age, height, weight);if (mDBHelper.update(user) > 0) {Toast.makeText(this, "修改成功", Toast.LENGTH_SHORT).show();}}}public void query(View view) {List<User> userList = mDBHelper.queryAll();StringBuilder sb = new StringBuilder();for (User user : userList) {sb.append(user.toString());sb.append("\n");}textView2.setText(sb.toString());Toast.makeText(this, "查询成功", Toast.LENGTH_SHORT).show();}
}

版本更新

onUpgrade 方法是 SQLiteOpenHelper 类中的一个回调方法,用于处理数据库版本升级时的逻辑。每当你更新数据库的版本号时(通过改变 DB_VERSION),这个方法都会被调用,以便你可以对数据库进行必要的升级操作。

java">@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {// 这里编写数据库升级的代码
}
java">@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {if (oldVersion < 2) {// 在版本 2 中添加一个新列String sql = "ALTER TABLE " + TABLE_NAME + " ADD COLUMN password VARCHAR";db.execSQL(sql);}// 如果有更多的版本升级逻辑,可以继续添加 else if 或其他条件
}

当改变 SQLiteOpenHelperDB_VERSION 常量并重新启动应用时,onUpgrade 方法将会被调用。

java">private static final int DB_VERSION = 2; // 更新版本号

相关知识点

ContentValues 类

ContentValues类用于存储一组键值对,其中每个键(key)对应一个值(value),通常用于插入或更新数据库中的记录。

SQLiteDatabase类中,insert方法的签名如下:

java">public long insert(String table, String nullColumnHack, ContentValues values)

values:包含要插入的数据的ContentValues对象。每个键是列名,每个值是对应列的值。

java">// 创建一个ContentValues对象
ContentValues values = new ContentValues();
values.put("name", "John Doe"); // 设置列“name”的值
values.put("age", 30);          // 设置列“age”的值

getXxx()put()

Cursor

数据结构,用于访问数据库查询结果的数据集合。它主要用于从ContentProvider中读取数据,也可以用于直接与SQLite数据库交互。Cursor对象提供了一种机制,可以按行逐条读取数据,并从中获取具体的字段值。

  1. 特点

数据集合Cursor表示数据库查询结果中的行集合,每行表示一条记录。

定位:可以使用Cursor的方法来定位到特定的行。常用的方法包括moveToFirst(), moveToNext(), moveToLast(), 和 moveToPosition(int position)

列名和数据类型:在访问数据时,你需要知道每一列的名称或索引,以便正确地获取数据。你还需要知道列的数据类型,以便适当地转换数据类型。

随机访问Cursor支持在数据集中随机访问,允许你通过行号(索引)来获取数据。

  1. 主要方法
  • 移动游标
    • moveToFirst(): 将游标移动到结果集的第一行。如果结果集为空,则返回false
    • moveToNext(): 将游标移动到下一行。如果已到达结果集的末尾,则返回false
  • 读取数据
    • getString(int columnIndex): 获取指定列索引的字符串数据。
    • getInt(int columnIndex): 获取指定列索引的整数数据。
  • 列信息
    • getColumnIndex(String columnName): 根据列名获取列索引。
    • getColumnName(int columnIndex): 根据列索引获取列名。
    • getColumnCount(): 获取结果集中列的数量。
    • getCount(): 获取结果集中的行数。
  • 关闭游标
    • close(): 关闭Cursor对象,释放相关资源。应在完成对Cursor的操作后调用。

image-20240730200227483



感谢您的阅读
如有错误烦请指正


参考:

  1. 67-SQL基本语法_哔哩哔哩_bilibili

http://www.ppmy.cn/news/1503597.html

相关文章

群晖NAS结合内网穿透工具实现远程连接内网SFTP服务传输文件

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

SAP ERP 通过SAP PO LDAP适配器与微软AD域服务系统集成案例

一、客户介绍 上海某芯片制造公司的主要产品应用于图像传感器、 图像信号处理芯片、 低功耗芯片、 射频芯片等。专注集成电路技术开发与制造&#xff0c;服务于图像传感器、图形图像信号处理芯片、低功耗芯片、射频芯片等领域的全球客户。 二、项目需求 该企业内部办公电…

一文看懂Java反射、注解、UML图和Lambda表达式

反射 定义: 反射是 java 开发语言的特征之一&#xff0c;它允许 java 程序对自身进行检查(自审)&#xff0c;并能直接操作程序内部属性&#xff0c;即就是将类中的各种成分映射成一个 java 对象&#xff0c;利用反射技术可以对一个类进行解剖&#xff0c;将各个组成部分映射成…

LinkedList 实现 LRU 缓存

LRU&#xff08;Least Recently Used&#xff0c;最近最少使用&#xff09;缓存是一种缓存淘汰策略&#xff0c;用于在缓存满时淘汰最久未使用的元素。 关键&#xff1a; 缓存选什么结构&#xff1f; 怎么实现访问顺序&#xff1f; import java.util.*;public class LRUCac…

第十九天培训笔记

上午 1 、构建 vue 发行版本 [rootserver eleme_web]# nohup npm run serve& // 运行 vue 项目 [rootserver eleme_web]# mkdir /eleme [rootserver eleme_web]# cp -r /root/eleme_web/dist/* /eleme/ // 将项目整体 移动到 /eleme 目录下 [rootserver eleme_web]# …

vue3实现面包屑-基础实现

1.在默认路由router文件下新增两个额外的文件page&#xff1a;存放额外的路由列表&#xff0c;注意这里需要引入有router-view视图的页面&#xff0c;这里我是采用let Main () > import("v/layout/Main.vue");代码&#xff1a; 在page中使用&#xff1a; 2.dyna…

vscode+platformio开发小技巧

使用vscodeplatformio开发&#xff0c;具体安装配置文章很多&#xff0c;这里分享一些方便使用的小技巧&#xff0c;让使用体验在不增加学习成本的情况下更加丝滑。 1、配置依赖库 在使用vscode开发前&#xff0c;arduino环境遗留了一些库文件&#xff0c;这些第三方库可以通…

Spring-Ioc,Di,Bean

博客主页&#xff1a;音符犹如代码系列专栏&#xff1a;JavaWeb关注博主&#xff0c;后期持续更新系列文章如果有错误感谢请大家批评指出&#xff0c;及时修改感谢大家点赞&#x1f44d;收藏⭐评论✍ 目录 IOC DI Bean 在上一期我们给大家讲解了三层架构和分层解耦&#xff…