数据库SQLite介绍
Android使用getWritableDatabase()和getReadableDatabase()方法都可以获取一个用于操作数据库的SQLiteDatabase实例。
getReadableDatabase()方法中会调用getWritableDatabase()方法
其中
getWritableDatabase() 方法以读写方式打开数据库,一旦数据库的磁盘空间满了,数据库就只能读而不能写,倘若使用的是getWritableDatabase() 方法就会出错。
getReadableDatabase()方法则是先以读写方式打开数据库,如果数据库的磁盘空间满了,就会打开失败,当打开失败后会继续尝试以只读方式打开数据库。如果该问题成功解决,则只读数据库对象就会关闭,然后返回一个可读写的数据库对象。
- 它会调用并返回一个可以读写数据库的对象
- 在第一次调用时会调用onCreate的方法
- 当数据库存在时会调用onOpen方法
- 结束时调用onClose方法
4. 区别
是不是上面两个总结一样?
然后事实呢?
- 两个方法都是返回读写数据库的对象,但是当磁盘已经满了时,
getWritableDatabase
会抛异常,而getReadableDatabase
不会报错,它此时不会返回读写数据库的对象,而是仅仅返回一个读数据库的对象。 -
getReadableDatabase
会在问题修复后继续返回一个读写的数据库对象。 - 两者都是数据库操作,可能存在延迟等待,所以尽量不要在主线程中调用。
创建与删除数据库
封装一个类去继承SQLiteOpenHelper 在构造函数中传入数据库名称与数据库版本号, 数据库被创建的时候会调用onCreate(SQLiteDatabase db) 方法, 数据库版本号发生改变的时候会调用 onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) 方法。 调用SQLiteOpenHelper 的 getReadableDatabase() 方法去创建数据库,如果数据库不存在则创建 并且返回SQLiteDatabase对象,如果数据库存在则不创建只返回SQLiteDatabase对象。 调用 deleteDatabase(DATABASE_NAME) 方法 传入数据库名称则可删除数据库。
封装了一个DatabaseHelper类继承SQLiteOpenHelper 我使用了设计模式中的单例模式来处理这个类,这里说一下单例模式 单例模式是常见的代码设计模式之一 它的好处是在于避免在内存中频繁的实例化所以将它的对象写成static 静态 这样它的对象就只有一份存在静态内存区使用的时候只须要通过getInstance()就可以直接拿到这个静态对象。
1 public class DatabaseHelper extends SQLiteOpenHelper { 2 private static DatabaseHelper mInstance = null; 3 4 /** 数据库名称 **/ 5 public static final String DATABASE_NAME = "xys.db"; 6 7 /** 数据库版本号 **/ 8 private static final int DATABASE_VERSION = 1; 9 10 /**数据库SQL语句 添加一个表**/ 11 private static final String NAME_TABLE_CREATE = "create table test(" 12 "_id INTEGER PRIMARY KEY AUTOINCREMENT," "name TEXT," "hp INTEGER DEFAULT 100," "mp INTEGER DEFAULT 100," 13 "number INTEGER);"; 14 15 DatabaseHelper(Context context) { 16 super(context, DATABASE_NAME, null, DATABASE_VERSION); 17 } 18 19 /**单例模式**/ 20 static synchronized DatabaseHelper getInstance(Context context) { 21 if (mInstance == null) { 22 mInstance = new DatabaseHelper(context); 23 } 24 return mInstance; 25 } 26 27 @Override 28 public void onCreate(SQLiteDatabase db) { 29 /**向数据中添加表**/ 30 db.execSQL(NAME_TABLE_CREATE); 31 } 32 33 @Override 34 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 35 /**可以拿到当前数据库的版本信息 与之前数据库的版本信息 用来更新数据库**/ 36 } 37 38 39 /** 40 * 删除数据库 41 * @param context 42 * @return 43 */ 44 public boolean deleteDatabase(Context context) { 45 return context.deleteDatabase(DATABASE_NAME); 46 } 47 }
在这个类中使用DatabaseHelper对象 实现创建与删除数据库、
1 public class NewSQLite extends Activity { 2 DatabaseHelper mDbHelper = null; 3 SQLiteDatabase mDb = null; 4 Context mContext = null; 5 @Override 6 protected void onCreate(Bundle savedInstanceState) { 7 setContentView(R.layout.create_sql); 8 mContext = this; 9 //创建DatabaseHelper对象 10 mDbHelper = DatabaseHelper.getInstance(mContext); 11 //调用getReadableDatabase方法如果数据库不存在 则创建 如果存在则打开 12 mDb= mDbHelper.getReadableDatabase(); 13 14 Button button0 = (Button)findViewById(R.id.createDateBase); 15 button0.setOnClickListener(new OnClickListener() { 16 17 @Override 18 public void onClick(View arg0) { 19 20 Toast.makeText(NewSQLite.this, "成功创建数据库", Toast.LENGTH_LONG).show(); 21 } 22 }); 23 Button button1 = (Button)findViewById(R.id.deleteDateBase); 24 button1.setOnClickListener(new OnClickListener() { 25 26 @Override 27 public void onClick(View arg0) { 28 mDbHelper = DatabaseHelper.getInstance(mContext); 29 // 调用getReadableDatabase方法如果数据库不存在 则创建 如果存在则打开 30 mDb = mDbHelper.getReadableDatabase(); 31 // 关闭数据库 32 mDbHelper.close(); 33 // 删除数据库 34 mDbHelper.deleteDatabase(mContext); 35 Toast.makeText(NewSQLite.this, "成功删除数据库", Toast.LENGTH_LONG).show(); 36 } 37 }); 38 39 40 41 super.onCreate(savedInstanceState); 42 } 43 44 }
创建的数据库会被保存在当前项目中 databases 路径下 添加与删除数据库中的表
数据库是可以由多张数据表组成的 如果添加一张数据库的表的话 可以使用 数据库语句 create table 名称(内容) 来进行添加 。这里给出一条创建数据库的语句 。 意思是创建一张表 名称为gameInfo 表中包含的字段 为 _id 为INTEGER 类型 并且递增 name 为Text类型 hp mp 为INTEGER 默认数值为100 number 为INTEGER 类型。 增加 删除 修改 查询 数据库中的数据
使用SQLiteDatabase对象调用 insert()方法 传入标的名称与ContentValues 添加的内容 则可以向数据库表中写入一条数据 delete ()为删除一条数据 update()为更新一条数据。
我详细说一下查找一条数据使用的方法 query 中 跟了8个参数
public Cursor query(String table,String[] columns,String selection,String[] selectionArgs,String groupBy,String having,String orderBy,String limit);
参数说明:
table:数据库表的名称
columns:数据库列名称数组 写入后最后返回的Cursor中只能查到这里的列的内容
selection:查询条件
selectionArgs:查询结果
groupBy:分组列
having:分组条件
orderBy:排序列
limit:分页查询限制
Cursor:返回值,将查询到的结果都存在Cursor
Cursor是一个游标接口,每次查询的结果都会保存在Cursor中 可以通过遍历Cursor的方法拿到当前查询到的所有信息。
Cursor的方法
moveToFirst() //将Curor的游标移动到第一条moveToLast()///将Curor的游标移动到最后一条
move(int offset)//将Curor的游标移动到指定ID
moveToNext()//将Curor的游标移动到下一条
moveToPrevious()//将Curor的游标移动到上一条
getCount() //得到Cursor 总记录条数
isFirst() //判断当前游标是否为第一条记录
isLast()//判断当前游标是否为最后一条数据
getInt(int columnIndex) //根据列名称获得列索引ID
getString(int columnIndex)//根据索引ID 拿到表中存的字段
这里给出一个例子遍历Cursor的例子
1 private void query(SQLiteDatabase db) { 2 // 把整张表的所有数据query到cursor中 3 Cursor cursor = db.query(TABLE_NAME, null, null, null, null, null, null); 4 //判断cursor不为空 这个很重要 5 if (cursor != null) { 6 // 循环遍历cursor 7 while (cursor.moveToNext()) { 8 // 拿到每一行name 与hp的数值 9 String name = cursor.getString(cursor.getColumnIndex("name")); 10 String hp = cursor.getString(cursor.getColumnIndex("hp")); 11 Log.v("info", "姓名是 " name "hp为 " hp); 12 } 13 // 关闭 14 cursor.close(); 15 } 16 }