Android快速入门之SQLite数据存储

轻量级的数据库SQLite

对于构造比较复杂的数据,Android提供了内置的SqlLite数据库存储数据,它是一个轻量的数据库引擎,且占用数据很少,专门用于资源有限的设备上。同时它不像Oracle、MySQL那样需要安装和启动,已经嵌入到手机上,SQLite数据库本身只是一个文件。

如果实际项目中有大量数据需要读写,或者并发访问,要放在服务器端的DATABASE

一般数据采用的固定的静态数据类型,而SQLite采用的是动态数据类型,会根据存入值自动判断。SQLite具有以下五种数据类型:

  • 1.NULL:空值。
  • 2.INTEGER:带符号的整型,具体取决有存入数字的范围大小。
  • 3.REAL:浮点数字,存储为8-byte IEEE浮点数。
  • 4.TEXT:字符串文本。
  • 5.BLOB:二进制对象。

SQLiteDatabase简介

Android提供了SQLiteDatabase代表数据库。一旦指定了数据库的SQLiteDatabase对象,就可以通过SQLiteDatabase对象来管理、操作数据库了。

在SQLiteDatabase提供3种静态方法打开数据库(一般实际开发中不会直接使用)

  • static SQLiteDatabase openDatabase(String path,SQLiteDatabase.CursorFactory factory,int flags):打开path文件所代表的SQLite数据库。
  • static SQLiteDatabase openOrCreateDatabase(File file,SQLiteDatabase.Cursor factory):打开或创建file文件所代表的SQLite数据库。
  • static SQLiteDatabase openOrCreateDatabase(String path,SQLiteDatabase.CursorFactory factory):打开或创建path文件所代表的SQLite数据库。

SQLiteDatabase操作数据库:

获得SQLiteDatabase对象后,就可以调用SQLiteDatabase方法操作数据库,SQLiteDatabase对象提供的常用方法:

  • create(SQLiteDatabase.CursorFactory factory) 创建数据库

  • execSQL(String sql,Object[] bindArgs)执行带占位符的SQL语句

  • execSQL(String sql) 执行SQL语句

  • rawQuery(String sql,String[] selectionArgs) 执行带占位符的查询

  • insert(String table,String nullColumnHack, ContentValues values):添加一条记录,表名、列名、参数集合。

  • delete(String table,String whereClause,String[] whereArgs):删除表中特定数据。表名、满足的条件、为条件传入的参数

  • update(String table,ContentValues values,String whereClause,String[] whereArgs):修改特定数据。表名、想更新的数据、满足的条件、为条件传入的参数

  • query(String table,String[] columns,String selection,String[] selectionArgs,String groupBy,String having, String orderBy):查询数据。表名、列名、查询条件、查询参数、分组、聚合函数、排序

使用SQLiteDatabase进行数据库操作的步骤:

  • 获取SQLiteDatabase对象,它代表了与数据库的连接
  • 调用SQLiteDatabase的方法来执行SQL语句:execSQL(……)、rawQuery(……)
  • 操作SQLiteDatabase的查询结果,比如用SimpleCursorAdapter封装Cursor
  • 关闭SQLiteDatabase,回收资源

示例代码:

//创建数据库
//SQLiteDatabase db=SQLiteDatabase.openOrCreateDatabase("/data/data/com.nsu.db/databases/stu.db",null);
SQLiteDatabase db=dbOpenHelper.getReadableDatabase();
//创建表
String sql = "create table dict(_id integer primary key autoincrement,word text,detail text)";
db.execSQL(sql);
//插入数据
db.execSQL("insert into user_info values(null,?,?)"
,new String[]{"小明","女"});
//删除数据
db.execSQL(“delete from user_info where _id = ?,new String[]{cursor.getInt(positions)+“”}//查询数据
String sql = "select * from dict where word like ? or detail like ?";
Cursor cursor = db.rawQuery(sql, 
new String[]{"%"+key+"%","%"+key+"%"});                                         

SQLiteOpenHelper类

SQLiteOpenHelper类是SQLiteDatabase一个辅助类。这个类的作用是生成一个数据库,并对数据库的版本进行管理。在实际项目中很少使用SQLiteDatabase的方法来打开数据库,通常会继承SQLiteOpenHelper开发子类。通过子类的相关方法打开数据库。

SQLiteOpenHelper是Android提供的一个管理数据库的工具类,可以用于管理数据库的创建和版本更新。创建SQLiteOpenHelper的子类,重写以下方法

  • onCreate(SQLiteDatabase db)当第一次创建数据库时回调该方法
  • onUpgrade(SQLiteDatabase db,int oldVersion,int newVersion)当数据库版本更新时回调该方法
public class DBOpenHelper extends SQLiteOpenHelper {

    private final static String CREATE_TABLE_SQL="create table employees(_id integer primary key autoincrement,name,age,department)";

    public DBOpenHelper(Context context, int version) {
        super(context,"zyl.db",null, version);
    }

    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase) {
        Log.i("DBOpenHelper","---onCreate called ----");
        sqLiteDatabase.execSQL(CREATE_TABLE_SQL);
    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
        Log.i("DBOpenHelper","----onUpgrade called----");
        sqLiteDatabase.execSQL("drop table if exists employees");
        onCreate(sqLiteDatabase);
    }

}

一旦得到SQLiteOpenHelper对象后,程序无需使用SQLiteDatabase的静态方法创建SQLiteDatabase实例,可以使用getWriteableDatabase()和getReadableDatabase()方法来获取一个用于操作数据库的SQLiteDatabase实例。

  • 打开数据库:
    getReadableDatabase():以读的方式打开数据库对应的SQLiteDatabase对象
    getWriteableDatabase():以写的方式打开数据库对应的SQLiteDatabase对象
  • 关闭数据库:
    close():关闭所有打开的SQLiteDatabase

Cursor接口

Cursor是一个游标接口,游标是系统为用户开设的一个数据源缓冲区,用于存放SQL语句的执行结果。使用query方法时会得到一个Cursor对象,Cursor可以定位到结果集的某一行,通过移动指针遍历查询结果。

Cursor常用方法:

  • move(int offset)将指针向上或向下移动指定的行数
  • boolean moveToFirst()移动到第一行
  • boolean moveToLast()移动到最后一行,成功则返回true
  • boolean moveToNext()移动到下一行
  • boolean moveToPosition(int position)移动到指定的行
  • boolean moveToPrevious()移动到上一行

利用SimpleCursorAdapter解析Cursor:

SimpleCursorAdapter(Context context,int layout,Cursor c,String[] from,int[] to,int flags)
//flags推荐取值CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER
SimpleCursorAdapter adapter = new SimpleCursorAdapter(
	context,R.layout.line,cursor,
	new String[]{"news_title","news_content"},
	new int[]{R.id.my_title,R.id.my_content}
)

注意:数据库表的主键列的列明必须为_id,否则会出现错误java.lang.IllegalArgumentException:column"_id" does not exist

SQLite事务操作:

SQLite支持事务,事务是针对数据库的一组操作,可以由一条或者多条SQL语句组成,事务具有原子性,也就是说事务中的语句要么都执行,要么都不执行,SQLiteDatabase中包含两个方法用于控制事务:

  • beginTransaction():开始事务
  • endTransaction():结束事务

使用SQLiteDatabase的beginTransaction()方法可以开启一个事务,程序执行到endTransaction() 方法时会检查事务的标志是否为成功,如果程序执行到endTransaction()之前调用了setTransactionSuccessful() 方法设置事务的标志为成功则提交事务,如果没有调用setTransactionSuccessful() 方法则回滚事务。

//获取数据库对象
SQLiteDatabase sqLiteDatabase=dbOpenHelper.getReadableDatabase();
sqLiteDatabase.beginTransaction();
try{
    //批量处理的操作
    sqLiteDatabase.execSQL("",new Object[]{});
    sqLiteDatabase.execSQL("",new Object[]{});
    //...
    //设置事务标志成功,当结束事务时就会提交事务
    sqLiteDatabase.setTransactionSuccessful();
}catch (Exception e){
    Log.i("事务处理失败",e.toString());
}finally {
    //结束事务
    sqLiteDatabase.endTransaction();
    sqLiteDatabase.close();
}

案例:员工管理

新建一个工程:主活动名为SQLiteOperateActivity,设置用户主界面:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_margin="20dp"
    tools:context=".SQLiteOperateActivity">

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/edtName"
        android:hint="输入员工姓名"
        android:layout_alignParentTop="true" />

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/edtAge"
        android:layout_below="@+id/edtName"
        android:hint="输入员工年龄"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        />

    <EditText
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@+id/edtDepartment"
        android:layout_below="@+id/edtAge"
        android:hint="输入员工部门"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true" />

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="新增"
        android:id="@+id/btnInsert"
        android:layout_below="@+id/edtDepartment"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true" />



    <ListView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/listView"
        android:layout_below="@+id/btnInsert"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true" />

</RelativeLayout>

布局样式:
在这里插入图片描述
设置每一个列表项的样式:itemt_employee.xml:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="5dp"
        android:text="Id"
        android:id="@+id/txtId"
        android:layout_alignParentTop="true"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="5dp"
        android:text="Name"
        android:id="@+id/txtName"
        android:layout_alignParentTop="true"
        android:layout_toRightOf="@+id/txtId"
        android:layout_toEndOf="@+id/txtId" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="5dp"
        android:text="Age"
        android:id="@+id/txtAge"
        android:layout_alignParentTop="true"
        android:layout_toRightOf="@+id/txtName"
        android:layout_toEndOf="@+id/txtName" />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="5dp"
        android:text="Department"
        android:id="@+id/txtDepartment"
        android:layout_alignParentTop="true"
        android:layout_toRightOf="@+id/txtAge"
        android:layout_toEndOf="@+id/txtAge" />

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="5dp"
        android:id="@+id/imgDelete"
        android:layout_alignParentTop="true"
        android:layout_alignParentRight="true"
        android:layout_alignParentEnd="true"
        android:src="@android:drawable/ic_delete" />

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:padding="5dp"
        android:id="@+id/imgEdit"
        android:src="@android:drawable/ic_menu_edit"
        android:layout_alignParentTop="true"
        android:layout_toLeftOf="@+id/imgDelete"
        android:layout_toStartOf="@+id/imgDelete" />
</RelativeLayout>

列表项样式:
在这里插入图片描述

创建数据库:DBOpenHelper类继承自SQLiteOpenHelper,在DBOpenHelper中完成数据库的创建工作:

public class DBOpenHelper extends SQLiteOpenHelper {

    private final static String CREATE_TABLE_SQL="create table employees(" +
            "_id integer primary key autoincrement," +
            "name text," +
            "age int," +
            "department text)";

    public DBOpenHelper(Context context, int version) {
        super(context,"zyl.db",null, version);
    }

    @Override
    public void onCreate(SQLiteDatabase sqLiteDatabase) {
        Log.i("DBOpenHelper","---onCreate called ----");
        sqLiteDatabase.execSQL(CREATE_TABLE_SQL);
    }

    @Override
    public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
        Log.i("DBOpenHelper","----onUpgrade called----");
        sqLiteDatabase.execSQL("drop table if exists employees");
        onCreate(sqLiteDatabase);
    }

}

创建数据库业务操作类:EmployeesDAO,在类中实现增、删、改、查操作。

public class EmployeesDAO {

    private DBOpenHelper dbOpenHelper;
    private static final String TABLENAME="employees";
    public EmployeesDAO(Context context){
        //创建DBOpenHelper对象
        dbOpenHelper=new DBOpenHelper(context,1);
    }
    //向数据库插入一条记录
    public void insert(String name,int age,String department){
        //获取数据库对象
        SQLiteDatabase sqLiteDatabase=dbOpenHelper.getReadableDatabase();

        ContentValues contentValues=new ContentValues();
        contentValues.put("name",name);
        contentValues.put("age",age);
        contentValues.put("department",department);
        //向表中插入记录
        sqLiteDatabase.insert(TABLENAME,null,contentValues);
        sqLiteDatabase.close();
    }
    //根据_id删除记录
    public int delete(int _id){
        SQLiteDatabase sqLiteDatabase=dbOpenHelper.getReadableDatabase();
        int count=sqLiteDatabase.delete(TABLENAME,"_id=?",new String[]{_id+""});
        sqLiteDatabase.close();
        return count;
    }
    //修改数据
    public int update(String name,int age,String department,int _id){
        SQLiteDatabase sqLiteDatabase=dbOpenHelper.getReadableDatabase();
        ContentValues contentValues=new ContentValues();
        contentValues.put("name",name);
        contentValues.put("age",age);
        contentValues.put("department",department);
        int count=sqLiteDatabase.update(TABLENAME,contentValues,"_id=?",new String[]{_id+""});
        sqLiteDatabase.close();
        return  count;
    }
    //查询所有数据
    public ArrayList queryAll(){
        SQLiteDatabase sqLiteDatabase=dbOpenHelper.getReadableDatabase();
        Cursor cursor=sqLiteDatabase.query(TABLENAME,new String[]{"_id","name","age","department"},null,null,null,null,null);
        ArrayList list=new ArrayList();
        while(cursor.moveToNext()){
            HashMap map=new HashMap();
            map.put("_id",cursor.getInt(cursor.getColumnIndex("_id")));
            map.put("name",cursor.getString(cursor.getColumnIndex("name")));
            map.put("age",cursor.getInt(cursor.getColumnIndex("age")));
            map.put("department",cursor.getString(cursor.getColumnIndex("department")));
            list.add(map);
        }
        cursor.close();
        dbOpenHelper.close();
        return list;
    }

}

创建自定义Adapter:EmployeesAdapter

public class EmployeesAdapter extends BaseAdapter {
    private Context context;
    private ArrayList list;

    public EmployeesAdapter(Context context,ArrayList list){
        this.context=context;
        this.list=list;
    }
    @Override
    public int getCount() {
        return list.size();
    }

    @Override
    public Object getItem(int i) {
        return list.get(i);
    }

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

    @Override
    public View getView(final int i, View view, ViewGroup viewGroup) {
        View itemView=view;
        ViewHolder holder;
        if(itemView==null){
            LayoutInflater inflater= (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            itemView=inflater.inflate(R.layout.item_sqlite_operator,null);
            holder=new ViewHolder();
            holder.txtId=(TextView)itemView.findViewById(R.id.txtId);
            holder.txtName=(TextView)itemView.findViewById(R.id.txtName);
            holder.txtAge=(TextView)itemView.findViewById(R.id.txtAge);
            holder.txtDepartment=(TextView)itemView.findViewById(R.id.txtDepartment);
            holder.imgDelete=(ImageView)itemView.findViewById(R.id.imgDelete);
            holder.imgEdit=(ImageView)itemView.findViewById(R.id.imgEdit);
            itemView.setTag(holder);
        }else{
            holder=(ViewHolder) itemView.getTag();
        }

        holder.txtId.setText(((HashMap)list.get(i)).get("_id")+"");
        holder.txtName.setText(((HashMap)list.get(i)).get("name").toString());
        holder.txtAge.setText(((HashMap)list.get(i)).get("age")+"");
        holder.txtDepartment.setText(((HashMap)list.get(i)).get("department").toString());

        holder.imgEdit.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                AlertDialog.Builder builder=new AlertDialog.Builder(context);
                builder.setTitle("请输入更新后的值");

                final View dialogView = LayoutInflater.from(context).inflate(R.layout.dialog_edit,null);
                final EditText edtName = (EditText)  dialogView.findViewById(R.id.edtName);
                final EditText edtAge = (EditText) dialogView.findViewById(R.id.edtAge);
                final EditText edtDepartment = (EditText) dialogView.findViewById(R.id.edtDepartment);
                builder.setView(dialogView);
                final AlertDialog dialog=builder.create();

                edtAge.setText(((HashMap)list.get(i)).get("age").toString());
                edtName.setText(((HashMap)list.get(i)).get("name").toString());
                edtDepartment.setText(((HashMap)list.get(i)).get("department").toString());

                Button btnSubmit=(Button)dialogView.findViewById(R.id.btnSubmit);

                btnSubmit.setOnClickListener(new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        int _id=Integer.parseInt(((HashMap)list.get(i)).get("_id").toString());
                        String name=edtName.getText().toString();
                        int age=Integer.parseInt(edtAge.getText().toString());
                        String department=edtDepartment.getText().toString();
                        HashMap map=(HashMap) list.get(i);
                        map.put("_id",_id);
                        map.put("name",name);
                        map.put("age",age);
                        map.put("department",department);
                        EmployeesDAO dao=new EmployeesDAO(context);
                        dao.update(name,age,department,_id);
                        notifyDataSetChanged();
                        dialog.dismiss();
                    }
                });
                dialog.show();



            }
        });

        holder.imgDelete.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                DialogInterface.OnClickListener listener=new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int pi) {

                        EmployeesDAO dao=new EmployeesDAO(context);
                        dao.delete(Integer.parseInt(((HashMap)list.get(i)).get("_id").toString()));
                        list.remove(i);
                        notifyDataSetChanged();
                    }
                };
                AlertDialog.Builder builder=new AlertDialog.Builder(context);
                builder.setTitle("确定删除该记录?");
                builder.setNegativeButton("取消",null);

                builder.setPositiveButton("确定",listener);
                builder.show();
            }
        });

        return itemView;
    }
    private static class ViewHolder{
        public TextView txtId;
        public TextView txtName;
        public TextView txtAge;
        public TextView txtDepartment;
        public ImageView imgDelete;
        public ImageView imgEdit;
    }

}

编写主界面:SQLiteOperateActivity

public class SQLiteOperateActivity extends AppCompatActivity {

    private EmployeesDAO employeesDAO;
    private EmployeesAdapter employeesAdapter;
    private ArrayList list;
    private EditText edtName,edtAge,edtDepartment;
    private ListView employeesListView;
    private Button btnInsert;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sqlite_operate);

        edtName=(EditText) findViewById(R.id.edtName);
        edtAge=(EditText)findViewById(R.id.edtAge);
        edtDepartment=(EditText) findViewById(R.id.edtDepartment);
        employeesListView=(ListView)findViewById(R.id.listView);
        btnInsert=(Button)findViewById(R.id.btnInsert);


        employeesDAO=new EmployeesDAO(SQLiteOperateActivity.this);
        list=employeesDAO.queryAll();

        employeesAdapter=new EmployeesAdapter(SQLiteOperateActivity.this,list);
        employeesListView.setAdapter(employeesAdapter);

        btnInsert.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String name=edtName.getText().toString();
                String str_age=edtAge.getText().toString();
                int age=Integer.parseInt("".equals(str_age)?"0":str_age);
                String department=edtDepartment.getText().toString();
                employeesDAO.insert(name,age,department);
                list=employeesDAO.queryAll();
                employeesAdapter=new EmployeesAdapter(SQLiteOperateActivity.this,list);
                employeesListView.setAdapter(employeesAdapter);
                edtName.setText("");
                edtAge.setText("");
                edtDepartment.setText("");
            }
        });
    }

}

运行结果:
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龙源lll

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值