Android数据存储之数据库SQLiteDatabases使用

       对于更加复杂的数据结构, android提供了内置的SQLite数据库来存储数据.SQLite使用SQL命 令提供了完整的关系型数据库能力,每个使用SQLite的应用程序都有一个该数据库的实例,并且在默认情况下公限当前应用使用,数据库存存储在android设置 的/data/data//databases文件夹中.
       这里创建数据库的操作对象要使用SQLiteOpenHelper类。

使用SQLite数据库的步骤如下:

1)创建数据库

创建SqliteOpenHelper的继承类,需要传入数据库的名称。底层已经帮你创建好数据库。

2)打开数据库

使用SQLiteOpenHelper创建的helper对象

SQLiteDatabase db = helper.getReadableDatabase();

3)创建表

使用SQL语句,在自定义SQLiteOpenHelper类里面创建

db.execSQL(SQlite.CREATE_TABLE);

4)完成数据库的增删改查操作

这里对数据库增删改查的操作都是使用db对象来进行的

增:
db.insert(String tableName,null,ContentValues values);第二个参数是占位符的使用。这里的values是键值对的形式put进去的
删:
db.delete(String tableName, ID + ” = ?”, new String[]{id + “”});
改:
db.update(String tebleName, ContentValues values, ID + “=?”, new String[]{user.id + “”});这里的values包含它要修改的信息。
adapter.notifyDataSetChanged();
查:
Cursor cursor =db.query(String tableName,….);
返回的是一个游标对象,使用moveToNext来获取数据

5)关闭数据库

db.close();

下面用一个程序示例来说明Android数据库的使用:

一.Xml布局文件设计

(一)main_activity.xml设计

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical">

    <Button  android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="insert" android:text="插入" />

    <Button  android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="select" android:text="查询" />

    <ListView  android:id="@+id/main_lv" android:layout_width="match_parent" android:layout_height="match_parent" />
</LinearLayout>

(二)对话框的显示布局文件dialog_layout.xml设计

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical">

    <LinearLayout  android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:padding="10dp">

        <TextView  android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="账号:" />

        <EditText  android:id="@+id/dialog_username" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="4" />
    </LinearLayout>

    <LinearLayout  android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:padding="10dp">

        <TextView  android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="年龄:" />

        <EditText  android:id="@+id/dialog_age" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="4" />
    </LinearLayout>

    <LinearLayout  android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:padding="10dp">

        <TextView  android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="性别:" />

        <EditText  android:id="@+id/dialog_sex" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="4" />
    </LinearLayout>

    <LinearLayout  android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" android:padding="10dp">

        <TextView  android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:text="信息:" />

        <EditText  android:id="@+id/dialog_info" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="4" />
    </LinearLayout>


</LinearLayout>

(三)显示信息的ListView的布局文件item_listView.xml设计

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal">


    <TextView  android:id="@+id/id" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center" android:padding="10dp" android:text="id" />

    <TextView  android:id="@+id/username" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center" android:padding="10dp" android:text="username" />

    <TextView  android:id="@+id/age" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center" android:padding="10dp" android:text="age" />

    <TextView  android:id="@+id/sex" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center" android:padding="10dp" android:text="sex" />

    <TextView  android:id="@+id/info" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:gravity="center" android:padding="10dp" android:text="info" />

</LinearLayout>

二.Java代码设计

(一)自定义SQLiteOpenHelper类的设计

package com.lwz.sqlite;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

/** * Android轻量级数据库的使用 * 可以存放一些简单的数据,而且数据库的创建并不复杂,使用数据库对象直接创建表格就会产生数据库 * 它本质上其实就是文件储存,就是存放和读取的格式是数据库的形式 * 它保存的数据库文件在/data/data/<packagename>/databases 文件夹中 */

public class MySqliteOpenHelper extends SQLiteOpenHelper {

    //构造方法
    //第一个参数是上下文的意思
    //第二个参数是数据库的名称
    //第三个参数是游标工厂,一般使用null就可以
    //第四个参数是版本号
    public MySqliteOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
    }

    //数据库没有创建才回调这个方法
    //用于数据库的表的创建
    @Override
    public void onCreate(SQLiteDatabase db) {
        //创建数据库的一个使用的表
        db.execSQL(SQlite.CREATE_TABLE);
    }

    //版本变化时回调的方法,要求新版本大于旧版本呢!
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        //删除数据库的表,再创建数据库的表
        db.execSQL(SQlite.DELETE_TABLE);
        onCreate(db);
    }

    //定义一个数据库的基本信息,包括一些基本的使用语句
    static class SQlite {
        public static final String DB_NAME = "Test.db";//数据库名称

        public static final String TABLE_NAME = "userInfo";//要操作的表的名称

        //表格里面的数据
        public static final String ID = "_id";//用户的ID

        public static final String USER_USERNAME = "username";//用户的姓名

        public static final String USER_AGE = "age";//用户的年龄

        public static final String USER_SEX = "sex";//用户的性别

        public static final String USER_INFO = "info";//用户的其他信息

        //创建表格使用的SQL语句
        public static final String CREATE_TABLE = "create table " + TABLE_NAME + " (" + ID + " integer primary key autoincrement," + USER_USERNAME + " text not null," + USER_AGE + " integer," + USER_SEX + " varchar(1)," + USER_INFO + " text" + ")";

        //删除表格使用的语句
        public static final String DELETE_TABLE = "drop table if exists " + TABLE_NAME;
    }

}

(二)MainActivity.java文件设计

package com.lwz.sqlite;

import android.content.ContentValues;
import android.content.DialogInterface;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.List;

/** * Android数据库的使用 * 使用ListView显示数据 */

public class MainActivity extends AppCompatActivity implements AdapterView.OnItemClickListener, AdapterView.OnItemLongClickListener {
    //定义ListView布局
    ListView listView;
    //存放数据的集合
    List<User> list = new ArrayList<>();

    //定义一个数据库的对象
    SQLiteDatabase db;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        listView = (ListView) findViewById(R.id.main_lv);
        //实例化数据库对象
        //要通过SQLiteHelper对象,这里使用的是自己定义的类
        MySqliteOpenHelper helper = new MySqliteOpenHelper(this, MySqliteOpenHelper.SQlite.DB_NAME, null, 1);
        //获得数据库对象helper.get...
        //可读,并且可写---的数据库: 磁盘满的情况,写不进去,不写了,一般情况使用这个
        db = helper.getReadableDatabase();
      /* //可读,并且可写---的数据库:磁盘满的情况,写不进去。报错,崩溃了 db = helper.getReadableDatabase();*/
        //给ListView设置适配器
        listView.setAdapter(adapter);

        //给ListView设置监听事件
        listView.setOnItemClickListener(this);
        listView.setOnItemLongClickListener(this);


    }

    /** * 插入数据的方法 */
    public void insert(View v) {
        //1 插入
        //ContentValues是以一种键值对的形式存储数据的
        ContentValues values = new ContentValues();
        values.put(MySqliteOpenHelper.SQlite.USER_USERNAME, "张三");
        values.put(MySqliteOpenHelper.SQlite.USER_AGE, 58);
        values.put(MySqliteOpenHelper.SQlite.USER_SEX, "男");
        values.put(MySqliteOpenHelper.SQlite.USER_INFO, "IT工程师---张工");
        db.insert(MySqliteOpenHelper.SQlite.TABLE_NAME, null, values);
        //插入后进行一次查询
        select();
    }

    /** * 查询数据 */
    public void select(View v) {
        select();
    }

    /** * 查询数据库的具体实现 */
    private void select() {
        //先清除页面上的数据
        list.clear();
        //再加载数据库的数据
        //这里查询所有的数据,只需要一个表名就可以了,后面的条件可以不写,获得的是一个结果集
        Cursor cursor = db.query(MySqliteOpenHelper.SQlite.TABLE_NAME, null, null, null, null, null, null);
        //结果集指向的表头前面.moveToNext()来指向下一个结果
        while (cursor.moveToNext()) {
            //获取结果集里面的数据
            //cursor.getColumnIndex()获取列名所在的列号
            User user = new User();
            //这里通过列号来获取数据
            user.id = cursor.getInt(cursor.getColumnIndex(MySqliteOpenHelper.SQlite.ID));
            user.age = cursor.getInt(cursor.getColumnIndex(MySqliteOpenHelper.SQlite.USER_AGE));
            user.username = cursor.getString(cursor.getColumnIndex(MySqliteOpenHelper.SQlite.USER_USERNAME));
            user.info = cursor.getString(cursor.getColumnIndex(MySqliteOpenHelper.SQlite.USER_INFO));
            user.sex = cursor.getString(cursor.getColumnIndex(MySqliteOpenHelper.SQlite.USER_SEX));
            //把找到的数据添加到List集合中
            list.add(user);
        }
        //刷新适配器
        adapter.notifyDataSetChanged();
    }

    /** * 适配器的创建,为了显示ListView */
    BaseAdapter adapter = new BaseAdapter() {
        @Override
        public int getCount() {
            return list.size();
        }

        @Override
        public User getItem(int position) {
            return list.get(position);
        }

        @Override
        public long getItemId(int position) {
            return position;
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            //定义ViewHolder对象
            ViewHolder holder;
            if (convertView == null) {
                convertView = View.inflate(MainActivity.this, R.layout.item_listview, null);
                holder = new ViewHolder(convertView);
                convertView.setTag(holder);
            } else {
                holder = (ViewHolder) convertView.getTag();
            }
            //往控件上放置数据
            User user = list.get(position);
            holder.age.setText(user.age + ""); //如果不是String类型的数据会报错ResourceNotFound
            holder.info.setText(user.info + "");
            holder.username.setText(user.username + "");
            holder.sex.setText(user.sex + "");
            holder.id.setText(user.id + "");
            //返回视图
            return convertView;
        }

        //创建一个ViewHolder
        class ViewHolder {
            //定义控件对象
            TextView id, info, sex, username, age;

            //通过构造方法传入控件存在的View的对象
            ViewHolder(View convertView) {
                //实例化控件对象
                id = (TextView) convertView.findViewById(R.id.id);
                info = (TextView) convertView.findViewById(R.id.info);
                sex = (TextView) convertView.findViewById(R.id.sex);
                username = (TextView) convertView.findViewById(R.id.username);
                age = (TextView) convertView.findViewById(R.id.age);
            }
        }
    };


    //点击ListView里面的条目时触发的方法,这里修改数据
    @Override
    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
        //要修改的属性的用户对象
        final User user = list.get(position);
        // 创建一个布局的VIew对象
        View dialogView = View.inflate(this, R.layout.dailog_layout, null);
        //定义布局内的控件
        final EditText et_name = (EditText) dialogView.findViewById(R.id.dialog_username);
        final EditText et_age = (EditText) dialogView.findViewById(R.id.dialog_age);
        final EditText et_sex = (EditText) dialogView.findViewById(R.id.dialog_sex);
        final EditText et_info = (EditText) dialogView.findViewById(R.id.dialog_info);
        //给布局内添加选择的条目的信息
        et_name.setText(user.username + "");
        et_age.setText(user.age + "");
        et_sex.setText(user.sex + "");
        et_info.setText(user.info + "");

        // 创建对话框对象
        new AlertDialog.Builder(this).
                // 设置标题
                        setTitle("请输入要修改信息").
                // 添加输入的文本框
                        setView(dialogView).
                // 添加确定按钮
                        setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        //或用户输入的信息并保存到数据库中
                        //修改使用的是ContentValues键值对put的方法
                        ContentValues values = new ContentValues();
                        user.username = et_name.getText().toString();

                        try {
                            user.age = Integer.parseInt(et_age.getText().toString());
                        } catch (Exception e) {
                            Toast.makeText(MainActivity.this, "你输入的年龄格式不正确!", Toast.LENGTH_SHORT).show();
                        }
                        //数据的修改
                        user.sex = et_sex.getText().toString();
                        user.info = et_info.getText().toString();
                        values.put(MySqliteOpenHelper.SQlite.USER_USERNAME, user.username);
                        values.put(MySqliteOpenHelper.SQlite.USER_AGE, user.age);
                        values.put(MySqliteOpenHelper.SQlite.USER_SEX, user.sex);
                        db.update(MySqliteOpenHelper.SQlite.TABLE_NAME, values, MySqliteOpenHelper.SQlite.ID + "=?", new String[]{user.id + ""});
                        adapter.notifyDataSetChanged();
                    }
                }).
                // 添加取消按钮
                        setNegativeButton("取消", null).
                // 产生并显示
                        create().show();
    }

    //长按ListView里面的条目时触发的方法,这里删除数据
    @Override
    public boolean onItemLongClick(AdapterView<?> parent, View view, final int position, long id) {
        //弹出一个对话框,询问是否删除数据
        new AlertDialog.Builder(this).
                setTitle("警告").
                setMessage("是否确定删除信息!").
                setNegativeButton("取消", null)
                .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        //点击确定后,删除信息
                        //获取点中的条目的用户的ID值
                        int id = list.get(position).id;
                        int rows = db.delete(MySqliteOpenHelper.SQlite.TABLE_NAME, MySqliteOpenHelper.SQlite.ID + " = ?", new String[]{id + ""});
                        //在集合中也删除这条数据
                        if (rows > 0) {
                            list.remove(position);
                        }
                        //刷新适配器
                        adapter.notifyDataSetChanged();
                    }
                }).show();
        return true;
    }

    //定义一个内部类方便数据的集体存放
    class User {
        int id;
        String username;
        String info;
        int age;
        String sex;
    }


    //页面关闭时,关闭数据库的连接
    @Override
    protected void onDestroy() {
        super.onDestroy();
        db.close();
    }

}

程序运行后的结果:
Android数据存储之数据库SQLiteDatabases使用_第1张图片

进行各种操作后的显示结果:
Android数据存储之数据库SQLiteDatabases使用_第2张图片

长按条目事件的结果:

点击事件的显示结果:
Android数据存储之数据库SQLiteDatabases使用_第3张图片

上面程序间接实现了SQLite数据库的增删改查操作。
增:点击按钮执行
删:长按后,选择确定时执行
改:点击ListView里面某个数据时执行
查:各种操作后,或点击查询按钮时执行

       其中SQLite数据库的数据是保存在本地文件中的,所以关闭数据库后,下次打开还是可以查询到之前操作的数据的。

你可能感兴趣的:(数据库,android,数据存储)