Android数据库源码
一、SQLiteOpenHelper类
简介
SQLiteOpenHelper
是一个帮助类,用于管理数据库的创建和版本控制,它封装了数据库的创建、升级和降级等操作。
主要方法
onCreate(SQLiteDatabase db): 当数据库第一次创建时会调用这个方法,通常在这个方法中创建表。
@Override public void onCreate(SQLiteDatabase db) { String createTableQuery = "CREATE TABLE " + TABLE_NAME + " (" + COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + COLUMN_NAME + " TEXT)"; db.execSQL(createTableQuery); }
onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion): 当数据库版本升级时会调用这个方法,通常在这个方法中进行数据迁移。
@Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { if (oldVersion < 2) { // 执行数据迁移操作 db.execSQL("ALTER TABLE ..."); } }
二、SQLiteDatabase类
简介
SQLiteDatabase
是Android中操作SQLite数据库的核心类,提供了丰富的API用于执行SQL语句、查询数据和管理事务。
主要方法
execSQL(String sql, Object[] bindArgs): 执行一条SQL语句。
db.execSQL("INSERT INTO users (name) VALUES (?)", new String[]{username});
query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy): 查询数据。
Cursor cursor = db.query("users", new String[]{"id", "name"}, "name=?", new String[]{username}, null, null, null);
insert(String tableName, String nullColumnHack, ContentValues values): 插入数据。
ContentValues values = new ContentValues(); values.put("name", name); db.insert("users", null, values);
update(String table, ContentValues values, String whereClause, String[] whereArgs): 更新数据。
ContentValues values = new ContentValues(); values.put("name", newName); db.update("users", values, "id=?", new String[]{userId});
delete(String table, String whereClause, String[] whereArgs): 删除数据。
db.delete("users", "id=?", new String[]{userId});
三、性能优化
减少数据库操作次数
尽量使用批量插入、批量更新等方法来减少数据库操作的次数,可以使用beginTransaction()
和endTransaction()
来包含多个操作,从而减少读写次数。
使用索引
合理使用索引可以大大提高查询效率,在创建表时,应根据查询需求为关键字段创建索引,要定期检查并优化索引,避免过多的无用索引占用存储空间。
优化SQL查询语句
尽量避免在数据库查询中使用复杂的JOIN操作,以减少查询时间,可以通过分解查询或使用临时表的方式来优化复杂查询。
四、常见问题及解决方法
数据库版本升级导致数据丢失
原因:在升级数据库版本时,如果没有正确处理数据迁移,可能会导致数据丢失。
解决方法:在onUpgrade
方法中正确处理数据迁移操作,可以使用ALTER TABLE
语句修改表结构,或者创建一个新的表并将旧表的数据迁移到新表中。
@Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { if (oldVersion < 2) { db.execSQL("ALTER TABLE users ADD COLUMN email TEXT"); } }
SQL注入攻击
原因:直接拼接SQL语句容易导致SQL注入攻击。
解决方法:使用参数化查询或ORM框架(如Room)来避免SQL注入,使用?
占位符代替直接拼接字符串。
String sql = "SELECT * FROM users WHERE username = ? AND password = ?"; Cursor cursor = db.rawQuery(sql, new String[]{username, password});
数据库性能问题
原因:查询语句复杂、索引不当等原因可能导致数据库性能下降。
解决方法:优化SQL查询语句,合理使用索引,可以通过EXPLAIN命令分析查询计划,找出性能瓶颈并进行优化。
db.rawQuery("EXPLAIN QUERY PLAN SELECT * FROM users WHERE name=?", new String[]{name});
五、相关示例代码
示例:创建一个简单的SQLite数据库操作类
public class DatabaseHelper extends SQLiteOpenHelper { private static final String DATABASE_NAME = "mydatabase.db"; private static final int DATABASE_VERSION = 1; private static final String TABLE_NAME = "users"; private static final String COLUMN_ID = "id"; private static final String COLUMN_NAME = "name"; public DatabaseHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } @Override public void onCreate(SQLiteDatabase db) { String createTableQuery = "CREATE TABLE " + TABLE_NAME + " (" + COLUMN_ID + " INTEGER PRIMARY KEY AUTOINCREMENT, " + COLUMN_NAME + " TEXT)"; db.execSQL(createTableQuery); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME); onCreate(db); } public void addUser(String name) { SQLiteDatabase db = this.getWritableDatabase(); ContentValues values = new ContentValues(); values.put(COLUMN_NAME, name); db.insert(TABLE_NAME, null, values); db.close(); } public List<String> getAllUsers() { List<String> userList = new ArrayList<>(); SQLiteDatabase db = this.getReadableDatabase(); Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_NAME, null); if (cursor.moveToFirst()) { do { userList.add(cursor.getString(cursor.getColumnIndex(COLUMN_NAME))); } while (cursor.moveToNext()); } cursor.close(); db.close(); return userList; } }
这个示例展示了如何创建一个SQLite数据库操作类,包括数据库的创建、升级以及基本的增删查操作。
以上就是关于“android数据库源码”的问题,朋友们可以点击主页了解更多内容,希望可以够帮助大家!
原创文章,作者:K-seo,如若转载,请注明出处:https://www.kdun.cn/ask/638560.html