当前位置: 首页 > news >正文

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

文章目录

  • 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

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

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) {}
}

进一步补充:

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 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 数据库

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),这个方法都会被调用,以便你可以对数据库进行必要的升级操作。

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {// 这里编写数据库升级的代码
}
@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 方法将会被调用。

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

相关知识点

ContentValues 类

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

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

public long insert(String table, String nullColumnHack, ContentValues values)

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

// 创建一个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

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • C语言数据在内存中的存储超详解
  • nacos 2.3.2 若依使用mysql
  • 智慧环卫可视化:科技赋能城市清洁管理
  • Java--二,十,十六进制间的相互转换
  • 【初阶数据结构篇】归并排序和计数排序(总结篇)
  • Python面试题:结合Python技术,如何使用Scrapy构建爬虫框架
  • [极客大挑战 2019]Secret File-web
  • 校园点餐系统
  • java算法递归算法练习-数组之和
  • 快速部署私有化大模型 毕昇(使用docker-compose方式)
  • Opencv threshold函数、adaptiveThreshold函数详解和示例
  • 【力扣】SQL题库练习5
  • actual combat 38 ——vue
  • 【C#】.net core 6.0 webapi 使用core版本的NPOI的Excel读取数据以及保存数据
  • 零基础学python 之 第十九讲 正则表达式
  • 【干货分享】SpringCloud微服务架构分布式组件如何共享session对象
  • 【刷算法】求1+2+3+...+n
  • 【译】理解JavaScript:new 关键字
  • Dubbo 整合 Pinpoint 做分布式服务请求跟踪
  • Eureka 2.0 开源流产,真的对你影响很大吗?
  • JavaScript中的对象个人分享
  • Laravel 中的一个后期静态绑定
  • Mybatis初体验
  • mysql 数据库四种事务隔离级别
  • PHP面试之三:MySQL数据库
  • React 快速上手 - 07 前端路由 react-router
  • 编写符合Python风格的对象
  • 开放才能进步!Angular和Wijmo一起走过的日子
  • 力扣(LeetCode)56
  • 排序(1):冒泡排序
  • 前端 CSS : 5# 纯 CSS 实现24小时超市
  • 强力优化Rancher k8s中国区的使用体验
  • C# - 为值类型重定义相等性
  • linux 淘宝开源监控工具tsar
  • 容器镜像
  • 如何在招聘中考核.NET架构师
  • ​软考-高级-信息系统项目管理师教程 第四版【第14章-项目沟通管理-思维导图】​
  • # 数仓建模:如何构建主题宽表模型?
  • #{}和${}的区别是什么 -- java面试
  • (echarts)echarts使用时重新加载数据之前的数据存留在图上的问题
  • (接口封装)
  • (蓝桥杯每日一题)love
  • (免费领源码)python#django#mysql公交线路查询系统85021- 计算机毕业设计项目选题推荐
  • (一)SvelteKit教程:hello world
  • (转)LINQ之路
  • ****** 二 ******、软设笔记【数据结构】-KMP算法、树、二叉树
  • .htaccess配置常用技巧
  • .NET I/O 学习笔记:对文件和目录进行解压缩操作
  • .Net IOC框架入门之一 Unity
  • .NET/ASP.NETMVC 大型站点架构设计—迁移Model元数据设置项(自定义元数据提供程序)...
  • .NET设计模式(7):创建型模式专题总结(Creational Pattern)
  • .Net通用分页类(存储过程分页版,可以选择页码的显示样式,且有中英选择)
  • ??eclipse的安装配置问题!??
  • @Bean注解详解
  • @html.ActionLink的几种参数格式