今天想实现一个功能,即在应用安装初始化时,创建本地数据库,同时为数据库添加数据,之后再从数据库中读取数据。
1 首先需要写一个类实现android中的SQLiteOpenHelper类。代码如下:
?
public class DatabaseHelper extends SQLiteOpenHelper { /** *DatabaseHelper作为一个访问SQLite的助手类,提供两个方面的功能 *第一,getReadableDatabase(),getWritableDAtabase()可以获得SQLiteDatabase对象,通过该对象可以对数据库进行操作 *第二,提供了onCreate()和onUpgrade()两个回调函数,允许我们在创建和升级数据库时,进行自己的操作 */ private static final int VERSION=1;// 数据库版本 private static final String NAME="oil.db";//数据库名 public DatabaseHelper(Context context, String name, CursorFactory factory, int version) { super(context, name, factory, version); } public DatabaseHelper(Context context, String name, int version) { this(context, name, null, version); } public DatabaseHelper(Context context) { this(context, NAME, VERSION); } String sql = "CREATE TABLE IF NOT EXISTS car ( _id VARCHAR(50) primary key ," + "company_name VARCHAR(50) , " + "type VARCHAR(50) , " + " general_name VARCHAR(50) ," + "transmission VARCHAR(50) , " + " emission VARCHAR(50)," + "city_consume VARCHAR(50) , " + "suburban_consume VARCHAR(50) ," + "total_consume VARCHAR(50)," + "factor VARCHAR(50)) ;"; //该函数是在第一次创建数据库的时候执行,实际上是在第一次得到SQLiteDatabase对象的时候, //才会调用这个方法 @Override public void onCreate(SQLiteDatabase db) { //创建表 db.execSQL(sql) ; System.out.println("create a database"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { System.out.println("update a database"); }}
?2.判断数据库表中是否有数据,这个可以区分出是否已经对表进行填充了。这个是在CarService中实现的。
?CarService中的构造方法:
private DatabaseHelper openHelper; private SQLiteDatabase sqliteDatabase; private Context mcontext; public CarService(Context context) { //传递上下文对象 mcontext=context; this.openHelper = new DatabaseHelper(context); //得到只读的对象 // sqliteDatabase = openHelper.getReadableDatabase(); if (isExist()) {// 若表中数据为空,则执行插入。 try { initInsert();// 插入初始化数据 } catch (IOException e) { e.printStackTrace(); } } }
?
之后是实现方法:
?
//判断数据库表中是否有数据 public boolean isExist(){ boolean result = true; String sql = "select count(*) count from car"; //sqliteDatabase = sqliteDatabase.openOrCreateDatabase(sql, null); sqliteDatabase = openHelper.getReadableDatabase(); Cursor cursor = sqliteDatabase.rawQuery(sql, null); //System.out.println(cursor.get); if (cursor.moveToNext() ) { int count = cursor.getInt(0); if(count>0){//存在数据 result = false; } cursor.close(); sqliteDatabase.close(); } return result; }
?3 开始往空表中填充数据。这个实现思路是直接把一个文件中的数据(大概1k条左右)写进数据库,因为数据量稍微多点,所以使用事务进行添加。同时这个数据文件car.sql是放在res/raw/文件夹下。我试过跟类放在一起我找不到文件。如果有同志实现了,可以交流下。呵呵。
/** * 通过读取文件,插入初始化数据 * @throws IOException */ public void initInsert() throws IOException { InputStreamReader reader = new InputStreamReader( mcontext.getResources().openRawResource(R.raw.cardata)); BufferedReader br = new BufferedReader(reader); String s1 = ""; sqliteDatabase = openHelper.getWritableDatabase(); //通过事务,进行批量插入 sqliteDatabase.beginTransaction(); while ((s1 = br.readLine()) != null) { //System.out.println(s1); String sql = s1; //System.out.println("sql---"+sql); sqliteDatabase.execSQL(sql); } sqliteDatabase.setTransactionSuccessful(); sqliteDatabase.endTransaction(); br.close(); reader.close(); sqliteDatabase.close(); }
?
我是用按行读取的,比较简便。嘿嘿难一点的,你们自己试吧。
4之后就是查询了。
public List<Car> getCompanyList(long startIndex, long maxCount) throws UnsupportedEncodingException { //路径/data/data/jw.oil/files /* String path=mcontext.getFilesDir().getPath().substring(0); System.out.println(path);*/ String sql = "SELECT DISTINCT(company_name) company_name FROM car "; //String[] selectionArgs = { String.valueOf(startIndex), String.valueOf(maxCount) }; sqliteDatabase = openHelper.getReadableDatabase(); Cursor cursor = sqliteDatabase.rawQuery(sql, null); List<Car> cars = new ArrayList<Car>(); if (cursor.getCount() != 0) {// 如果有数据 while (cursor.moveToNext()) { Car car = new Car(); car.setCompany_name(cursor.getString(0)); System.out.println("----" + car.getCompany_name()); cars.add(car); } cursor.close(); sqliteDatabase.close();//关闭数据库 } else { cars = null; } return cars;}
?
如果填充数据没错,就出现效果了。
?
?
出现问题:因为总是测试,很多时候使用命令行查看数据库。删除应用的时候,只是删除文件夹。有好几次在程序初始化时都会报错:unable to open database file
?查了很多资料,最后才明白是自己的应用没有删干净。建议用模拟器自带的卸载管理。
?