上一篇文章介绍了SQLite的一些基本用法,本篇文章是一个SQLite在项目中的实际例子。
实际开发中,为了能够更好的管理和维护数据库,我们会封装一个继承自SQLiteOpenHelper类的数据库操作类,然后以这个类为基础,再封装我们的业务逻辑方法。
目录结构
DBHelper继承了SQLiteOpenHelper,作为维护和管理数据库的基类,DBManager是建立在DBHelper之上,封装了常用的业务方法,Person是我们的person表对应的JavaBean.
DBHelper
package com.example.daniel.test.db; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; /** * Created by Daniel on 10/12/2015. */ public class DBHelper extends SQLiteOpenHelper { private static final String DATABASE_NAME = "test.db"; private static final int DATABASE_VERSION = 1; public DBHelper(Context context) { //CursorFactory设置为null,使用默认值 super(context, DATABASE_NAME, null, DATABASE_VERSION); } //数据库第一次被创建时onCreate会被调用 @Override public void onCreate(SQLiteDatabase db) { db.execSQL("CREATE TABLE IF NOT EXISTS person" + "(_id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR, age INTEGER, info TEXT)"); } //如果DATABASE_VERSION值被改为2,系统发现现有数据库版本不同,即会调用onUpgrade @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } }
package com.example.daniel.test.db; import android.content.ContentValues; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import java.util.ArrayList; import java.util.List; /** * Created by Daniel on 10/12/2015. */ public class DBManager { private DBHelper helper; private SQLiteDatabase db; public DBManager(Context context) { helper = new DBHelper(context); //因为getWritableDatabase内部调用了mContext.openOrCreateDatabase(mName, 0, mFactory); //所以要确保context已初始化,我们可以把实例化DBManager的步骤放在Activity的onCreate里 db = helper.getWritableDatabase(); } /** * add persons * * @param persons */ public void add(List<Person> persons) { db.beginTransaction(); //开始事务 try { for (Person person : persons) { db.execSQL("INSERT INTO person VALUES(null, ?, ?, ?)", new Object[]{person.name, person.age, person.info}); } db.setTransactionSuccessful(); //设置事务成功完成 } finally { db.endTransaction(); //结束事务 } } /** * update person's age * * @param person */ public void updateAge(Person person) { ContentValues cv = new ContentValues(); cv.put("age", person.age); db.update("person", cv, "name = ?", new String[]{person.name}); } /** * delete old person * * @param person */ public void deleteOldPerson(Person person) { db.delete("person", "age >= ?", new String[]{String.valueOf(person.age)}); } /** * query all persons, return list * * @return List<Person> */ public List<Person> query() { ArrayList<Person> persons = new ArrayList<Person>(); Cursor c = queryTheCursor(); while (c.moveToNext()) { Person person = new Person(); person._id = c.getInt(c.getColumnIndex("_id")); person.name = c.getString(c.getColumnIndex("name")); person.age = c.getInt(c.getColumnIndex("age")); person.info = c.getString(c.getColumnIndex("info")); persons.add(person); } c.close(); return persons; } /** * query all persons, return cursor * * @return Cursor */ public Cursor queryTheCursor() { Cursor c = db.rawQuery("SELECT * FROM person", null); return c; } /** * close database */ public void closeDB() { db.close(); } }
package com.example.daniel.test.db; /** * Created by Daniel on 10/12/2015. */ public class Person { public int _id; public String name; public int age; public String info; public Person() { } public Person(String name, int age, String info) { this.name = name; this.age = age; this.info = info; } }
import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import android.app.Activity; import android.database.Cursor; import android.database.CursorWrapper; import android.os.Bundle; import android.view.View; import android.widget.ListView; import android.widget.SimpleAdapter; import android.widget.SimpleCursorAdapter; public class MainActivity extends Activity { private DBManager mgr; private ListView listView; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); listView = (ListView) findViewById(R.id.listView); //初始化DBManager mgr = new DBManager(this); } @Override protected void onDestroy() { super.onDestroy(); //应用的最后一个Activity关闭时应释放DB mgr.closeDB(); } public void add(View view) { ArrayList<Person> persons = new ArrayList<Person>(); Person person1 = new Person("Ella", 22, "lively girl"); Person person2 = new Person("Jenny", 22, "beautiful girl"); Person person3 = new Person("Jessica", 23, "sexy girl"); persons.add(person1); persons.add(person2); persons.add(person3); mgr.add(persons); } public void update(View view) { Person person = new Person(); person.name = "Jane"; person.age = 30; mgr.updateAge(person); } public void delete(View view) { Person person = new Person(); person.age = 30; mgr.deleteOldPerson(person); } public void query(View view) { List<Person> persons = mgr.query(); ArrayList<Map<String, String>> list = new ArrayList<Map<String, String>>(); for (Person person : persons) { HashMap<String, String> map = new HashMap<String, String>(); map.put("name", person.name); map.put("info", person.age + " years old, " + person.info); list.add(map); } SimpleAdapter adapter = new SimpleAdapter(this, list, android.R.layout.simple_list_item_2, new String[]{"name", "info"}, new int[]{android.R.id.text1, android.R.id.text2}); listView.setAdapter(adapter); } public void queryTheCursor(View view) { Cursor c = mgr.queryTheCursor(); startManagingCursor(c); //托付给activity根据自己的生命周期去管理Cursor的生命周期 CursorWrapper cursorWrapper = new CursorWrapper(c) { @Override public String getString(int columnIndex) { //将简介前加上年龄 if (getColumnName(columnIndex).equals("info")) { int age = getInt(getColumnIndex("age")); return age + " years old, " + super.getString(columnIndex); } return super.getString(columnIndex); } }; //确保查询结果中有"_id"列 SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_2, cursorWrapper, new String[]{"name", "info"}, new int[]{android.R.id.text1, android.R.id.text2}); ListView listView = (ListView) findViewById(R.id.listView); listView.setAdapter(adapter); } }
/** * This method allows the activity to take care of managing the given * {@link Cursor}'s lifecycle for you based on the activity's lifecycle. * That is, when the activity is stopped it will automatically call * {@link Cursor#deactivate} on the given Cursor, and when it is later restarted * it will call {@link Cursor#requery} for you. When the activity is * destroyed, all managed Cursors will be closed automatically. * * @param c The Cursor to be managed. * * @see #managedQuery(android.net.Uri , String[], String, String[], String) * @see #stopManagingCursor */startManagingCursor方法会根据Activity的生命周期去管理当前的Cursor对象的生命周期,就是说当Activity停止时他会自动调用Cursor的deactivate方法,禁用游标,当Activity重新回到屏幕时它会调用Cursor的requery方法再次查询,当Activity摧毁时,被管理的Cursor都会自动关闭释放。