Android 系统集成了一个轻量级的关系数据库—— SQLite。其优点是占用资源少,运行效率高、安全可靠、可移植性强,并且提供零配
置运行模式,适用于在资源有限的设备(如手机和平板电脑等)上进行数据存取。
在开发手机应用时,一般会通过代码来动态创建数据库,即在程序运行时,首先尝试打开数据库,如果数据库不存在,则自动创建该数据库,然后再打开数据库。下面介绍如何通过代码来创建以及操作数据库。

一、数据库的创建

在 Android 的 SQLite 数据库中,提供了两种创建数据库的方法,分别是:
方法一:SQLiteDatabase 提供了openOrCreateDatabase() 方法来打开或创建一个数据库,语法如下:

static SQLiteDatabase openOrCreateDatabase(String path, SQLiteDatabase.CursorFactory factory)

例如,使用 openOrCreateDatabase() 方法创建一个名称为 user.db 的数据库的代码如下:

SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase("user.db", null);

方法二: 通过 SQLiteOpenHelper 类创建数据库在 Android 中,提供了一个数据库辅助类 SQLiteOpenHelper。在该类的构造器中,调用Context 中的方法创建并打开一个指定名称的数据库。我们在应用这个类时,需要编写继承自SQLiteOpenHelper 类的子类,并且重写 onCreate() 和 onUpgrade() 方法。

本例着重介绍方法二的使用。
我们创建一个SQLiteOpenHelper的子类MySQLiteOpenHelper。代码如下:

MySQLiteOpenHelper.java

package com.example.mydemo;import android.content.Context;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteOpenHelper;import androidx.annotation.Nullable;public class MySQLiteOpenHelper extends SQLiteOpenHelper {         private static final String DATABASE_NAME = "noteBase.db";    private static final int VERSION = 1;    //这是一条数据库常用语句,用于创建一个新表    private static final String table =            "create table " + DBSchema.TABLE_NAME +"("+            "_id integer primary key autoincrement,"+            DBSchema.UUID+","+            DBSchema.CONTENT+","+            DBSchema.DATE+")";    public MySQLiteOpenHelper(@Nullable Context context) {         //重写构造方法并设置工厂为null        super(context, DATABASE_NAME, null, VERSION);    }    @Override    public void onCreate(SQLiteDatabase db) {             //下面的语句会执行数据库语句创建新表        db.execSQL(table);    }    @Override    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {         }    public static class DBSchema{             public static final String TABLE_NAME = "custom";        public static final String UUID = "uuid";        public static final String CONTENT = "content";        public static final String DATE = "date";    }}

二、增删改查的使用

SQLiteDatabase 类提供了 insert(……)(增)、update(……)(改)、delete(……) (删)和 query(……)(查) 方法,这些方法封装了执行增删改查操作的 SQL 命令,所以我们可以使用这些方法来完成对应的操作,而不用去编写 SQL 语句了。

(1)添加操作
SQLiteDatabase 类提供了 insert() 方法用于向表中插入数据。insert() 方法的基本语法格式如下:

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

◆ table:用于指定表名。
◆ nullColumnHack:可选的,用于指定当 values 参数为空时,将哪个字段设置为 null,如果values 不为空,则该参数值可以设置为 null。
◆ values:用于指定具体的字段值,它相当于 Map 集合,也是通过键值对的形式存储值的。

(2)更新操作
SQLiteDatabase 类提供了 update() 方法用于更新表中的数据。update() 方法的基本语法格式如下:

public int update(String table, ContentValues values, String whereClause, String[] whereArgs) 

◆ table:用于指定表名。
◆ values:用于指定要更新的字段及对应的字段值,它相当于 Map 集合,也是通过键值对的形式存储值的。
◆ whereClause:用于指定条件语句,可以使用占位符(?)。
◆ whereArgs:当条件表达式中包含占位符(?)时,该参数用于指定各占位参数的值。如果不包括占位符,该参数值可以设置为 null。

(3)删除操作
SQLiteDatabase 类提供了 delete() 方法用于从表中删除数据。delete() 方法的基本语法格式如下:

public int delete(String table, String whereClause, String[] whereArgs)

◆ table:用于指定表名。
◆ whereClause:用于指定条件语句,可以使用占位符(?)。
◆ whereArgs:当条件表达式中包含占位符(?)时,该参数用于指定各占位参数的值。如果不包括占位符,该参数值可以设置为 null。

(4)查询操作
SQLiteDatabase 类提供了 query() 方法用于查询表中的数据。query() 方法的基本语法格式如下:

public Cursor query( String table, String[] columns, String selection, String[] selectionArgs, String groupBy,String having,String orderBy,String limit);

◆ table:用于指定表名。
◆ columns:用于指定要查询的列。若为空,则返回所有列。
◆ selection:用于指定 where 子句,即指定查询条件,可以使用占位符(?)。
◆ selectionArgs:where 子句对应的条件值,当条件表达式中包含占位符(?)时,该参数用于指定各占位参数的值。如果不包括占位符,该参数值可以设置为 null。
◆ groupBy:用于指定分组方式。
◆ having:用于指定 having 条件。
◆ orderBy:用于指定排序方式,为空表示采用默认排序方式。
◆ limit:用于限制返回的记录条数,为空表示不限制。query() 方法的返回值为 Cursor 对象。该对象中保存着查询结果,但是这个结果并不是数据集合的完整复制,而是数据集的指针。通过它提供的多种移动方式,我们可以获取数据集合中的数据。
Cursor 类提供的常用方法如下表所示:

这里演示一个实例作为参考:

下面贴出源码:
MySQLiteOpenHelper.java与上面数据库的创建方法二相同,不在赘述。

Note.java

package com.example.mydemo;import java.util.Date;import java.util.UUID;public class Note {         //给每个Note实例添加加一个唯一识别码,这个是独一无二的    private String uuId;    private String content;    private Date date;    public Note() {             this.date = new Date();        uuId = UUID.randomUUID().toString();    }    public void setUuId(String uuId) {             this.uuId = uuId;    }    public String getUuId() {             return uuId;    }    public String getContent() {             return content;    }    public void setContent(String content) {             this.content = content;    }    public Date getDate() {             return date;    }    public void setDate(long date) {             this.date = new Date(date);    }}

NoteLab .java

package com.example.mydemo;import android.content.ContentValues;import android.content.Context;import android.database.Cursor;import android.database.sqlite.SQLiteDatabase;import android.util.Log;import java.util.ArrayList;import java.util.List;public class NoteLab {         private static NoteLab sNoteLab;    private SQLiteDatabase database ;    //用于暂存数据库的数据    private List<Note> notes;    //留给外界的接口,用于得到NoteLab实例    public static NoteLab createNoteLab(Context context){             if (sNoteLab == null){                 sNoteLab = new NoteLab(context);        }        return sNoteLab;    }    //构造方法私有,使得只能通过createNoteLab(……)方法创建NoteLab实例    private NoteLab(Context context) {             database = new MySQLiteOpenHelper(context).getWritableDatabase();        updateNotes();    }    //插入数据    public  void addData(Note note) {             ContentValues values = getValues(note);        database.insert(MySQLiteOpenHelper.DBSchema.TABLE_NAME,null,values);        updateNotes();    }    //查询数据    public List<Note> queryData(String whereClause,String[] whereArgs) {             Cursor cursor = database.query(                MySQLiteOpenHelper.DBSchema.TABLE_NAME,                null,                whereClause,                whereArgs,                null,                null,                null        );        List<Note> notes = new ArrayList<>();        cursor.moveToFirst();        try{                 while (!cursor.isAfterLast()){                     notes.add(getNote(cursor));                cursor.moveToNext();            }        }        finally {                 cursor.close();        }        return notes;    }    //在查询数据是使用,用于返回Note实例    private Note getNote(Cursor cursor) {             Note note = new Note();        String uuId = cursor.getString(cursor.getColumnIndex(MySQLiteOpenHelper.DBSchema.UUID));        String content = cursor.getString(cursor.getColumnIndex(MySQLiteOpenHelper.DBSchema.CONTENT));        long date = cursor.getLong(cursor.getColumnIndex(MySQLiteOpenHelper.DBSchema.DATE));        note.setUuId(uuId);        note.setContent(content);        note.setDate(date);        return note;    }    //更新数据    public void updateDate(int position,String content) {             Note note = notes.get(position);        note.setContent(content);        ContentValues values = getValues(note);        database.update(                MySQLiteOpenHelper.DBSchema.TABLE_NAME,                values,                MySQLiteOpenHelper.DBSchema.UUID + "= ?",                new String[]{     note.getUuId()}        );        updateNotes();    }    //删除数据    public void deleteData(int position) {             Note note = notes.get(position);        database.delete(                MySQLiteOpenHelper.DBSchema.TABLE_NAME,                MySQLiteOpenHelper.DBSchema.UUID + "= ?",                new String[]{     note.getUuId()}                );//        database.delete(MySQLiteOpenHelper.DBSchema.TABLE_NAME,null,null);        Log.i("删除数据", "deleteData: "+position);        updateNotes();    }    //返回一个ContentValues实例,方便插入和更新数据使用    private ContentValues getValues(Note note) {             ContentValues values = new ContentValues();        String uuId = note.getUuId();        String content = note.getContent();        long date = note.getDate().getTime();        values.put(MySQLiteOpenHelper.DBSchema.UUID,uuId);        values.put(MySQLiteOpenHelper.DBSchema.CONTENT,content);        values.put(MySQLiteOpenHelper.DBSchema.DATE,date);        return values;    }    //用于更新暂存数据库的数据实例notes    private void updateNotes() {             notes = queryData(null,null);    }}

activity_main.xml

<?xml version="1.0" encoding="utf-8"?><androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:app="http://schemas.android.com/apk/res-auto"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:background="#E2DFDF"    tools:context=".MainActivity">    <TextView        android:id="@+id/tv_date"        android:layout_width="0dp"        android:layout_height="wrap_content"        android:layout_marginStart="5dp"        android:layout_marginLeft="5dp"        android:layout_marginTop="5dp"        android:layout_marginEnd="5dp"        android:layout_marginRight="5dp"        android:background="#ffffff"        android:text="/????????????????/"        android:textSize="20sp"        app:layout_constraintBottom_toBottomOf="@+id/textView"        app:layout_constraintEnd_toEndOf="parent"        app:layout_constraintStart_toEndOf="@+id/textView"        app:layout_constraintTop_toTopOf="parent" />    <TextView        android:id="@+id/textView"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_marginStart="5dp"        android:layout_marginLeft="5dp"        android:layout_marginTop="5dp"        android:text="日期:"        android:textSize="30sp"        app:layout_constraintStart_toStartOf="parent"        app:layout_constraintTop_toTopOf="parent" />    <EditText        android:id="@+id/et_content"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:layout_marginStart="5dp"        android:layout_marginLeft="5dp"        android:layout_marginTop="10dp"        android:layout_marginEnd="5dp"        android:layout_marginRight="5dp"        android:background="#ffffff"        android:hint="请输入内容 !"        android:textSize="30sp"        app:layout_constraintEnd_toEndOf="parent"        app:layout_constraintStart_toStartOf="parent"        app:layout_constraintTop_toBottomOf="@+id/tv_date"        tools:ignore="MissingConstraints" />    <EditText        android:id="@+id/et_flag"        android:layout_width="0dp"        android:layout_height="wrap_content"        android:background="#ffffff"        android:gravity="center"        android:textSize="30sp"        app:layout_constraintBottom_toBottomOf="@+id/btn_confirm"        app:layout_constraintEnd_toEndOf="@+id/btn_num"        app:layout_constraintStart_toStartOf="@+id/btn_num"        app:layout_constraintTop_toTopOf="@+id/btn_update" />    <Button        android:id="@+id/btn_confirm"        android:layout_width="0dp"        android:layout_height="wrap_content"        android:layout_marginStart="5dp"        android:layout_marginLeft="5dp"        android:layout_marginTop="10dp"        android:layout_marginEnd="10dp"        android:layout_marginRight="10dp"        android:text="插入数据"        android:textSize="25sp"        app:layout_constraintEnd_toStartOf="@+id/et_flag"        app:layout_constraintStart_toStartOf="parent"        app:layout_constraintTop_toBottomOf="@+id/et_content" />    <Button        android:id="@+id/btn_query"        android:layout_width="0dp"        android:layout_height="wrap_content"        android:layout_marginStart="5dp"        android:layout_marginLeft="5dp"        android:layout_marginTop="20dp"        android:layout_marginEnd="10dp"        android:layout_marginRight="10dp"        android:text="查询结果"        android:textSize="25sp"        app:layout_constraintEnd_toStartOf="@+id/btn_num"        app:layout_constraintStart_toStartOf="parent"        app:layout_constraintTop_toBottomOf="@+id/btn_confirm" />    <TextView        android:id="@+id/textView3"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_marginStart="5dp"        android:layout_marginLeft="5dp"        android:text="内容:"        android:textSize="20sp"        app:layout_constraintBottom_toBottomOf="@+id/tv_query_content"        app:layout_constraintStart_toStartOf="parent"        app:layout_constraintTop_toTopOf="@+id/tv_query_content" />    <TextView        android:id="@+id/tv_query_content"        android:layout_width="0dp"        android:layout_height="wrap_content"        android:layout_marginStart="5dp"        android:layout_marginLeft="5dp"        android:layout_marginTop="10dp"        android:layout_marginEnd="5dp"        android:layout_marginRight="5dp"        android:background="#ffffff"        android:text="TextView"        android:textSize="20sp"        app:layout_constraintEnd_toEndOf="parent"        app:layout_constraintStart_toEndOf="@+id/textView3"        app:layout_constraintTop_toBottomOf="@+id/btn_query" />    <Button        android:id="@+id/btn_update"        android:layout_width="0dp"        android:layout_height="wrap_content"        android:layout_marginStart="10dp"        android:layout_marginLeft="10dp"        android:layout_marginEnd="5dp"        android:layout_marginRight="5dp"        android:text="更新数据"        android:textSize="25sp"        app:layout_constraintEnd_toEndOf="parent"        app:layout_constraintStart_toEndOf="@+id/et_flag"        app:layout_constraintTop_toTopOf="@+id/btn_confirm" />    <Button        android:id="@+id/btn_delete"        android:layout_width="0dp"        android:layout_height="wrap_content"        android:layout_marginStart="10dp"        android:layout_marginLeft="10dp"        android:layout_marginEnd="5dp"        android:layout_marginRight="5dp"        android:text="删除数据"        android:textSize="25sp"        app:layout_constraintEnd_toEndOf="parent"        app:layout_constraintStart_toEndOf="@+id/btn_num"        app:layout_constraintTop_toTopOf="@+id/btn_query" />    <Button        android:id="@+id/btn_num"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_marginTop="10dp"        android:text="数据量"        app:layout_constraintBottom_toBottomOf="@+id/btn_query"        app:layout_constraintEnd_toEndOf="parent"        app:layout_constraintStart_toStartOf="parent"        app:layout_constraintTop_toBottomOf="@+id/et_flag" /></androidx.constraintlayout.widget.ConstraintLayout>

MainActivity .java

package com.example.mydemo;import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.EditText;import android.widget.TextView;import android.widget.Toast;import java.util.List;public class MainActivity extends AppCompatActivity {         private Button mBtnConfirm;    private Button mBtnQuery;    private Button mBtnUpdate;    private Button mBtnDelete;    private Button mBtnDataNum;    private EditText mEtContent;    private EditText mEtFlag;    private TextView mTvDate;    private TextView mTvContentQuery;    @Override    protected void onCreate(Bundle savedInstanceState) {             super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        //绑定布局中的控件        initView();        //为各个控件设置执行命令        initEvent();    }    //得到当前数据库有多少条数据    private int getNoteNum() {            int noteNum = NoteLab.createNoteLab(getApplicationContext())                .queryData(null,null)                .size();       return noteNum;    }    private void initEvent() {             mEtFlag.setText(getNoteNum() + "");        mEtContent.setText("");        //插入数据        mBtnConfirm.setOnClickListener(new View.OnClickListener() {                 @Override            public void onClick(View v) {                     if (mEtContent.getText().toString().length() != 0){                         Note note = new Note();                    note.setContent(mEtContent.getText().toString());                    mTvDate.setText(note.getDate().toString());                    mEtContent.setText("");                    NoteLab.createNoteLab(getApplicationContext()).addData(note);                }                else {                         Toast.makeText(MainActivity.this,"插入数据失败 !",Toast.LENGTH_SHORT)                            .show();                }            }        });        //查询数据        mBtnQuery.setOnClickListener(new View.OnClickListener() {                 @Override            public void onClick(View v) {                     List<Note> notes = NoteLab.createNoteLab(getApplicationContext())                        .queryData(null,null);                int position = Integer.parseInt(mEtFlag.getText().toString())-1;                if ((position >= 0) && (position < getNoteNum())){                         Note note = notes.get(position);                    mTvContentQuery.setText(note.getContent()+"\n\n"+note.getDate());                }                else {                         mTvContentQuery.setText("");                    Toast.makeText(MainActivity.this,"查询数据失败 !",Toast.LENGTH_SHORT)                            .show();                }            }        });        //更新数据        mBtnUpdate.setOnClickListener(new View.OnClickListener() {                 @Override            public void onClick(View v) {                     int position = Integer.parseInt(mEtFlag.getText().toString())-1;                if ((position >= 0) && (position < getNoteNum())){                         Log.i("更新数据position",position+"");                    Log.i("更新数据getNoteNum",getNoteNum()+"");                    NoteLab.createNoteLab(getApplicationContext())                            .updateDate(position,mEtContent.getText().toString());                }                else {                         Toast.makeText(MainActivity.this,"更新数据失败 !",Toast.LENGTH_SHORT)                            .show();                }            }        });        //删除数据        mBtnDelete.setOnClickListener(new View.OnClickListener() {                 @Override            public void onClick(View v) {                     int position = Integer.parseInt(mEtFlag.getText().toString())-1;                if ((position >= 0) && (position < getNoteNum())){                         NoteLab.createNoteLab(getApplicationContext())                            .deleteData(position);                }                else {                         Toast.makeText(MainActivity.this,"删除数据失败 !",Toast.LENGTH_SHORT)                            .show();                }            }        });        //获取数据量        mBtnDataNum.setOnClickListener(new View.OnClickListener() {                 @Override            public void onClick(View v) {      mEtFlag.setText(getNoteNum()+"");            }        });    }    private void initView() {             mBtnConfirm = findViewById(R.id.btn_confirm);        mBtnQuery = findViewById(R.id.btn_query);        mBtnUpdate = findViewById(R.id.btn_update);        mBtnDelete = findViewById(R.id.btn_delete);        mBtnDataNum = findViewById(R.id.btn_num);        mEtContent = findViewById(R.id.et_content);        mEtFlag = findViewById(R.id.et_flag);        mTvDate = findViewById(R.id.tv_date);        mTvContentQuery = findViewById(R.id.tv_query_content);    }}

链接:百度网盘下载 提取码:0d1d

更多相关文章

  1. 一句话锁定MySQL数据占用元凶
  2. Android异步消息处理机制 深入理解Looper、Handler、Message的关
  3. 打造通用的Android下拉刷新组件(适用于ListView、GridView等各类
  4. 详解android的号码匹配
  5. Binder框架在Framework层的C++中的使用
  6. Android(安卓)修改字体,跳不过的 Typeface
  7. android多线程详解之Handler
  8. [置顶] Android之路——第一个上线 APP项目总结
  9. 新建Android工程并引用其他工程当做类库 报错解决方法

随机推荐

  1. 【Android(安卓)Developers Training】 1
  2. 一起学android之如何获取网络类型并判断
  3. MTK Android(安卓)Driver知识大全
  4. 我的第一个 Mono for Android(安卓)应用
  5. Android(安卓)Camera(五)
  6. 安卓开发环境AS2.0搭建
  7. android adb shell 笔记
  8. android点击事件
  9. android的学习(一)环境搭建
  10. Android(安卓)AIDL 教程 (一)—— 简单的