热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【Android开发】:数据存储之SQLite数据库操作(三)

上一讲中我们讲到了SQLite数据库的操作方法[数据存储之SQLite数据库操作(二)],我们主要是以SQL语句对数据库进行增删改查,这一讲我们来学习一下Android建议的对数据库的操
    上一讲中我们讲到了SQLite数据库的操作方法 [数据存储之SQLite数据库操作(二)],我们主要是以SQL语句对数据库进行增删改查,这一讲我们来学习一下 Android 建议的对数据库的操作方法
    查看 SQLiteDatabase 中, 在上一讲中有讲到 execSQL (String sql, Object[] bindArgs) 这个方法,在这里Android建议我们在操纵数据库的时候用以下几种方式:
1) 插入: insert(String, String, ContentValues) insertOrThrow(String, String, ContentValues) insertWithOnConflict(String, String, ContentValues, int)
2) 更新:
update(String, ContentValues, String, String[]) updateWithOnConflict(String, ContentValues, String, String[], int)

3) 删除:
delete(String, String, String[])

[注]这一讲中我们就来使用Android推荐的这些操作数据库的方法来进行数据库的操作,Demo 还是与上一讲类似,读者可以结合上一讲内容来学习,对比之间的不同。

1. 方法概要     1) 查看API文档 SQLiteDatabase 中的
    public long insert (String table, String nullColumnHack, ContentValues values)
    插入一行数据到数据库中
参数:
table : 需要插入行的表的名称 nullColumnHack : 这个参数是可选的,可以为null, SQL 不允许插入一个至少一列都不命名的完全空的行。如果你提供的 values 是空的,而且
没有已知的的列名,这就是一个空行,这是不能被插入的。如果设置非空,nullColumnHack 参数提供一个可为空的列的名称,当插入的 values 是空的时候,就将这个列名置为NULL,然后values值插入。
values : 指定行对应的列的值,这个类型很类似Map,key表示列的名称,values表示列的值
返回值:
返回新插入的行的ID,如果存在错误默认返回 -1
[备注]第二个参数翻译的有些拘谨,我们可以这样理解
当在没有任何已知的列名的情况下,values参数为空的时候,insert是会失败的(数据库不允许插入一个空行),为了防止Insert()方法要求必须添加一条除了主键之外其它字段为Null值的记录,我们要在这里必须指定一个列名[因为values值是以ContentValues 的形式来存储的],到时候如果发现将要插入的行为空行时,就会将你指定的这个列名的值设为null,然后再将values值向NULL列中插入。查看源代码,我们可以发现 Android 中操作数据库的方法底层也是通过构造SQL语句来实现的。
2) 查看API文档SQLiteDatabase 中
public int delete (String table, String whereClause, String[] whereArgs)
删除操作

参数:
table : 表示表名 whereClause : 可选项,是可以通过 SQL语句中where语句来过滤条件删除的条目,如果是null 表示删除所有行 whereArgs : 紧跟第二个参数,作为删除过滤条件的占位符,详情请看下面程序 PersonDao2 的 deletePerson() 方法的操作。
返回值:
如果是 0 表示未删除任何行,如果已经有删除行的操作 会得到 count > 0的数,表示删除的行数

3) 查看API文档SQLiteDatabase 中的

public int update (String table, ContentValues values, String whereClause, String[] whereArgs)
更新操作

参数 :
table :表示表名values :  Map 中指定列名用来更新新的值,如果是null 值则为修改为 NULLwhereClause : 可选项,支持SQL中的更新语句,用来做条件过滤,如果设置null 则会更新所有行whereArgs : 紧跟第二个参数,作为更新过滤条件的占位符,详情请看下面程序 PersonDao2 的updatePerson () 方法的操作。
返回值:
返回所更新的数据库的行数

4)查看API文档SQLiteDatabase 中

   查询操作 query(),可以发现 SQLiteDatabase 中有大量的 query() 查询的重载方法,其实这边它不管怎么重载,都是遵循 SQL 语句来的这里我就剖析一个最为常见的查询方法,其他的读者自己查看文档说明.

public Cursor query (boolean distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit)
参数:
distinct :  判断是否返回的行是唯一值,如果想要返回唯一的行,则为true,否则为false。 table :需要查询的表的名称。 columns : 需要返回的列,如果要返回所有列则置为null。 selection :过滤需要返回的行,格式遵从SQL中 SQL WHERE 语句(除了Where关键字以外).如果返回给定表的所有行,则置为Null。 selectionArgs : 过滤条件的占位符,这里的值会代替过滤语句中 "?"。 groupBy : 过滤条件对行进行分组,格式遵从SQL中 SQL GROUP BY 语句 (除了关键字GROUP BY之外),如果不分组,置为Null。 having : 对分组过滤条件的占位符操作。 orderBy : 如何进行排序,遵从SQL中的SQL ORDER BY 语句, 如果是null表示使用默认的排序顺序。 limit :是否对数据库进行分页的查询。
返回值:
它返回的是一个游标,这个用法之前有讲过,不懂的可以查看前面几讲内容的介绍

2. 代码实现

1) 程序布局文件 activity_main.xml,这里只是定义了几个按钮,就不贴出来了

2) DBOpenHelper.java 用来创建数据库使用

package com.android.sqlitedemo.db;

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

public class DBOpenHelper extends SQLiteOpenHelper {

private static String name = "mydb.db"; // 表示数据库的名称
private static int version = 1; // 表示数据库的版本号

public DBOpenHelper(Context context) {
super(context, name, null, version);
// TODO Auto-generated constructor stub
}

// 当数据库创建的时候,是第一次被执行,完成对数据库的表的创建
@Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
// SQLite 数据创建支持的数据类型: 整型数据,字符串类型,日期类型,二进制的数据类型
// 数据库这边有一个特点,就是SQLite数据库中文本类型没有过多的约束,也就是可以把布尔类型的数据存储到文本类型中,这样也是可以的
String sql = "create table person(id integer primary key autoincrement,name varchar(64),address varchar(64),sex varchar(8))";
db.execSQL(sql); // 完成数据库的创建
}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
}

}
3) PersonService2.java 定义操作数据库(增删改查)的接口
package com.android.sqlitedemo.service;import android.content.ContentValues;import java.util.List;import java.util.Map;/** * 定义好增删改查接口 * @author xukunhui * */public interface PersonService2 {    public boolean addPersion(ContentValues values);         public boolean deletePerson(String whereClause, String[] whereArgs);        public boolean updatePerson(ContentValues values, String whereClause, String[] whereArgs);        //使用 Map 做一个封装,比如说查询数据库的时候返回的单条记录    public Map viewPerson(String selection, String[] selectionArgs);        //使用 List> 做一个封装,比如说查询数据库的时候返回的多条记录    public List> listPersonMaps(String selection, String[] selectionArgs);}
3) PersonDao2.java 实现操作数据库的增删改查的功能
package com.android.sqlitedemo.dao;import android.content.ContentValues;import android.content.Context;import android.database.Cursor;import android.database.sqlite.SQLiteDatabase;import com.android.sqlitedemo.db.DBOpenHelper;import com.android.sqlitedemo.service.PersonService2;import java.util.ArrayList;import java.util.HashMap;import java.util.List;import java.util.Map;public class PersonDao2 implements PersonService2 {    private DBOpenHelper helper = null;    public PersonDao2(Context context) {        helper = new DBOpenHelper(context);    }    @Override    public boolean addPersion(ContentValues values) {        // TODO Auto-generated method stub        boolean flag = false;        SQLiteDatabase database = null;        long id = -1;        try {            database = helper.getWritableDatabase();            id = database.insert("person", null, values);            flag = (id != -1 ? true : false);        } catch (Exception e) {            // TODO: handle exception        } finally {            if (database != null) {                database.close();            }        }        return flag;    }    @Override    public boolean deletePerson(String whereClause, String[] whereArgs) {        // TODO Auto-generated method stub        boolean flag = false;        SQLiteDatabase database = null;        int count = 0;        try {            database = helper.getWritableDatabase();            count = database.delete("person", whereClause, whereArgs);            flag = (count > 0 ? true : false);        } catch (Exception e) {            // TODO: handle exception        } finally {            if (database != null) {                database.close();            }        }        return flag;    }    @Override    public boolean updatePerson(ContentValues values, String whereClause, String[] whereArgs) {        // TODO Auto-generated method stub        boolean flag = false;        SQLiteDatabase database = null;        int count = 0; // 影响数据库的行数        try {            database = helper.getWritableDatabase();            count = database.update("person", values, whereClause, whereArgs);            flag = (count > 0 ? true : false);        } catch (Exception e) {            // TODO: handle exception        } finally {            if (database != null) {                database.close();            }        }        return flag;    }    // 查询单条记录    @Override    public Map viewPerson(String selection, String[] selectionArgs) {        // TODO Auto-generated method stub        // select * from        // * 表示 返回的列的名称(投影查询) from        SQLiteDatabase database = null;        Cursor cursor = null;        Map map = new HashMap();        try {            database = helper.getReadableDatabase();            cursor = database.query(true, "person", null, selection, selectionArgs, null,                    null, null, null); //查询单条记录,记录是唯一的,所以第一个参数置为 true.            int cols_len = cursor.getColumnCount(); // 获取游标个数,即查询所得的结果数目            while (cursor.moveToNext()) {                for (int i = 0; i > listPersonMaps(String selection, String[] selectionArgs) {        // TODO Auto-generated method stub        SQLiteDatabase database = null;        Cursor cursor = null;        List> list = new ArrayList>();        try {            database = helper.getReadableDatabase();            cursor = database.query(false, "person", null, selection, selectionArgs, null,                    null, null, null); //查询所有记录,所以有重复的数据也要全部检出,所以第一参数置为false.            int cols_len = cursor.getColumnCount();            while (cursor.moveToNext()) {                Map map = new HashMap();                for (int i = 0; i 
 4) MainActivity.java 点击按钮触发操作数据的事件
 
package com.android.sqlitedemo;

import java.util.List;
import java.util.Map;

import com.android.sqlitedemo.dao.PersonDao2;
import com.android.sqlitedemo.db.DBOpenHelper;
import com.android.sqlitedemo.service.PersonService2;

import android.os.Bundle;
import android.app.Activity;
import android.content.ContentValues;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity {

private Button button1;
private Button button2;
private Button button3;
private Button button4;
private Button button5;
private Button button6;

private static final String TAG = "MainActivity";

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initComponent();
button1.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
DBOpenHelper helper = new DBOpenHelper(MainActivity.this);
// 调用 getWritableDatabase()或者 getReadableDatabase()其中一个方法将数据库建立
helper.getWritableDatabase();
}
});
button2.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
PersonService2 service2 = new PersonDao2(MainActivity.this);
ContentValues values = new ContentValues();
values.put("name", "AHuier");
values.put("address", "XIAMEN");
values.put("sex", "male");
boolean flag = service2.addPersion(values);
Log.i(TAG, "---- addPersion --->" + flag);
}
});
button3.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
PersonService2 service2 = new PersonDao2(MainActivity.this);
// 删除的SQL语句 :delete from person where id = ?
// 不包含 where 关键字
boolean flag = service2.deletePerson(" id = ? ", new String[] {
"4"
});
Log.i(TAG, "---- deletePerson ---->" + flag);
}
});
button4.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
PersonService2 service2 = new PersonDao2(MainActivity.this);
ContentValues values = new ContentValues();
values.put("name", "AHuier");
values.put("address", "XIAMEN");
values.put("sex", "female");
boolean flag = service2.updatePerson(values, " id = ? ", new String[] {
"1"
});
Log.i(TAG, "---- updatePerson --->" + flag);
}
});
button5.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
PersonService2 service2 = new PersonDao2(MainActivity.this);
Map map = service2.viewPerson(" id = ? ", new String[] { "2" });
Log.i(TAG, "---- viewPerson --->" + map.toString());
}
});
button6.setOnClickListener(new OnClickListener() {

@Override
public void onClick(View v) {
PersonService2 service2 = new PersonDao2(MainActivity.this);
// select * from person
List> list = service2.listPersonMaps(null, null);
Log.i(TAG, "---- viewPerson --->" + list.toString());
}
});
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}

private void initComponent() {
button1 = (Button) findViewById(R.id.button1);
button2 = (Button) findViewById(R.id.button2);
button3 = (Button) findViewById(R.id.button3);
button4 = (Button) findViewById(R.id.button4);
button5 = (Button) findViewById(R.id.button5);
button6 = (Button) findViewById(R.id.button6);
}

}

3. 程序执行过程

1) 插入数据


2) 删除ID = 4 的数据


3) 修改ID = 1 的数据


4) 返回查询的单条记录和多条记录




附该 Demo 的源代码下载地址: http://download.csdn.net/my/uploads









推荐阅读
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • 本文讨论了在数据库打开和关闭状态下,重新命名或移动数据文件和日志文件的情况。针对性能和维护原因,需要将数据库文件移动到不同的磁盘上或重新分配到新的磁盘上的情况,以及在操作系统级别移动或重命名数据文件但未在数据库层进行重命名导致报错的情况。通过三个方面进行讨论。 ... [详细]
  • ALTERTABLE通过更改、添加、除去列和约束,或者通过启用或禁用约束和触发器来更改表的定义。语法ALTERTABLEtable{[ALTERCOLUMNcolu ... [详细]
  • 本文介绍了iOS数据库Sqlite的SQL语句分类和常见约束关键字。SQL语句分为DDL、DML和DQL三种类型,其中DDL语句用于定义、删除和修改数据表,关键字包括create、drop和alter。常见约束关键字包括if not exists、if exists、primary key、autoincrement、not null和default。此外,还介绍了常见的数据库数据类型,包括integer、text和real。 ... [详细]
  • Oracle seg,V$TEMPSEG_USAGE与Oracle排序的关系及使用方法
    本文介绍了Oracle seg,V$TEMPSEG_USAGE与Oracle排序之间的关系,V$TEMPSEG_USAGE是V_$SORT_USAGE的同义词,通过查询dba_objects和dba_synonyms视图可以了解到它们的详细信息。同时,还探讨了V$TEMPSEG_USAGE的使用方法。 ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • Python SQLAlchemy库的使用方法详解
    本文详细介绍了Python中使用SQLAlchemy库的方法。首先对SQLAlchemy进行了简介,包括其定义、适用的数据库类型等。然后讨论了SQLAlchemy提供的两种主要使用模式,即SQL表达式语言和ORM。针对不同的需求,给出了选择哪种模式的建议。最后,介绍了连接数据库的方法,包括创建SQLAlchemy引擎和执行SQL语句的接口。 ... [详细]
  • Java学习笔记之使用反射+泛型构建通用DAO
    本文介绍了使用反射和泛型构建通用DAO的方法,通过减少代码冗余度来提高开发效率。通过示例说明了如何使用反射和泛型来实现对不同表的相同操作,从而避免重复编写相似的代码。该方法可以在Java学习中起到较大的帮助作用。 ... [详细]
  • 利用Visual Basic开发SAP接口程序初探的方法与原理
    本文介绍了利用Visual Basic开发SAP接口程序的方法与原理,以及SAP R/3系统的特点和二次开发平台ABAP的使用。通过程序接口自动读取SAP R/3的数据表或视图,在外部进行处理和利用水晶报表等工具生成符合中国人习惯的报表样式。具体介绍了RFC调用的原理和模型,并强调本文主要不讨论SAP R/3函数的开发,而是针对使用SAP的公司的非ABAP开发人员提供了初步的接口程序开发指导。 ... [详细]
  • 006_Redis的List数据类型
    1.List类型是一个链表结构的集合,主要功能有push,pop,获取元素等。List类型是一个双端链表的结构,我们可以通过相关操作进行集合的头部或者尾部添加删除元素,List的设 ... [详细]
  • 本文讨论了在openwrt-17.01版本中,mt7628设备上初始化启动时eth0的mac地址总是随机生成的问题。每次随机生成的eth0的mac地址都会写到/sys/class/net/eth0/address目录下,而openwrt-17.01原版的SDK会根据随机生成的eth0的mac地址再生成eth0.1、eth0.2等,生成后的mac地址会保存在/etc/config/network下。 ... [详细]
  • web.py开发web 第八章 Formalchemy 服务端验证方法
    本文介绍了在web.py开发中使用Formalchemy进行服务端表单数据验证的方法。以User表单为例,详细说明了对各字段的验证要求,包括必填、长度限制、唯一性等。同时介绍了如何自定义验证方法来实现验证唯一性和两个密码是否相等的功能。该文提供了相关代码示例。 ... [详细]
author-avatar
乘浪追风2010_210
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有