每个应用程序都要使用数据,Android应用程序也不例外,Android使用开源的、与操作系统无关的SQL数据库--大名鼎鼎的SQLite。SQLite是一款轻量级数据库,它的设计目的是嵌入式,而且它占用的资源非常少,在嵌入式设备中,可能只需要几百KB,这也是Android 系统采用SQLite 数据库的原因之一吧。
简介
?轻量级
使用SQLite 只需要带一个动态库,就可以享受它的全部功能,而且那
个动态库的尺寸想当小。
?独立性
SQLite 数据库的核心引擎不需要依赖第三方软件,也不需要所谓的“安
装”。
?隔离性
SQLite 数据库中所有的信息(比如表、视图、触发器等)都包含在一个
文件夹内,方便管理和维护。
?跨平台
SQLite 目前支持大部分操作系统,不至电脑操作系统更在众多的手机系
统也是能够运行,比如:Android。
?多语言接口
SQLite 数据库支持多语言编程接口。
?安全性
SQLite 数据库通过数据库级上的独占性和共享锁来实现独立事务处理。
这意味着多个进程可以在同一时间从同一数据库读取数据,但只能有一
个可以写入数据。
SQLite使用介绍
首先先来看一下本篇例子继承SQLiteOpenHelper 类实现的dbHelper 类。
package com.terry;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
public class dbHelper extends SQLiteOpenHelper {
private final static String DATABASE_NAME="sec_db";
private final static int DATABASE_VERSION=1;
private final static String TABLE_NAME="sec_pwd";
public final static String FIELD_ID="_id";
public final static String FIELD_TITLE="sec_Title";
public dbHelper(Context context)
{
super(context, DATABASE_NAME,null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
String sql="Create table "+TABLE_NAME+"("+FIELD_ID+" intege
r primary key autoincrement,"
+FIELD_TITLE+" text );";
db.execSQL(sql);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newV ersion) {
// TODO Auto-generated method stub
String sql=" DROP TABLE IF EXISTS "+TABLE_NAME;
db.execSQL(sql);
onCreate(db);
public Cursor select()
{
SQLiteDatabase db=this.getReadableDatabase();
Cursor cursor=db.query(TABLE_NAME, null, null, null, null, nu ll, " _id desc");
return cursor;
}
public long insert(String Title)
{
SQLiteDatabase db=this.getWritableDatabase();
ContentValues cv=new ContentValues();
cv.put(FIELD_TITLE, Title);
long row=db.insert(TABLE_NAME, null, cv);
return row;
}
public void delete(int id)
{
SQLiteDatabase db=this.getWritableDatabase();
String where=FIELD_ID+"=?";
String[] whereValue={Integer.toString(id)};
db.delete(TABLE_NAME, where, whereValue);
}
public void update(int id,String Title)
{
SQLiteDatabase db=this.getWritableDatabase();
String where=FIELD_ID+"=?";
String[] whereValue={Integer.toString(id)};
ContentValues cv=new ContentValues();
cv.put(FIELD_TITLE, Title);
db.update(TABLE_NAME, cv, where, whereValue);
}
}
创建和打开数据库
上篇通过构造函数来创建数据库,看一下构造函数的方法
android.database.sqlite.SQLiteOpenHelper.SQLiteOpenHelper(Cont ext context, String name, CursorFactory factory, int version)
public SQLiteOpenHelper (Context context, String name, SQLiteD atabase.CursorFactory factory, int version)
Since: API Level 1
Create a helper object to create, open, and/or manage a databa se. The database is not actually created or opened until one o
f getWritableDatabase() or getReadableDatabase() is called.
Parameters
context to use to open or create the database
name of the database file, or null for an in-memory database factory to use for creating cursor objects, or null for the d efault
version number of the database (starting at 1); if the databa se is older, onUpgrade(SQLiteDatabase, int, int) will be use
d to upgrad
e the database
Public Methods
大体可以理成如下:如果进入此函数,不存在此数据库则创建,如果存在此数据库则打开连接,只要进入此方法就可以用打开的连接获得getWritableDatabase()或getReadableDatabase()这两个方法。
?创建表--》Create Table
一个数据库中可以包含多个表,每一条数据都存在指定的表中,要创建可以通过execSQL 方法来执行一条SQL 语句。上面的方法为
代码
public void onCreate(SQLiteDatabase db) {
// TODO Auto-generated method stub
String sql="Create table "+TABLE_NAME+"("+FIELD_ID+" i nteger primary key autoincrement,"
+FIELD_TITLE+" text );";
db.execSQL(sql);
}
上面代码创建了表名为“sec_pwd” 的数据表,表内存在一个integer 类型的主键和一个text 类型的字段,并执行创建该表。
?添加数据--》Insert
上面的代码封装了一个使用SQLite 的insert 方法,向表中添加数据,但是insert 方法要求把数据都打包到ContentValues 中,ContentValue 其实可就是一个HashTable,Key值是字段名称,Value 值是字段的值。通过ContentValues 的put 方法就可以把数据库放到ContentValue 对象中,然后插入到表中去。代码为:
public long insert(String Title)
{
SQLiteDatabase db=this.getWritableDatabase();
ContentValues cv=new ContentValues();
cv.put(FIELD_TITLE, Title);
long row=db.insert(TABLE_NAME, null, cv);
return row;
}
?删除数据--》Delete
依此类推,添加数据用Insert,那么删除数据为Delete
public void delete(int id)
{
SQLiteDatabase db=this.getWritableDatabase();
String where=FIELD_ID+"=?";
String[] whereValue={Integer.toString(id)};
db.delete(TABLE_NAME, where, whereValue);
}
?修改数据--》Update
public void update(int id,String Title)
{
SQLiteDatabase db=this.getWritableDatabase();
String where=FIELD_ID+"=?";
String[] whereValue={Integer.toString(id)};
ContentValues cv=new ContentValues();
cv.put(FIELD_TITLE, Title);
db.update(TABLE_NAME, cv, where, whereValue);
}
可根据自己需要修改字段自行加参数。
?查询数据--》Query
public Cursor select()
{
SQLiteDatabase db=this.getReadableDatabase();
Cursor cursor=db.query(TABLE_NAME, null, null, null, n ull, null, " _id desc");
return cursor;
}
在Android 中查询数据是通过Cursor 类来实现的,当我们使用SQLiteDatabase.query()方法时,会得到一个Cursor对象,Cursor指向的就是每一条数据。它提供了很多有关查询的方法,具体截图如下:
现在dbHelper己经封装完毕,接下来正式进入到我们实际例子中要操作的功能吧,项
目运行效果图:
这里用到了Menu做功能按钮,实例代码如下:
package com.terry;
import android.app.Activity;
import android.database.Cursor;
import android.database.sqlite.SQLiteCursor;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.EditText;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemSelectedListener; public class testDbActivity extends Activity {
private dbHelper db;
private Cursor myCursor;
private ListView myListView;
private EditText myEditText;
private int _id;
protected final static int MENU_ADD=Menu.FIRST;
protected final static int MENU_EDIT=Menu.FIRST+1;
protected final static int MENU_DELETE=Menu.FIRST+2;
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// TODO Auto-generated method stub
super.onCreateOptionsMenu(menu);
menu.add(Menu.NONE, MENU_ADD, 0, R.string.ADD);
menu.add(Menu.NONE, MENU_EDIT, 0,R.string.EDIT);
menu.add(Menu.NONE, MENU_DELETE, 0,R.string.DELETE);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) { // TODO Auto-generated method stub
super.onOptionsItemSelected(item);
switch (item.getItemId()) {
case MENU_ADD:
operation("add");
break;
case MENU_EDIT:
operation("edit");
break;
case MENU_DELETE:
operation("delete");
break;
default:
break;
}
return true;
}
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(https://www.doczj.com/doc/3f18850646.html,yout.main);
myEditText=(EditText)findViewById(R.id.EditText1);
myListView=(ListView)findViewById(R.id.ListView1);
db=new dbHelper(testDbActivity.this);
myCursor=db.select();
SimpleCursorAdapter adpater=new SimpleCursorAdapter(this
, https://www.doczj.com/doc/3f18850646.html,yout.test, myCursor,
new String[]{dbHelper.FIELD_TITLE},
new int[]{R.id.topTextView});
myListView.setAdapter(adpater);
myListView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView> arg0, View arg1, i nt arg2,
long arg3) {
// TODO Auto-generated method stub
myCursor.moveToPosition(arg2);
_id=myCursor.getInt(0);
myEditText.setText(myCursor.getString(1));
}
});
myListView.setOnItemSelectedListener(new OnItemSelectedListen
er() {
@Override
public void onItemSelected(AdapterView> arg0, View arg1,
int arg2, long arg3) {
// TODO Auto-generated method stub
SQLiteCursor sc=(SQLiteCursor)arg0.getSelectedItem(); _id=sc.getInt(0);
myEditText.setText(sc.getString(1));
}
@Override
public void onNothingSelected(AdapterView> arg0) {
// TODO Auto-generated method stub
}
});
}
private void operation(String cmd)
{
if(myEditText.getText().toString().equals(""))
return;
if(cmd=="add")
db.insert( myEditText.getText().toString());
if(cmd=="edit")
db.update(_id, myEditText.getText().toString());
if(cmd=="delete")
db.delete(_id);
myCursor.requery();
myListView.invalidateViews();
myEditText.setText("");
_id=0;
}
}
原文来源:https://www.doczj.com/doc/3f18850646.html,/TerryBlog/archive/2010/06/12/1757166.html
Android学习笔记---SQLite介绍,以及使用Sqlite,进行数据库的创建,完成数据添删改查的理解 17_创建数据库与完成数据添删改查--------------------------------------1.SQLite介绍:最大特点是,无数据类型; 除了可以使用文件或SharedPreferences存储数据,还可以选择使用SQLite数据库存储数据。在Android平台上,集成了一个嵌入式关系型数据库—SQLite,SQLite3支持 NULL、INTEGER n n 、REAL(浮点数字)、TEXT(字符串文本)和BLOB(二进制对象)数据类型,虽然它支持的类型 n n 只有五种,但实际上sqlite3也接受varchar(n)、char(n)、decimal(p,s) 等数据类型,只不 n n 过在运算或保存时会转成对应的五种数据类型。 SQLite最大的特点是你可以把各种类型的数n n 据保存到任何字段中,而不用关心字段声明的数据类型是什么。例如:可以在Integer类型的 n n 字段中存放字符串,或者在布尔型字段中存放浮点数,或者在字符型字段中存放日期型值。n n n 但有一种情况例外:定义为INTEGER PRIMARY KEY的字段只能存储64位整数, 当向这种字段 n n 保存除整数以外的数据时,将会产生错误。 另外, SQLite 在解析CREATE TABLE 语句时, n n 会忽略 CREATE TABLE 语句中跟在字段名后面的数据类型信息,如下面语句会忽略 name字段 n n 的类型信息: CREATE TABLE person (personid integer primary key autoincrement, name varchar n n (20)) SQLite可以解析大部分标准SQL语句,如:查询语句:select * from 表名 where 条件子句 group by 分组字句 having ... order byn n n 排序子句如:select * from person n n n n select * from person order by id desc n n n n select name from person group by name having count(*)>1 ---------------------------------------------------------------------------2.a.分页SQL与mysql类似,下面SQL语句获取5条记录,跳过前面3条记录n n select * from Account limit 5 offset 3 或者 select * from Account limit 3,5 n b.select * from Account limit 3,5,指的是跳过前面的3条记录,然后获取5条记录n c.select * from Account limit 3,5是select * from Account limit 5 offset 3语句 n n 的简写版 -------------------------------------------------------------------------------n 3.常用操作: a.插入语句:insert into 表名(字段列表) values(值列表)。如: insert into person nn n n (name, age) values(‘传智’,3) b.更新语句:update 表名 set 字段名=值where 条件子句。如:update person set name=n n n n'credream ‘where id=10 c.删除语句:delete from 表名 where 条件子句。如:delete from person nwhere id=10 -------------------------------------------------------------------------------2.虽然无数据类型,但是建议加上,这样可以增加可读性,支持标准sql,oracle中的不行 ---------------------------------------------------3.获取添加记录后的自增长的ID值:select last_insert_rowid(); -----------------------------------------------------------4.在android中开发数据库应用: n a.创建数据库:以前在javaee时候,需要手工数据,但是android应用,需要运行在用户的 n n 手机上,所以,android应用,要有自动创建数据库功能,当第一次使用软件的时候 n n 就创建数据库----------------------------------------5.关于数据库自动创建的详细介绍: 我们在编写数据库应用软件时,需要考虑这样的问题:因为我们开发的软件可能会安装在很 n n 多用户的手机上,如果应用使用到了SQLite数据库,我们必须在用户初次使用软件时创建出 n n 应用使用到的数据库表结构及添加一些初始化记录,另外在软件升级的时候,也需要对数据 n n 表结构进行更新。那么,我们如何才能实现在用户初次使用或升级软件时自动在用户的手机 n n 上创建出应用需要的数据库表呢?总不能让我们在每个需要安装此软件的手机上通过手工方 n n 式创建数据库表吧?因为这种需求是每个数据库应用都要面临的,所以在Android系统,为我 n n 们提供了一个名为SQLiteOpenHelper的抽象类,必须继承它才能使用,它是通过对数据库版 n n 本进行管理来实现前面提出的需求。n -----------------------------------------6.SQLite数据库添加,删除,改查操作 n A.创建数据库:SQLiteOpenHelper .getWritableDatabase ()或getReadableDatabase() n n 可以创建数据库7.创建完成以后可以使用SQLITE Expert软件打开生成的数据库n 可以看到除了生成的自己的需要的表之外,还生成了一张:android_metadata表: n 如果在sqlite中使用数据库一定会有一张android_metadata表,用来登记用户的 n 使用语言:zh_cn -----------------------------------------------------n b.数据库自动创建的过程及方法详细介绍: n n我们在编写数据库应用软件时,需要考虑这样的问题:因为我们开发的软件可能会安装在 n n 很多用户的手机上,如果应用使用到了SQLite数据库,我们必须在用户初次使用软件时创建 n n 出应用使用到的数据库表结构及添加一些初始化记录,另外在软件升级的时候,也需要对数n n 据表结构进行更新。那么,我们如何才能实现在用户初次使用或升级软件时自动在用户的手 n n 机上创建出应用需要的数据库表呢?总不能让我们在每个需要安装此软件的手机上通过手工 n n 方式创建数据库表吧?因为这种需求是每个数据库应用都要面临的,所以在Android系统,为n n 我们提供了一个名为SQLiteOpenHelper的抽象类,必须继承它才能使用,它是通过对数据库n n 版本进行管理来实现前面提出的需求。n -------------------------------------------8.详细介绍: 为了实现对数据库版本进行管理,SQLiteOpenHelper类提供了两个重要的方法,分别是 n n onCreate(SQLiteDatabase db)和onUpgrade(SQLiteDatabase db, int oldVersion, intn n n newVersion),前者用于初次使用软件时生成数据库表,后者用于升级软件时更新数据库表结n n 构。当调用SQLiteOpenHelper的getWritableDatabase()或者getReadableDatabase()方法获n n 取用于操作数据库的SQLiteDatabase实例的时候,如果数据库不存在,Android系统会自动生 n n 成一个数据库,接着调用onCreate()方法,onCreate()方法在初次生成数据库时才会被调用 n n ,在onCreate()方法里可以生成数据库表结构及添加一些应用使用到的初始化数据。 n n onUpgrade()方法在数据库的版本发生变化时会被调用,一般在软件升级时才需改变版本号, n n 而数据库的版本是由程序员控制的,假设数据库现在的版本是1,由于业务的变更,修改了数n n 据库表结构,这时候就需要升级软件,升级软件时希望更新用户手机里的数据库表结构,为n n 了实现这一目的,可以把原来的数据库版本设置为2(有同学问设置为3行不行?当然可以,如 n n 果你愿意,设置为100也行),并且在onUpgrade()方法里面实现表结构的更新。当软件的版本 n n 升级次数比较多,这时在onUpgrade()方法里面可以根据原版号和目标版本号进行判断,然后 n n 作出相应的表结构及数据更新。 getWritableDatabase()和getReadableDatabase()方法都可以获取一个用于操作数据库的 n n SQLiteDatabase实例。但getWritableDatabase() 方法以读写方式打开数据库,一旦数据库n n 的磁盘空间满了,数据库就只能读而不能写,倘若使用的是getWritableDatabase() 方法就 n n 会出错。getReadableDatabase()方法先以读写方式打开数据库,如果数据库的磁盘空间满了 n n ,就会打开失败,当打开失败后会继续尝试以只读方式打开数据库。 ------------------------------------------------------------------------9.创建数据库的代码: n a.创建项目:DBSQLIte n b./DBSQLIte/src/com/credream/service/DBOpenHelter.java n n package com.credream.service; n n import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.database.sqlite.SQLiteDatabase.CursorFactory; n n public class DBOpenHelter extends SQLiteOpenHelper { //父类没有默认构造器,需要显示调用 public DBOpenHelter(Context context) { super (context, "credream.db", null, 1); //数据库创建完成后,默认会保存在<包>/database/文件夹下 //当修改版本号时候,会触发:onUpgrade方法 //第二个:指定数据库名称, //第三个:游标工厂,用来迭代,查询后的结果集,null代表使用系统默认的 n n 游标工厂//版本号,大于0 n } /** n* 这个方法是在数据库第一次被创建的时候调用的 n*/ @Override public void onCreate(SQLiteDatabase db) { //SQLiteDatabase这个类,封装了增删改查操作,也叫做数据库操作实例 db.execSQL("CREATE TABLE person (personid integer primary keyn n n autoincrement, name varchar(20))"); //这里也可以不写name的数据类型,因为sqlite是数据类型无关的,就是写n n 了varchar(20),也可以写入超过20的内容 n n } /** n* 当数据库的版本号变更的时候被调用 n*/ @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("alter table person add phone varchar(12) null"); n n } n n } --------------------------------------------------------2.在清单文件中写入测试环境 n n n
SQLite version 3.7.9 2011-11-01 00:52:41 Enter ".help" for instructions Enter SQL statements terminated with a ";" sqlite> create table students( ...> id integer primary key, ...> name text not null unique, ...> sex int default 1, ...> bak text); sqlite> .tables students sqlite> .help .backup ?DB? FILE Backup DB (default "main") to FILE .bail ON|OFF Stop after hitting an error. Default OFF .databases List names and files of attached databases .dump ?TABLE? ... Dump the database in an SQL text format If TABLE specified, only dump tables matching LIKE pattern TABLE. .echo ON|OFF Turn command echo on or off .exit Exit this program .explain ?ON|OFF? Turn output mode suitable for EXPLAIN on or off. With no args, it turns EXPLAIN on. .header(s) ON|OFF Turn display of headers on or off .help Show this message .import FILE TABLE Import data from FILE into TABLE .indices ?TABLE? Show names of all indices If TABLE specified, only show indices for tables matching LIKE pattern TABLE. .load FILE ?ENTRY? Load an extension library .log FILE|off Turn logging on or off. FILE can be stderr/stdout .mode MODE ?TABLE? Set output mode where MODE is one of: csv Comma-separated values column Left-aligned columns. (See .width) html HTML