Android:SQLite数据库学习小结

SQLite数据库


SQLite数据库简介

​ SQLite是一个轻量级数据库,它是D.Richard Hipp建立的公有领域项目,在2000年发布了第一个版本。它的设计目标是嵌入式的,而且占用资源非常低,在内存中只需要占用几百KB的存储空间,这也是Android移动设备采用SQLite的原因之一。

​ SQLite没有服务器进程,它通过文件保存数据,该文件是跨平台的,可以放在其他平台中使用。并且在保存数据时,支持null(零)、integer(整数)、real(浮点数字)、text(字符串文本)和blob(二进制对象)5种数据类型。

数据库的创建

​ Android系统推荐使用SQLiteOpenHelper的子类创建数据库,因此需要创建一个类继承自SQLiteOpenHelper,并重写该类中的onCreat()方法和onUpgrade()方法即可,示例代码如下:

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import androidx.annotation.Nullable;

public class MyHelper extends SQLiteOpenHelper {
    public MyHelper(Context context) {
        super(context, "itcast.db", null, 2);//上下文对象,数据库名称,游标工厂(通常是null),数据库版本
    }
    
	//数据库第一次被创建时调用该方法
    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE information(_id INTEGER PRIMARY KEY AUTOINCREMENT,name VARCHAR(20),price INTEGER)");
    }
	
    //当数据库的版本号增加时调用
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }
}

数据库的使用

SQLite的基本操作

  1. 增加一条数据

        public void insert(String name, String price) {
            SQLiteDatabase db = helper.getWritableDatabase();	//获取可读写 SQLiteDatabase 对象
            ContentValues values = new ContentValues();		//创建 ContentValues 对象
            values.put("name", name);					//将数据添加到 ContentValues 对象
            values.put("price", price);
            long id = db.insert("information", null, values);	//插入一条数据到information表
            db.close();										//关闭数据库
        }
    

    ​ 使用完SQLiteDatabase对象后一定要调用close()方法关闭,否则数据库连接会一直村咋子,不断消耗内存,当系统内存不足时将获取不到SQLiteDatabase对象,并且会爆出数据库未关闭异常。

  2. 修改一条数据

        public int update(String name, String price) {
            SQLiteDatabase db = helper.getWritableDatabase();
            ContentValues values = new ContentValues();	
            values.put("price", price
                      );
            int number = db.update("information", values, "name=?", new String[]{name});
            return number;
        }
    

    update()方法接收4个参数,第一个参数表示表名,第二个参数接收一个ContentValues对象,第三个参数为可选的where语句,第四个参数表示whereClause语句中表达式的占位参数列表,这些字符会替换掉where条件中的 “ ? ”。

  3. 删除一条数据

        public int delete(long id) {
            SQLiteDatabase db = helper.getWritableDatabase();
            int number = db.delete("information", "_id=?", new String[]{id + ""});
            Toast.makeText(MainActivity.this, "删除成功", Toast.LENGTH_SHORT).show();
            return number;
        }
    
  4. 查询一条数据

        public boolean find(long id) {
            SQLiteDatabase db = helper.getReadableDatabase();		//获取可读 SQLiteDatabase 对象
            Cursor cursor = db.query("information", null, "_id=?", new String[]{id + ""}, null, null, null);
            boolean result = cursor.moveToNext();
            cursor.close();		//关闭游标
            db.close();
            return result;
        }
    

    query()方法接收7个参数,第一个参数表示表的名称,第二个参数表示查询的列名,第三个参数接收查询条件子句,第四个参数接收查询子句对应的条件值,第五个参数表示分组方式,第六个参数接收having条件,即定义组的过滤器,第七个参数表示排序方式。

  5. 删除所有数据

        public void deleteAll(){
            db = helper.getWritableDatabase();
            db.execSQL("delete from information");	//只删除表的数据,不破坏表的结构
        }
    

SQLite中的事务

事务是一个对数据库执行工作的单元,是针对数据库的一组操作,它可以由一条或者多条SQL语句组成。事务是以逻辑顺序完成的工作单位或者序列,可以是由用户手动操作完成,也可以是由某种数据库程序自动完成。同一个事物的操作具备同步的特点,如果其中有一条语句无法执行,那么所有的语句都不会执行。

MyHelper helper = new MyHelper(MainActivity.this);
SQLiteDatabase db = helper.getWritableDatabase();
        db.beginTransaction();      //开始数据库事务
        try {
            db.execSQL("update person set account = account-1000 where name =?", 
                       new Object[]{"zhangsan"}); //执行转出操作* 
            db.execSQL("update person set account = account+1000 where name =?",
                       new Object[]{"wangwu"});   //执行转入操作
            db.setTransactionSuccessful();      //标记数据库事务执行成功
        } catch (Exception e) {
            Log.i("事务处理失败", e.toString());
        } finally {
            db.endTransaction();        //关闭事物
            db.close();     //关闭数据库
        }

数据展示控件

Listview控件

ListView是以列表的形式展示具体数据内容。当数据过多时会出现滚动条,并且能够根据数据的长度自适应屏幕显示。

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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"
    tools:context=".MainActivity">

    <ListView
        android:id="@+id/LV"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_margin="5dp"
        android:divider="#d9d9d9"
        android:dividerHeight="1dp" />

</RelativeLayout>
class MyBaseAdapter extends BaseAdapter {
        @Override
        public int getCount() {
            return names.length;
        }

        @Override
        public Object getItem(int position) {
            return names[position];
        }

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

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            View view = View.inflate(MainActivity.this,R.layout.list_item,null);
            TextView TV = (TextView) view.findViewById(R.id.TV);
            TV.setText(names[position]);
            ImageView imageView = (ImageView) view.findViewById(R.id.image);
            imageView.setBackgroundResource(imgs[position]);
            return view;
        }

        class ViewHolder {
            TextView TV;
            ImageView img;
        }
    }

ListView在定义了id属性之后,才会看到如下图所示的界面。如果ListView没有进行数据适配,那么程序运行之后界面空白,无数据显示。

在这里插入图片描述

ListView的优化

​ 在使用 ListView 展示数据时需要创建对应的 Item 条目展示每条数据。如果展示的数据有成千上万条,那么就需要创建成千上万个 Item,这样会 大大增加内存的消耗,甚至会由于内存溢出导致程序崩溃。为了防止这种情况的出现,就需要对 ListView 进行优化。ListView 优化有两种方式,一种是复用 convertview,一种是使用 ViewHolder 类。

  1. 复用 convertView

    ​ 在 ListView 第一次展示时,系统会根据屏幕的高度和 ltem 的高度创建一定数量的 convertView。当滑动 ListView 时,顶部的 Item 会滑出屏幕,同时释放它所使用的 convertView, 底部新的数据会进入屏幕进行展示,这时新的数据会使用顶部滑出 Item 的converView,从而使整个 ListView 展示数据的过程使用固定数量的 convertView,避免了每次创建新的 Item 而消耗大量内存。

  2. 使用 ViewHolder 类

    ​ 在加载 Item 布局时,会使用 findViewByld()方法找到 Item 布局中的各个控件,在每一次加 载新的 ltem 数据时都会进行控件寻找,这样也会产生耗时操作。为了进一步优化 Listview 减少耗时操作,可以将要加载的子 View 放在 ViewHolder 类中,当第一次创建 convertView 时将这些控件找出,在第二次重用 convertView 时就可直接通过 convertView 中的 getTag()方法获得这些控件。

    ​ 接下来使用上述两种优化方式对上一小节代码进行优化,示例代码如下:

        public View getView(int position, View convertView, ViewGroup parent) {
            ViewHolder holder;
            if (convertView == null) {
                convertView = LayoutInflater.from(
                    getApplicationContext()).inflate(R.layout.list_item, parent, false);
                holder = new ViewHolder();
                holder.TV = (TextView) convertView.findViewById(R.id.TV);
                holder.img = (ImageView) convertView.findViewById(R.id.image);
                convertView.setTag(holder);
            } else {
                holder = (ViewHolder) convertView.getTag();
            }
            holder.TV.setText(names[position]);
            holder.img.setBackgroundResource(imgs[position]);
            return convertView;
        }

        class ViewHolder {
            TextView TV;
            ImageView img;
        }

常用的数据适配器

  1. BaseAdapter

    BaseAdapter实际上是一个抽象类,通常在使用自定义适配器时需要继承BaseAdapter,该类拥有4个抽象方法。即:

    方法名称功能描述
    public int getCount()得到Item的条数
    public Object getItem(int position)根据position(位置)得到某个Item的对象
    public long getItemId(int position)根据position(位置)得到某个Item的id
    public View getView(int position, View convertView, ViewGroup parent)得到相应position对应的Item视图,position是当前Item的位置,convertView用于复用旧视图,parent用于加载XML布局
  2. SimpleAdapter

    SimpleAdapter继承自BaseAdapter,实现了BaseAdapter的4个抽象方法并进行了封装。因此在使用SimpleAdapter进行数据是配时,只需要在构造方法里传入相应的参数即可,SimpleAdapter的构造方法如下所示:

    public SimpleAdapter(Context context, List<? extends Map<String, ?>> data,int resource,String[] from,int[] to);
    

    ​ 所对应的参数分别是:Context上下文对象、数据集合,data中的每一项对应着ListView中的每一项数据、Item布局的资源id、Map集合里的key值,Item布局相应的控件id。

  3. ArrayAdapter

    ​ ArrayAdapter也是BaseAdapter的子类,用法和SimpleAdapter类似。ArrayAdapter通常用于适配TextView控件,例如Android系统中的Setting(设置菜单)。

    public ArrayAdapter(Context context, int resource);
    public ArrayAdapter(Context context, int resource, int textViewResourceId);
    public ArrayAdapter(Context context, int resource, T[] objects);
    public ArrayAdapterContext context, int resource, int textViewResourceId, T[] objects);
    public ArrayAdapter(Context context, int resource, List<T> objects);
    public ArrayAdapter(Context context, int resource, int textViewResourceId, List<T> objects)
    

    ​ ArrayAdapter构造方法中的参数:

    • Context context:Context上下文对象。
    • int resource:Item布局的资源id。
    • int textViewResourceId:Item布局中相应TextView的id。
    • T[] objects:需要适配的数据数组,数据类型数据。
    • List objects:需要适配的数据数组,List类型数据。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值