一、使用SQLiteOpenHelper类创建数据库与版本管理
1、nCreate(database):首次使用软件时生成数据库表
2、onUpgrade(database,oldVersion,newVersion):在数据库的版本发生变化时会被调用, 一 般 在软件升级时才需改变版本号,而数据库的版本是由程序员控制的
public class MyDBOpenHelper extends SQLiteOpenHelper { public MyDBOpenHelper(Context context, String name, CursorFactory factory, int version) {super(context, "my.db", null, 1); } @Override //数据库第一次创建时被调用 public void onCreate(SQLiteDatabase db) { db.execSQL("CREATE TABLE person(personid INTEGER PRIMARY KEY AUTOINCREMENT,name VARCHAR(20))"); } //软件版本号发生改变时调用 @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("ALTER TABLE person ADD phone VARCHAR(12) NULL"); } }
当调用的MyDBOpenhelper的对象的getWritableDatabase()就会在下述目录下创建我们的db 数据库文件:
可以使用SQLite图形化工具(SQLite Expert )查看db文件
二、Demo
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Context mContext;
private Button btn_insert;
private Button btn_query;
private Button btn_update;
private Button btn_delete;
private SQLiteDatabase db;
private MyDBOpenHelper myDBHelper;
private StringBuilder sb;
private int i = 1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mContext = MainActivity.this;
myDBHelper = new MyDBOpenHelper(mContext, "my.db", null, 1);
bindViews();
}
private void bindViews() {
btn_insert = (Button) findViewById(R.id.btn_insert);
btn_query = (Button) findViewById(R.id.btn_query);
btn_update = (Button) findViewById(R.id.btn_update);
btn_delete = (Button) findViewById(R.id.btn_delete);
btn_query.setOnClickListener(this);
btn_insert.setOnClickListener(this);
btn_update.setOnClickListener(this);
btn_delete.setOnClickListener(this);
}
@Override
public void onClick(View v) {
db = myDBHelper.getWritableDatabase();
switch (v.getId()) {
case R.id.btn_insert:
ContentValues values1 = new ContentValues();
values1.put("name", "呵呵~" + i);
i++;
//参数依次是:表名,强行插入null值得数据列的列名,一行记录的数据
db.insert("person", null, values1);
Toast.makeText(mContext, "插入完毕~", Toast.LENGTH_SHORT).show();
break;
case R.id.btn_query:
sb = new StringBuilder();
//参数依次是:表名,列名,where约束条件,where中占位符提供具体的值,指定group by的列,进一步约束
//指定查询结果的排序方式
Cursor cursor = db.query("person", null, null, null, null, null, null);
if (cursor.moveToFirst()) {
do {
int pid = cursor.getInt(cursor.getColumnIndex("personid"));
String name = cursor.getString(cursor.getColumnIndex("name"));
sb.append("id:" + pid + ":" + name + "\n");
} while (cursor.moveToNext());
}
cursor.close();
Toast.makeText(mContext, sb.toString(), Toast.LENGTH_SHORT).show();
break;
case R.id.btn_update:
ContentValues values2 = new ContentValues();
values2.put("name", "嘻嘻~");
//参数依次是表名,修改后的值,where条件,以及约束,如果不指定三四两个参数,会更改所有行
db.update("person", values2, "name = ?", new String[]{"呵呵~2"});
break;
case R.id.btn_delete:
//参数依次是表名,以及where条件与约束
db.delete("person", "personid = ?", new String[]{"3"});
break;
}
}
}
三、使用SQL语句操作数据库,QLiteDatabase提供的相关方法:
- execSQL(SQL,Object[]):使用带占位符的SQL语句,这个是执行修改数据库内容的sql语句用的
- rawQuery(SQL,Object[]):使用带占位符的SQL查询操作 另外前面忘了介绍下Curosr这个东西以及相关属性,这里补充下: ——Cursor对象有点类似于JDBC中的ResultSet,结果集!使用差不多,提供一下方法移动查询结果的记录指针:
- move(offset):指定向上或者向下移动的行数,整数表示向下移动;负数表示向上移动!
- moveToFirst():指针移动到第一行,成功返回true,也说明有数据
- moveToLast():指针移动到最后一样,成功返回true;
- moveToNext():指针移动到下一行,成功返回true,表明还有元素!
- moveToPrevious():移动到上一条记录
- getCount( )获得总得数据条数
- isFirst():是否为第一条记录
- isLast():是否为最后一项
- moveToPosition(int):移动到指定行
1.插入数据:
public void save(Person p) { SQLiteDatabase db = dbOpenHelper.getWritableDatabase(); db.execSQL("INSERT INTO person(name,phone) values(?,?)", new String[]{p.getName(),p.getPhone()}); }
2.删除数据:
public void delete(Integer id) { SQLiteDatabase db = dbOpenHelper.getWritableDatabase(); db.execSQL("DELETE FROM person WHERE personid = ?", new String[]{id}); }
3.修改数据:
public void update(Person p) { SQLiteDatabase db = dbOpenHelper.getWritableDatabase(); db.execSQL("UPDATE person SET name = ?,phone = ? WHERE personid = ?", new String[]{p.getName(),p.getPhone(),p.getId()}); }
4.查询数据:
public Person find(Integer id) { SQLiteDatabase db = dbOpenHelper.getReadableDatabase(); Cursor cursor = db.rawQuery("SELECT * FROM person WHERE personid = ?", new String[]{id.toString()}); //存在数据才返回true if(cursor.moveToFirst()) { int personid = cursor.getInt(cursor.getColumnIndex("personid")); String name = cursor.getString(cursor.getColumnIndex("name")); String phone = cursor.getString(cursor.getColumnIndex("phone")); return new Person(personid,name,phone); } cursor.close(); return null; }
5.数据分页:
public List<Person> getScrollData(int offset,int maxResult) { List<Person> person = new ArrayList<Person>(); SQLiteDatabase db = dbOpenHelper.getReadableDatabase(); Cursor cursor = db.rawQuery("SELECT * FROM person ORDER BY personid ASC LIMIT= ?,?", new String[]{String.valueOf(offset),String.valueOf(maxResult)}); while(cursor.moveToNext()) { int personid = cursor.getInt(cursor.getColumnIndex("personid")); String name = cursor.getString(cursor.getColumnIndex("name")); String phone = cursor.getString(cursor.getColumnIndex("phone")); person.add(new Person(personid,name,phone)) ; } cursor.close(); return person; }
6.查询记录数:
public long getCount() { SQLiteDatabase db = dbOpenHelper.getReadableDatabase(); Cursor cursor = db.rawQuery("SELECT COUNT (*) FROM person",null); cursor.moveToFirst(); long result = cursor.getLong(0); cursor.close(); return result; //除了上面获取条数的方法外还可以使用cursor.getCount()方法获得数据的条数, 但是SQL语句要改 改!比如SELECT * FROM person; }
四、事务
SQLiteDatabase mydb = myDBHelper.getWritableDatabase(); mydb.beginTransaction();//开启事务 try { mydb.execSQL("update person set adress = ? where personid=?", new String[]{"呼呼家~" + i,"20000"}); mydb.execSQL("INSERT INTO person(name,phone) values(?,?)", new String[]{"噜噜~" + i,"phone"+i}); mydb.setTransactionSuccessful();//提交事务 }finally { mydb.endTransaction();//结束事务 } 五、SimpleCursorAdapter绑定数据库数据
六、数据库版本升级
假如我们已经升级到第三个版本了,我们在第二个版本增加了一个表, 然后第三个版本也增加了一个表,加入用户直接从第一个版本升级到第三个版本,这样 没经过第二个版本,就没有增加的那个表....?
public void onUpgrade(SQLiteDatabase db, ConnectionSource connectionSource, int arg2, int arg3) { switch(arg2){ case 1: db.execSQL(第一个版本的建表语句); case 2: db.execSQL(第二个版本的建表语句); case 3: db.execSQL(第三个版本的建表语句); } } 这里并没有写break,这就对了,这是为了保证跨版本升级时,每次数据库 修改都能全部执行到!这样可以保证表结构都是最新的!