Android——数据库存储(简单使用增、删、改、查)

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 类提供的常用方法如下表所示:
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);

    }


}
发布了13 篇原创文章 · 获赞 4 · 访问量 4701

猜你喜欢

转载自blog.csdn.net/qq_43567345/article/details/104295314