Android作为眼下主流的移动操作系统,全然符合SQLite占用资源少的优势,故在Android平台上,集成了一个嵌入式关系型数据库—SQLite。假设想要开发 Android 应用程序,须要在 Android 上存储数据,使用SQLite 数据库是一种很好的选择。在一般程序中使用数据库的过程都能够框架化,套路化,实比例如以下:

表说明:

1.班级 classes:

class_id  主键 class_name

2.学生 students:

student_id 主键 student_name  score  class_id 外键

创建表:

CREATE TABLE classes(class_id varchar(10) primary key , class_name varchar(20))

CREATE TABLE students(student_id varchar(10) primary key ,

student_name varchar(20) ,

                                               score varchar(4) ,

                                               class_id varchar(10),

foreign key (class_id) references classes(class_id) on delete cascade on update cascade )

1. 继承扩展 SQLiteOpenHelper 创建数据库和相应表

package com.tang.databasedemo;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log; public class DBHelper extends SQLiteOpenHelper
{ public DBHelper(Context context) {
super(context, "info.db", null, 1);
// TODO Auto-generated constructor stub
} @Override
public void onCreate(SQLiteDatabase db)
{
// TODO Auto-generated method stub
String classesSQL = "CREATE TABLE classes(class_id varchar(10) primary key , " +
"class_name varchar(20))"; String studentsSQL = "CREATE TABLE students(student_id varchar(10) primary key , " +
"student_name varchar(20) ,score varchar(4) ,class_id varchar(10), " +
"foreign key (class_id) references classes(class_id) " +
"on delete cascade on update cascade )";
db.execSQL(classesSQL);
Log.d("my", "create table classes:"+classesSQL);
db.execSQL(studentsSQL);
Log.d("my", "create table students:"+studentsSQL); } @Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
// TODO Auto-generated method stub } }

2. 创建学生(Class)学生(Student)实体

package com.tang.databasedemo;
import android.util.Log;
public class Class
{
private String classId;
private String className; public String getClassId() {
return classId;
}
public void setClassId(String classId) {
this.classId = classId;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public String toString() {
return "Class--->"+"classId:"+classId+" className:"+className; }
}
package com.tang.databasedemo;
public class Student
{
private String studentId;
private String studentName;
private String score;
private String classId; public String getStudentId() {
return studentId;
}
public void setStudentId(String studentId) {
this.studentId = studentId;
}
public String getStudentName() {
return studentName;
}
public void setStudentName(String studentName) {
this.studentName = studentName;
}
public String getScore() {
return score;
}
public void setScore(String score) {
this.score = score;
}
public String getClassId() {
return classId;
}
public void setClassId(String classId) {
this.classId = classId;
}
public String toString()
{
return "Student--->"+"studentId:"+studentId+" studentName:"+studentName+" score:"+score+" classId:"+classId; } }

3. 创建DBServer类,在该类中定义增删改查等方法来操作数据库

package com.tang.databasedemo;
import java.util.ArrayList;
import java.util.List; import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase; public class DBServer
{
private DBHelper dbhelper;
public DBServer(Context context)
{
this.dbhelper = new DBHelper(context);
}
/**
* 加入班级
* @param entity
*/
public void addClass(Class entity)
{ SQLiteDatabase localSQLiteDatabase = this.dbhelper.getWritableDatabase();
Object[] arrayOfObject = new Object[2];
arrayOfObject[0] = entity.getClassId();
arrayOfObject[1] = entity.getClassName();
localSQLiteDatabase.execSQL("insert into classes(class_id,class_name) values(?,?)", arrayOfObject);
localSQLiteDatabase.close();
}
/**
* 加入学生
* @param entity
*/
public void addStudent(Student entity)
{ SQLiteDatabase localSQLiteDatabase = this.dbhelper.getWritableDatabase();
Object[] arrayOfObject = new Object[4];
arrayOfObject[0] = entity.getStudentId();
arrayOfObject[1] = entity.getStudentName();
arrayOfObject[2] = entity.getScore();
arrayOfObject[3] = entity.getClassId();
localSQLiteDatabase.execSQL("insert into students(student_id,student_name,score,class_id) values(?,?,?,?)", arrayOfObject);
localSQLiteDatabase.close();
} /**
* 删除一个班级
* 同一时候会删除students中该班级的学生
* @param class_id
*/
public void deleteClass(String class_id)
{
SQLiteDatabase localSQLiteDatabase = this.dbhelper.getWritableDatabase();
//设置了级联删除和级联更新
//在运行有级联关系的语句的时候必须先设置“PRAGMA foreign_keys=ON”
//否则级联关系默认失效
localSQLiteDatabase.execSQL("PRAGMA foreign_keys=ON");
Object[] arrayOfObject = new Object[1];
arrayOfObject[0] =class_id;
localSQLiteDatabase.execSQL("delete from classes where class_id=?", arrayOfObject);
localSQLiteDatabase.close();
} /**
* 删除一个学生
* @param student_id
*/
public void deleteStudent(String student_id)
{
SQLiteDatabase localSQLiteDatabase = this.dbhelper.getWritableDatabase();
Object[] arrayOfObject = new Object[1];
arrayOfObject[0] =student_id;
localSQLiteDatabase.execSQL("delete from students where student_id=?", arrayOfObject);
localSQLiteDatabase.close();
} /**
* 改动学生信息
* @param entity
*/
public void updateStudentInfo(Student entity)
{
SQLiteDatabase localSQLiteDatabase = this.dbhelper.getWritableDatabase();
Object[] arrayOfObject = new Object[4]; arrayOfObject[0] = entity.getStudentName();
arrayOfObject[1] = entity.getScore();
arrayOfObject[2] = entity.getClassId();
arrayOfObject[3] = entity.getStudentId(); localSQLiteDatabase.execSQL("update students set student_name=?,score=?,class_id=? where student_id=?", arrayOfObject);
localSQLiteDatabase.close();
} /**
* 使用班级编号查找该班级全部学生
* @param classId
* @return
*/
public List<Student> findStudentsByClassId(String classId)
{
List<Student> localArrayList=new ArrayList<Student>();
SQLiteDatabase localSQLiteDatabase = this.dbhelper.getWritableDatabase();
Cursor localCursor = localSQLiteDatabase.rawQuery("select student_id, student_name ,score from students " +
"where class_id=? order by score desc", new String[]{classId}); while (localCursor.moveToNext())
{
Student temp=new Student();
temp.setStudentId(localCursor.getString(localCursor.getColumnIndex("student_id")));
temp.setStudentName(localCursor.getString(localCursor.getColumnIndex("student_name")));
temp.setScore(localCursor.getString(localCursor.getColumnIndex("score")));
temp.setClassId(classId);
localArrayList.add(temp);
}
localSQLiteDatabase.close();
return localArrayList;
} /**
* 使用班级名查找该班级全部学生
* @param className
* @return
*/
public List<Student> findStudentsByClassName(String className)
{
List<Student> localArrayList=new ArrayList<Student>();
SQLiteDatabase localSQLiteDatabase = this.dbhelper.getWritableDatabase();
Cursor localCursor = localSQLiteDatabase.rawQuery("select student_id, student_name,score,classes.class_id from students,classes" +
" where students.class_id=classes.class_id and classes.class_name =? order by score asc" , new String[]{className}); while (localCursor.moveToNext())
{
Student temp=new Student();
temp.setStudentId(localCursor.getString(localCursor.getColumnIndex("student_id")));
temp.setStudentName(localCursor.getString(localCursor.getColumnIndex("student_name")));
temp.setScore(localCursor.getString(localCursor.getColumnIndex("score")));
temp.setClassId(localCursor.getString(3));
localArrayList.add(temp);
}
localSQLiteDatabase.close();
return localArrayList;
}
/**
* 查找全部学生
* @param className
* @return
*/
public List<Student> findAllStudents()
{
List<Student> localArrayList=new ArrayList<Student>();
SQLiteDatabase localSQLiteDatabase = this.dbhelper.getWritableDatabase();
Cursor localCursor = localSQLiteDatabase.rawQuery("select * from students " +
"where 1=1 order by score desc ", null);
while (localCursor.moveToNext())
{
Student temp=new Student();
temp.setStudentId(localCursor.getString(localCursor.getColumnIndex("student_id")));
temp.setStudentName(localCursor.getString(localCursor.getColumnIndex("student_name")));
temp.setScore(localCursor.getString(localCursor.getColumnIndex("score")));
temp.setClassId(localCursor.getString(localCursor.getColumnIndex("class_id")));
localArrayList.add(temp);
}
localSQLiteDatabase.close();
return localArrayList;
} /**
* 取得全部班级
* @return
*/
public List<Class> findAllClasses()
{
List<Class> localArrayList=new ArrayList<Class>();
SQLiteDatabase localSQLiteDatabase = this.dbhelper.getWritableDatabase();
Cursor localCursor = localSQLiteDatabase.rawQuery("select * from classes " +
"where 1=1", null);
while (localCursor.moveToNext())
{
Class temp=new Class();
temp.setClassId(localCursor.getString(localCursor.getColumnIndex("class_id")));
temp.setClassName(localCursor.getString(localCursor.getColumnIndex("class_name")));
localArrayList.add(temp);
}
localSQLiteDatabase.close();
return localArrayList;
} /**
* 成绩最好
* @return
*/
public Student findMaxScoreStudent()
{
Student temp =new Student();
SQLiteDatabase localSQLiteDatabase = this.dbhelper.getWritableDatabase();
Cursor localCursor = localSQLiteDatabase.rawQuery("select student_id,student_name,class_id,max(score) from students " +
"where 1=1",null );
localCursor.moveToFirst();
temp.setStudentId(localCursor.getString(0));
temp.setStudentName(localCursor.getString(1));
temp.setClassId(localCursor.getString(2));
temp.setScore(localCursor.getString(3));
return temp;
} /**
* 查找是否有该学生
* @param studentId
* @return
*/
public boolean isStudentsExists(String studentId)
{
SQLiteDatabase localSQLiteDatabase = this.dbhelper.getWritableDatabase();
Cursor localCursor = localSQLiteDatabase.rawQuery("select count(*) from students " +
"where student_id=?", new String[]{studentId});
localCursor.moveToFirst();
if(localCursor.getLong(0)>0)
return true;
else
return false;
} /**
* 确认该班级是否存在
* @param classId
* @return
*/
public boolean isClassExists(String s)
{
SQLiteDatabase localSQLiteDatabase = this.dbhelper.getWritableDatabase();
Cursor localCursor = localSQLiteDatabase.rawQuery("select count(*) from classes " +
"where class_id=? or class_name=?", new String[]{s,s});
localCursor.moveToFirst();
if(localCursor.getLong(0)>0)
return true;
else
return false;
} }

4.调用DBServer里的方法,操作数据

package com.tang.databasedemo;

import java.util.ArrayList;
import java.util.List;
import java.util.Random; import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.text.AlteredCharSequence;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView; public class MainActivity extends Activity implements OnClickListener { private List<Class> classData =new ArrayList<Class>();
private List<Student> studentsData =new ArrayList<Student>();
private static final String className ="A/B/C/D/E";
private static final String studentName ="彭大/黄二/张三/李四/王五/郑六/田七/周八/叶九/孔十/萧十一";
private DBServer db;
private SharedPreferences share;
private SharedPreferences.Editor editor;
private String info ="";
private EditText editText;
private Button b,b1,b2,b3,b4,b5,b6;
private EditText sId,sName,score,cId,cName;
private Handler hander =new Handler()
{
@Override
public void handleMessage(Message msg)
{
// TODO Auto-generated method stub
if(msg.what==0)
{
sId.setText("");
sName.setText("");
score.setText("");
cName.setText("");
cId.setText("");
}
else if(msg.what==1)
{
db.deleteClass((String)msg.obj);
info += "删除一个班级及班级里面的学生:班级Id:"+(String)msg.obj;
editText.setText(info);
} } };
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
share = getSharedPreferences("DatabaseDamo", 0);
editor =share.edit();
db=new DBServer(this);
if(share.getInt("times", 0)==0)
{
initDatabase();
editor.putInt("times", 1);
editor.commit();
}
} private void initView()
{
editText = (EditText) findViewById(R.id.info);
sId = (EditText) findViewById(R.id.studentId);
sName = (EditText) findViewById(R.id.studentName);
score = (EditText) findViewById(R.id.score);
cId = (EditText) findViewById(R.id.classId);
cName = (EditText) findViewById(R.id.className);
b =(Button) findViewById(R.id.button);
b1 =(Button) findViewById(R.id.button1);
b2 =(Button) findViewById(R.id.button2);
b3 =(Button) findViewById(R.id.button3);
b4 =(Button) findViewById(R.id.button4);
b5 =(Button) findViewById(R.id.button5);
b6 =(Button) findViewById(R.id.button6);
b.setOnClickListener(this);
b1.setOnClickListener(this);
b2.setOnClickListener(this);
b3.setOnClickListener(this);
b4.setOnClickListener(this);
b5.setOnClickListener(this);
b6.setOnClickListener(this); }
private void initDatabase()
{
info="";
editText.setText("");
String []classTemp = className.split("/");
Class c;
for(int i=0;i<classTemp.length;i++)
{
c=new Class();
c.setClassName(classTemp[i]);
c.setClassId("00"+i);
db.addClass(c);
info+= '\n'+"add to database classes:"+c.toString();
}
String []studentTemp = studentName.split("/");
Student s;
for(int j=0;j<studentTemp.length;j++)
{
s=new Student();
s.setStudentName(studentTemp[j]);
s.setStudentId("2014050"+j);
s.setClassId("00"+new Random().nextInt(classTemp.length));
s.setScore(String.valueOf(new Random().nextInt(100)+1));
db.addStudent(s);
info+= '\n'+ "add to database students:"+'\n'+s.toString();
}
editText.setText(info);
} private void addAStudent()
{
info ="";
editText.setText("");
String tempSID = sId.getText().toString();
String tempSName = sName.getText().toString();
String tempScore = score.getText().toString();
String tempCID = cId.getText().toString();
if(checkInfo(tempSID)&&checkInfo(tempSName)&&checkInfo(tempScore)&&checkInfo(tempCID))
{
Student temp =new Student();
temp.setStudentId(tempSID);
temp.setStudentName(tempSName);
temp.setScore(tempScore);
temp.setClassId(tempCID);
db.addStudent(temp);
info+= "add to database students:"+'\n'+temp.toString();
}
else
{
info += "加入一个学生失败:缺少必要信息,请确认studentId,studentName,score,classId的信息是否完整!";
}
editText.setText(info);
} private void deleteAClass()
{
info ="";
editText.setText("");
final String tempCID = cId.getText().toString();
if(checkInfo(tempCID))
{
if(db.isClassExists(tempCID))
{
new AlertDialog.Builder(this)
.setTitle("提示:")
.setMessage("删除一个班级将会删除该班的全部学生信息,确定?")
.setPositiveButton("确定",new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
Message msg =new Message();
msg.what = 1;
msg.obj = tempCID;
hander.sendMessage(msg);
}
})
.setNegativeButton("取消", null)
.show();
}
else
info += "删除一个班级失败:查无此相应班级,请确认classId的信息是否正确!";
}
else
{
info += "删除一个班级失败:缺少必要信息,请确认classId的信息是否完整!";
}
editText.setText(info);
} private void deleteAStudent()
{
info ="";
editText.setText("");
String tempSID = sId.getText().toString();
if(checkInfo(tempSID))
{
if(db.isStudentsExists(tempSID))
{
db.deleteStudent(tempSID);
info += "删除一个学生:学生Id:"+tempSID;
}
else
info += "删除一个学生失败:查无此相应学生,请确认studentId的信息是否正确!";
}
else
{
info += "删除一个学生失败:缺少必要信息,请确认studentId的信息是否完整!";
}
editText.setText(info);
} private void updateStudent()
{
info ="";
editText.setText("");
String tempSID = sId.getText().toString();
String tempSName = sName.getText().toString();
String tempScore = score.getText().toString();
String tempCID = cId.getText().toString();
if(checkInfo(tempSID)&&checkInfo(tempSName)&&checkInfo(tempScore)&&checkInfo(tempCID))
{
if(db.isStudentsExists(tempSID))
{
Student temp =new Student();
temp.setStudentId(tempSID);
temp.setStudentName(tempSName);
temp.setScore(tempScore);
temp.setClassId(tempCID);
db.updateStudentInfo(temp);
info+= "update database students:"+'\n'+temp.toString();
}
else
{
Student temp =new Student();
temp.setStudentId(tempSID);
temp.setStudentName(tempSName);
temp.setScore(tempScore);
temp.setClassId(tempCID);
db.addStudent(temp);
info+= "没有找到相应ID的学生,将此学生加入到数据库!"+'\n'+
"add to database students:"+'\n'+temp.toString();
}
}
else
{
info += "更新学生失败:缺少必要信息,请确认studentId,studentName,score,classId的信息是否完整!";
}
editText.setText(info);
} /**
* 打印某班的学生
*/
private void printStudentsOfClass()
{
info ="";
editText.setText("");
String tempCID = cId.getText().toString();
String tempCName = cName.getText().toString();
if(checkInfo(tempCID))
{
if(db.isClassExists(tempCID))
{
info += "使用ID查询";
studentsData.clear();
studentsData= db.findStudentsByClassId(tempCID);
}
else
{
info += "该ID相应的班级不存在";
}
}
else if(checkInfo(tempCName))
{
if(db.isClassExists(tempCName))
{
info += "使用Name查询";
studentsData.clear();
studentsData = db.findStudentsByClassName(tempCName);
}
else
{
info += "该Name相应的班级不存在";
}
}
else
{
studentsData.clear();
info += "查找学生失败:缺少必要信息,请确认classId或className的信息是否完整!";
}
for(int i=0;i<studentsData.size();i++)
{
info+= '\n'+studentsData.get(i).toString();
}
editText.setText(info);;
} private void printMaxScoreStudent()
{
info ="";
editText.setText("");
Student temp =db.findMaxScoreStudent();
info+= '\n'+temp.toString();
editText.setText(info);;
} private void getAllStudent()
{
studentsData.clear();
studentsData = db.findAllStudents();
for(int i=0;i<studentsData.size();i++)
{
info+= '\n'+studentsData.get(i).toString();
}
} private void getAllClass()
{
classData.clear();
classData = db.findAllClasses();
for(int i=0;i<classData.size();i++)
{
info+= '\n'+classData.get(i).toString();
}
} private void printAllInfo()
{
info ="";
editText.setText("");
getAllStudent();
getAllClass();
editText.setText(info); } @Override
public void onClick(View v)
{
// TODO Auto-generated method stub
int id = v.getId();
switch(id)
{
case R.id.button:
printAllInfo();
break;
case R.id.button1:
addAStudent();
break;
case R.id.button2:
deleteAStudent();
break;
case R.id.button3:
deleteAClass();
break;
case R.id.button4:
updateStudent();
break;
case R.id.button5:
printStudentsOfClass();
break;
case R.id.button6:
printMaxScoreStudent();
break;
}
hander.sendEmptyMessageDelayed(0, 5000);
} private boolean checkInfo(String s)
{
if(s.equals("")||s==null)
return false;
else
return true;
}
}

附图一张:

注:

1 . 关于游标(Cursor)

在查询返回的是一个Cursor类型的对象,它是一个指针,且永远都不会为空,所以,当查询某语句,并推断返回值是否为空时,切勿用cursor==null表示。而有个方法,cursor.getCount()==0就能推断其结果值是否为空了。

close()

关闭游标,释放资源

copyStringToBuffer(int columnIndex, CharArrayBuffer buffer) yB

在缓冲区中检索请求的列的文本,将将其存储

getColumnCount()

返回全部列的总数

getColumnIndex(String columnName)

返回指定列的名称,假设不存在返回-1

getColumnIndexOrThrow(String columnName)

从零開始返回指定列名称,假设不存在将抛出IllegalArgumentException 异常。

getColumnName(int columnIndex)

从给定的索引返回列名

getColumnNames()

返回一个字符串数组的列名

getCount()

返回Cursor 中的行数

moveToFirst()

移动光标到第一行

moveToLast()

移动光标到最后一行

moveToNext()

移动光标到下一行

moveToPosition(int position)

移动光标到一个绝对的位置

moveToPrevious()

移动光标到上一行

2. 关于on delete cascade on update cascade 级联更新和级联删除

SQLite在3.6.19版本号中才開始支持外键约束,可是为了兼容曾经的程序,默认并没有启用该功能,假设要启用该功能每次都要须要使用例如以下语句:PRAGMA foreign_keys = ON来打开。也就是说,在运行删除一个班级的语句的时候须要运行db.execSQL("PRAGMA foreign_keys=ON")

可见:http://blog.csdn.net/tangnengwu/article/details/25980263

3.关于getWritableDatabase()和getReadableDatabase()

这2个方法都能够获取SQLiteDatabase的实例,当使用getWritableDatabase() 方法打开数据库时,一旦数据库的磁盘空间满了,数据库在运行写操作的时候就会出错,

而getReadableDatabase()方法则是先以读写方式打开数据库,假设数据库的磁盘空间满了,就会打开失败,当打开失败后会继续尝试以仅仅读方式打开数据库。假设该问题成功

解决,则仅仅读数据库对象就会关闭,然后返回一个可读写的数据库对象。也就是说getReadableDatabase()将getWritableDatabase()在安全上进行了优化。

在4.4的源代码中:/frameworks/base/core/java/android/database/sqlite/SQLiteOpenHelper.java

 /**
* Create and/or open a database that will be used for reading and writing.
* The first time this is called, the database will be opened and
* {@link #onCreate}, {@link #onUpgrade} and/or {@link #onOpen} will be
* called.
*
* <p>Once opened successfully, the database is cached, so you can
* call this method every time you need to write to the database.
* (Make sure to call {@link #close} when you no longer need the database.)
* Errors such as bad permissions or a full disk may cause this method
* to fail, but future attempts may succeed if the problem is fixed.</p>
*
* <p class="caution">Database upgrade may take a long time, you
* should not call this method from the application main thread, including
* from {@link android.content.ContentProvider#onCreate ContentProvider.onCreate()}.
*
* @throws SQLiteException if the database cannot be opened for writing
* @return a read/write database object valid until {@link #close} is called
*/
public SQLiteDatabase getWritableDatabase() {
synchronized (this) {
return getDatabaseLocked(true);
}
} /**
* Create and/or open a database. This will be the same object returned by
* {@link #getWritableDatabase} unless some problem, such as a full disk,
* requires the database to be opened read-only. In that case, a read-only
* database object will be returned. If the problem is fixed, a future call
* to {@link #getWritableDatabase} may succeed, in which case the read-only
* database object will be closed and the read/write object will be returned
* in the future.
*
* <p class="caution">Like {@link #getWritableDatabase}, this method may
* take a long time to return, so you should not call it from the
* application main thread, including from
* {@link android.content.ContentProvider#onCreate ContentProvider.onCreate()}.
*
* @throws SQLiteException if the database cannot be opened
* @return a database object valid until {@link #getWritableDatabase}
* or {@link #close} is called.
*/
public SQLiteDatabase getReadableDatabase() {
synchronized (this) {
return getDatabaseLocked(false);
}
} private SQLiteDatabase getDatabaseLocked(boolean writable) {
if (mDatabase != null) {
if (!mDatabase.isOpen()) {
// Darn! The user closed the database by calling mDatabase.close().
mDatabase = null;
} else if (!writable || !mDatabase.isReadOnly()) {
// The database is already open for business.
return mDatabase;
}
} if (mIsInitializing) {
throw new IllegalStateException("getDatabase called recursively");
} SQLiteDatabase db = mDatabase;
try {
mIsInitializing = true; if (db != null) {
if (writable && db.isReadOnly()) {
db.reopenReadWrite();
}
} else if (mName == null) {
db = SQLiteDatabase.create(null);
} else {
try {
if (DEBUG_STRICT_READONLY && !writable) {
final String path = mContext.getDatabasePath(mName).getPath();
db = SQLiteDatabase.openDatabase(path, mFactory,
SQLiteDatabase.OPEN_READONLY, mErrorHandler);
} else {
db = mContext.openOrCreateDatabase(mName, mEnableWriteAheadLogging ?
Context.MODE_ENABLE_WRITE_AHEAD_LOGGING : 0,
mFactory, mErrorHandler);
}
} catch (SQLiteException ex) {
if (writable) {
throw ex;
}
Log.e(TAG, "Couldn't open " + mName
+ " for writing (will try read-only):", ex);
final String path = mContext.getDatabasePath(mName).getPath();
db = SQLiteDatabase.openDatabase(path, mFactory,
SQLiteDatabase.OPEN_READONLY, mErrorHandler);
}
} onConfigure(db); final int version = db.getVersion();
if (version != mNewVersion) {
if (db.isReadOnly()) {
throw new SQLiteException("Can't upgrade read-only database from version " +
db.getVersion() + " to " + mNewVersion + ": " + mName);
} db.beginTransaction();
try {
if (version == 0) {
onCreate(db);
} else {
if (version > mNewVersion) {
onDowngrade(db, version, mNewVersion);
} else {
onUpgrade(db, version, mNewVersion);
}
}
db.setVersion(mNewVersion);
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
} onOpen(db); if (db.isReadOnly()) {
Log.w(TAG, "Opened " + mName + " in read-only mode");
} mDatabase = db;
return db;
} finally {
mIsInitializing = false;
if (db != null && db != mDatabase) {
db.close();
}
}
}

对于getReadableDatabase()的凝视,大致意思也就是:

getWritableDatabase()和getReadableDatabase()会返回同样的对象,除非出现了一些如空间已满的问题,这时就会返回一个仅仅读的对象。当问题攻克了之后,仅仅读对象将会被关闭,这时就会返回一个可读写的对象。

SQL实例可运行代码:

http://download.csdn.net/detail/tangnengwu/7369503

android SQLite 使用实例的更多相关文章

  1. Android SQLite总结(一) (转)

    Android SQLite总结(一)  郑海波 2012-08-21 转载请声明:http://blog.csdn.net/nuptboyzhb/article/details/7891887 前言 ...

  2. Android SQLite 数据库详细介绍

    Android SQLite 数据库详细介绍 我们在编写数据库应用软件时,需要考虑这样的问题:因为我们开发的软件可能会安装在很多用户的手机上,如果应用使用到了SQLite数据库,我们必须在用户初次使用 ...

  3. Android SQLite 数据库 增删改查操作

    Android SQLite 数据库 增删改查操作 转载▼ 一.使用嵌入式关系型SQLite数据库存储数据 在Android平台上,集成了一个嵌入式关系型数据库--SQLite,SQLite3支持NU ...

  4. Android SQLite 简易指北

    Android SQLite SQLite一款开源的, 轻量级的数据库. 以文本文件的形式存储数据. SQLite支持所有标准的关系型数据库特性. SQLite运行时占用内存非常少(约250 KByt ...

  5. Android——SQLite/数据库 相关知识总结贴

    android SQLite简介 http://www.apkbus.com/android-1780-1-1.html Android SQLite基础 http://www.apkbus.com/ ...

  6. xamarin.Android SQLite存储

    在可移植类库 新建: using SQLite.Net.Interop; using System; using System.Collections.Generic; using System.Li ...

  7. Android SQLite最简单demo实现(增删查改)

    本来不太想写这篇博客的,但是看到网上的关于android数据库操作的博文都讲得很详细,对于像我这样的新手入门了解SQLite的基本操作有一定难度,所以我参考了网上的一些博客文章,并自己亲自摸索了一遍, ...

  8. 再读Android sqlite

    再读Android sqlite Android原生支持sqlite数据库操作,sqlite时轻量级关系型数据库,支持标准sql语句.Android对sqlite进行良好的接口封装来避免sql注入等安 ...

  9. C#操作SQLite方法实例详解

    用 C# 访问 SQLite 入门(1) CC++C#SQLiteFirefox  用 C# 访问 SQLite 入门 (1) SQLite 在 VS C# 环境下的开发,网上已经有很多教程.我也是从 ...

随机推荐

  1. CCNP路由实验之十五 NAT(网络地址转换)

     CCNP路由实验之十五 NAT(网络地址转换) 众所周知,要让自己的电脑连上Internet,必须要到运营商(ISP)申请一个上网账号,依据此账号申请自己的宽频业务(拨号上网.商业固定IP等等) ...

  2. 利用zip格式实现手机客户端二维码扫描分享识别

    场景: 用户A想要将某应用推荐给用户B,用户B扫描用户A的手机app中的二维码进行下载和安装, 并且需要识别用户B是扫描了用户A的二维码,进而给用户A一定的奖励. (例如:健一网app) zip格式: ...

  3. dataguard主备延迟多长时间的查询方法

    select value from v$dataguard_stats where name='apply lag';    

  4. 使用Microsoft.Office.Interop.Excel时,64位问题

    前不久,碰到一个问题. 曾经用的好好的Microsoft.Office.Interop.Excel实现的导出Excel,迁移至64位server后,就出现: 检索 COM 类工厂中 CLSID 为 { ...

  5. JAVA异常机制简述

    1.类的继承结构 在JAVA所有的异常对象都是Throwable类的一个子类的实例 Exception包含两个分支,由于程序错误导致的异常属于RuntimeException,比如数组下标越界,空指针 ...

  6. Objective-C - 类的静态常量

    创建头文件(.h), 导出常量: // Constants.h FOUNDATION_EXPORT NSString *const MyFirstConstant; FOUNDATION_EXPORT ...

  7. USB串行端口

    USB-SERIAL CH341A(COM22)USB串行端口

  8. [Angular & Web] Retrieve user data from Session

    Once user sign up, we store the user data inside cookie in the broswer and also keep a memory copy i ...

  9. Linux字符界面安装图形界面XWindow

    https://jingyan.baidu.com/article/219f4bf790f4c7de442d3825.html

  10. 学习笔记:Vue——混入

    前言: 到现在用Vue做了不少项目了,用到的都是初阶的功能,很多高阶能力都没有用到.仅用初级阶段也能做项目,甚至是复杂项目,可见vue之强大,果然是渐进式开发方式. 但是本着虚心学习的态度,还是要抽空 ...