mysql保存为vna文件_Android 数据存储(三)SQLite Databases

本文介绍了Android中SQLite数据库的使用,包括如何创建、打开数据库,创建表,添加、修改、删除和查询数据。通过SQLiteOpenHelper管理数据库版本,详细讲解了数据库操作的关键方法和步骤。
摘要由CSDN通过智能技术生成

最近项目需要用到涉及数据库SQLite的知识,真正用的时候才发现自己一点都不熟悉。所以打算将其使用方法总结一下,方便自己以后复习。

SQLiteDatabase

6d5cad1c7ae3

SQLiteDatabase类用来管理SQLite数据库。它有方法可以创建,删除,执行SQL命令,并执行其它常见的数据库管理任务。

1 创建 打开数据库

SQLiteDatabase类中提供了5 个static方法用来打开一个文件对应的数据库。

//openDatabase方法打开path文件对应的数据库。

public static SQLiteDatabase openDatabase(String path, CursorFactory factory, int flags)

public static SQLiteDatabase openDatabase(String path, CursorFactory factory, int flags,DatabaseErrorHandler errorHandler)

//openOrCreateDatabase 如果不存在则先创建再打开数据库,如果存在则直接打开。

public static SQLiteDatabase openOrCreateDatabase(File file, CursorFactory factory)

public static SQLiteDatabase openOrCreateDatabase(String path, CursorFactory factory)

public static SQLiteDatabase openOrCreateDatabase(String path, CursorFactory factory,DatabaseErrorHandler errorHandler)

通过文件path 或者file 创建SQLiteDatabase对象。通过此对象就可以操作数据库了。

//创建打开数据库。

SQLiteDatabase mTestDb = SQLiteDatabase.

openOrCreateDatabase("/data/data/cn.vn.sqlitedatademo/databases/my.db", null);

要保证文件路径是已存在,(例如没有databases文件夹,则会报错android.database.sqlite.SQLiteCantOpenDatabaseException: unknown error (code 14): Could not open database)

Activity的父类(不是直接父类)ContextWrapper.Java实现了Context.java中的如下两个抽象方法:

SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory)

SQLiteDatabase openOrCreateDatabase(String name, int mode, CursorFactory factory, DatabaseErrorHandler errorHandler)

所以可以在Activity中直接调用这两个方法来创建数据库,或者通过它的context来创建数据库。

2 创建表

创建一张表,表名user_info,列为 _id(主键并且自动增加)、name(用户名)、pwd(密码)、modifyTime(修改时间)。

mTestDb.execSQL("CREATE TABLE IF NOT EXISTS user_info(_id INTEGER PRIMARY KEY AUTOINCREMENT,

name TEXT,pwd TEXT,modifyTime INTEGER)")

3 添加数据

public static void InsertTest(){

UserBean user = new UserBean();

user.setName("xiaopihai");

user.setPwd("12345678");

user.setModifyTime(System.currentTimeMillis());

//增加一条数据,INSERT INTO user_info VALUES()因为有4列,所以需要写4项数据,否则会失败,

//第一个数据位null,这是因为它是自动增长的。.

mTestDb.execSQL("INSERT INTO user_info VALUES(null,'xiaopihai','12345678',"+user.getModifyTime()+")");

//不可以为主键设置数据,因为它是唯一的,不可以与别的相同。否则会报错

//SQLiteConstraintException: PRIMARY KEY must be unique (code 19)

//mTestDb.execSQL("INSERT INTO user_info VALUES(12,'zhangsan','mima1111',"+System.currentTimeMillis()+")");

//下面是增加一条数据(只设置某个或某几个内容),默认没添加的数据时空的。

mTestDb.execSQL("INSERT INTO user_info(name,pwd) VALUES('lisi','mimajjjj')");

mTestDb.execSQL("INSERT INTO user_info VALUES(null,?,?,?)",new Object[]{user.getName(),user.getPwd(),user.getModifyTime()});

mTestDb.execSQL("INSERT INTO user_info(name,pwd) VALUES(?,?)",new Object[]{"lisi","mimajjjj"});

ContentValues values = new ContentValues();

values.put(UserSQLiteOpenHelper.COL_NAME,"qwerdf");

//values.put(UserSQLiteOpenHelper.COL_PWD, "qwerdflol");

values.put(UserSQLiteOpenHelper.COL_TIME, user.getModifyTime());

mTestDb.insert("user_info", null,values);

}

数据库结果

_id|name|pwd|modifyTime

1|xiaopihai|12345678|1466403447668

2|lisi|mimajjjj|

3|xiaopihai|12345678|1466403447668

4|lisi|mimajjjj|

5|qwerdf||1466403447668

数据库增加有两种方法:

通过执行sql语句,调用execSQL(String sql) 或者 execSQL(String sql,Object[] bindArgs)方法。

execSQL(String sql) 执行不带占位符的sql语句

mTestDb.execSQL("INSERT INTO user_info(name,pwd) VALUES('hhohh', 'hidiiiihiihh')");

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

mTestDb.execSQL("INSERT INTO user_info(name,pwd) VALUES(?,?)",new Object[]{"lisi","mimajjjj"});

SQLiteDatabase的insert(String table,String nullColumnHack,ContentValues values)方法,

参数1 表名称,

参数2 空列的默认值

参数3 ContentValues类型的一个封装了列名称和列值的Map;

返回值:新插入的行的行号,或-1(如果发生错误)。

values中可以存单个或多个数据。

ContentValues values = new ContentValues();

values.put(UserSQLiteOpenHelper.COL_NAME,"qwerdf");

//values.put(UserSQLiteOpenHelper.COL_PWD, "qwerdflol");

values.put(UserSQLiteOpenHelper.COL_TIME, user.getModifyTime());

mTestDb.insert("user_info", null,values);}

4 修改数据

public static void updateTest(){

mTestDb.execSQL("UPDATE user_info SET name = 'update1' WHERE _id = 1;");

mTestDb.execSQL("UPDATE user_info SET name =? WHERE _id=?",new Object[]{"update1",1});

mTestDb.execSQL("UPDATE user_info SET name = 'update2',modifyTime=111 WHERE _id = 2;");

mTestDb.execSQL("UPDATE user_info SET name =? ,modifyTime =? WHERE _id=?",new Object[]{"update1",111,2});

ContentValues values = new ContentValues();

values.put("name","update3");

values.put("pwd", "2222222");

values.put("modifyTime", 898);

mTestDb.update("user_info", values, "_id=?", new String[]{String.valueOf(3)});

}

数据库结果:

_id|name|pwd|modifyTime

1|update1|12345678|1466404010484

2|update1|mimajjjj|111

3|update3|2222222|898

4|lisi|mimajjjj|

5|qwerdf||1466404010484

修改数据库两种方法:

通过execSQL执行sql语句。

通过方法

public int update (String table, ContentValues values, String whereClause, String[] whereArgs)

在数据库中更新行的便捷方法。

参数:更新的表名; map更新的内容,null是有效值将被转换为NULL。whereClause可选更新时WHERE子句适用。传递null将更新所有行。返回受影响的行数,如果没有返回0。

5 删除数据

public static void deleteTest(){

mTestDb.execSQL("delete from user_info where _id=1");

//mTestDb.execSQL("delete from user_info where _id=?",new Object[]{1});

mTestDb.delete("user_info", "_id=?", new String[]{String.valueOf(2)});

}

数据库结果

_id|name|pwd|modifyTime

3|update3|2222222|898

4|lisi|mimajjjj|

5|qwerdf||1466404010484

删除数据库的两种方法:

修改数据库两种方法:

通过execSQL执行sql语句。

通过下面方法

public int delete (String table, String whereClause, String[] whereArgs)

参数

删除的表

whereClause选择时删除WHERE子句适用。传递null将删除所有行。

返回

受影响的行数,返回删除的行数,如果没有返回0。

6 查询数据

查询所有

public List findAll() {

List userList = new ArrayList();

//查询表中的所有数据。

Cursor cursor = mDB.query(UserSQLiteOpenHelper.DATABASE_TABLE_USER,

null, null, null, null, null, UserSQLiteOpenHelper.COL_TIME

+ " desc"); //order by modifytime 降序

if (null != cursor) {

while (cursor.moveToNext()) {

UserBean user = new UserBean();

user.set_id(cursor.getLong(cursor

.getColumnIndex(UserSQLiteOpenHelper.COL_ID)));

user.setName(cursor.getString(cursor

.getColumnIndex(UserSQLiteOpenHelper.COL_NAME)));

user.setPwd(cursor.getString(cursor

.getColumnIndex(UserSQLiteOpenHelper.COL_PWD)));

user.setModifyTime(cursor.getLong(cursor

.getColumnIndex(UserSQLiteOpenHelper.COL_TIME)));

userList.add(user);

}

cursor.close();

}

return userList;

}

查询某个

/某个或某些查询

//模糊查询

Cursor cursor = mDB.query(UserSQLiteOpenHelper.DATABASE_TABLE_USER,

null, UserSQLiteOpenHelper.COL_NAME + " like?"+" and "+UserSQLiteOpenHelper.COL_ID+" >?",

new String[] {"%"+name+"%",2+""}, null, null, UserSQLiteOpenHelper.COL_ID

+ " desc");

// Cursor cursor = mDB.query(UserSQLiteOpenHelper.DATABASE_TABLE_USER,

// null, UserSQLiteOpenHelper.COL_NAME + " =?",

// new String[] {name}, null, null, UserSQLiteOpenHelper.COL_ID

// + " desc");

//多个条件查询

// Cursor cursor = mDB.query(UserSQLiteOpenHelper.DATABASE_TABLE_USER,

// null, UserSQLiteOpenHelper.COL_NAME + " like?"+" and "+UserSQLiteOpenHelper.COL_ID+" >?",

// new String[] {"%"+name+"%",2+""}, null, null, UserSQLiteOpenHelper.COL_ID

// + " desc");

6d5cad1c7ae3

SqliteDatabase query

这是SqliteDatabase提供的几种方法,可以适当选用,进行查询。

SQLiteOpenHelper类(抽象类),一个辅助类来管理数据库的建立和版本管理。

可以创建一个它的子类,实现onCreate(SQLiteDatabase)

, onUpgrade(SQLiteDatabase, int, int) 以及可选的方法onOpen(SQLiteDatabase),****它主要是打开数据库(如果已存在),如果没存在则创建并打开。根据需要进行升级。

对其子类进行初始化时UserSQLiteOpenHelper.getInstance(context),这时并没有建立数据库。

public static UserSQLiteOpenHelper getInstance(Context context) {

if (null == mInstance) {

mInstance = new UserSQLiteOpenHelper(context);

mContext = context;

}

return mInstance;

}

private UserSQLiteOpenHelper(Context context) {

//这时并没有建立数据库。

super(context, REMOTE_LIVE_DATABASE_NAME, null, version);

}

看父类SQLiteOpenHelper类源码

public SQLiteOpenHelper(Context context, String name, CursorFactory factory, int version) {

this(context, name, factory, version, null);

}

public SQLiteOpenHelper(Context context, String name, CursorFactory factory, int version,

DatabaseErrorHandler errorHandler) {

if (version < 1) throw new IllegalArgumentException("Version must be >= 1, was " + version);

mContext = context;

mName = name;

mFactory = factory;

mNewVersion = version;

mErrorHandler = errorHandler;

}

先是调方法SQLiteOpenHelper(Context context, String name, CursorFactory factory, int version),然后掉到方法SQLiteOpenHelper(Context context, String name, CursorFactory factory, int version),该方法中要求我们传递的version必须大于等于1,否则会报错IllegalArgumentException异常。这个方法中并没有为我们创建并打开数据库,只是存了5个变量的值而已。

那什么时候才会创建数据库呢?

SQliteOpenHelper

public SQLiteDatabase getWritableDatabase() {

synchronized (this) {

return getDatabaseLocked(true);

}

}

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();

}

}

}

查看SQLiteOpenHelper源码中,发现只有getDatabaseLocked()中才会创建数据库,也就是第一次调用SQLiteOpenHelper.getWritableDatabase()或SQLiteOpenHelper.getReadableDatabase()时才回真正的创建数据库。此方法创建的数据库地址为:/data/data/包名/databases/

onConfigure(db)

创建数据库后,调用onConfigure(db),这个方法里面可以设置数据库连接的一些参数,如setLocale() 、setMaximumSize()、setForeignKeyConstraintsEnabled()。

onCreate(db)

再向下会走到onCreate(db)方法中,onCreate只在数据库第一次创建的时候会调用,调用之前version = 0,之后就会设置新的version,所以此方法不会再走了。在onCreate()方法中,主要用来创建表。

之后使用时可以通过设置SQLiteOpenHelper 中的mNewVersion,然后调用getReadableDatabase()或getWritableDatabase(),当mNewVersion大于数据库的version,则会调用onUpgrade来升级。而当mNewVersion小于数据库的version,则调用onDwongrade来降级。然后再将此版本号设置为数据库的版本号。

db.setVersion(mNewVersion)

如何设置mNewVersion呢?

查看SQLiteOpenHelper中只有构造方法中设置了mNewVersion,所有只能通过这两个方法才可以。(子类调用父类的这两个方法。。)

public SQLiteOpenHelper (Context context, String name,

SQLiteDatabase.CursorFactory factory, int version)

public SQLiteOpenHelper (Context context, String name,

SQLiteDatabase.CursorFactory factory, int version, DatabaseErrorHandler errorHandler)

onOpen()每次打开数据库会调用,选用,不是必须的。

6d5cad1c7ae3

效果图

欢迎大家关注、评论、点赞。

你们的支持是我坚持的动力。

6d5cad1c7ae3

欢迎关注微信公众号

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值