2014-10-27Android学习------SQLite数据库操作(一)------城市列表应用程序

2022-03-07 08:37:34 浏览数 (1)

我学习Android都是结合源代码去学习,这样比较直观,非常清楚的看清效果,觉得很好,今天的学习源码是网上找的个CityList 源码 百度搜就知道很多下载的地方 我写的东西有可能比较乱,如果单一的篇章没看明白,请看上一篇文章

上篇文章 地址:http://blog.csdn.net/u014737138/article/details/40593367

数据库的操作方式有很多种 今天要学习的是 如何从资源文件中读取数据库 写入 到当前应用程序在手机上的/data 下

这句话也说明:这种方式是必须有个已经建好的数据库,把这个文件导出来直接放到资源文件下就可以

然后我们只需要 打开数据库 查询数据 关闭数据库 即可 ;在我们的管理类中只需要打开数据库 ,关闭数据库;用到的时候就查询就可以了

1.变量的声明:

private static final String PACKAGE_NAME = "com.city.list.main";//这个包名是你的应用程序在DDMS中file system中data下面的包名,这个位置容易出错,会写成当前的包 public static final String DB_NAME = "china_city_name.db";//这个就是你要创建存到/data下的数据库的名字 public static final String DB_PATH = "/data" Environment.getDataDirectory().getAbsolutePath() "/" PACKAGE_NAME ; // 存放路径

2.把布局文件的数据库文件写到/data下面去

private SQLiteDatabase openDateBase(String dbFile) {//传递进来的是一个数据库文件名 :这个文件就是你要在/data下面存储的数据库名 File file = new File(dbFile);//创建这个文件 if (!file.exists()) {//如果该文件在你的/data下面不存在,那么我们就需要从资源文件中去加载它,就是写进去 // // 打开raw中得数据库文件,获得stream流 InputStream stream = this.mContext.getResources().openRawResource(R.raw.china_city_name);//这个资源索引就是我们存放的数据库 try { // 将获取到的stream 流写入道data中

//我们获取的是一个数据库文件,这个如果你直接打开肯定是乱码,但是起始字段肯定是“SQLite format ”,这个字符串系统懂,它代表着数据库文件 FileOutputStream outputStream = new FileOutputStream(dbFile);//我们把输出流写入到文件dbFile中去 byte[] buffer = new byte[BUFFER_SIZE]; int count = 0; while ((count = stream.read(buffer)) > 0) { outputStream.write(buffer, 0, count);//把输入流的内容写到输出流中, } outputStream.close();//关闭输出流 stream.close();//关闭输入流 SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(dbFile, null); return db; } catch (FileNotFoundException e) { //文件没有找到的异常 // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // 输入输出异常 // TODO Auto-generated catch block e.printStackTrace(); } } return database; }

看下openOrCreateDatabase(dbFile,null)的原型:

1.onpenOrCreateDatabase():

public static SQLiteDatabase openOrCreateDatabase (String path, SQLiteDatabase.CursorFactory factory)

Since: API Level 1

Equivalent to openDatabase(path, factory, CREATE_IF_NECESSARY).

参数:

path

to database file to open and/or create

factory

an optional factory class that is called to instantiate a cursor when query is called, or null for default

2.openDatabase():

public static SQLiteDatabase openDatabase (String path, SQLiteDatabase.CursorFactory factory, int flags)

Since: API Level 1

Open the database according to the flags OPEN_READWRITE OPEN_READONLY CREATE_IF_NECESSARY and/or NO_LOCALIZED_COLLATORS.

Sets the locale of the database to the the system's current locale. Call setLocale(Locale) if you would like something else.

Parameters

path

to database file to open and/or create

factory

an optional factory class that is called to instantiate a cursor when query is called, or null for default

flags

to control database access mode

Returns
  • the newly opened database
Throws

SQLiteException

if the database cannot be opened

3.看看flags的访问模式有哪几种:

public static final int CREATE_IF_NECESSARY

Since: API Level 1

Flag for openDatabase(String, SQLiteDatabase.CursorFactory, int) to create the database file if it does not already exist.

Constant Value: 268435456 (0x10000000)

如果数据库不存在就创建它,意思就是如果在你的文件夹下当前没有这个数据库,那么就执行创建这个数据库文件

上面我们从资源文件raw/china_city_name 把这个文件读到/data/com.wust.citylist/下面,这个文件最开始是没有这样一个名字的数据库,执行这段代码的时候就要去创建它

如果有这个数据库文件的话,就需要去打开它就可以了。

public static final int OPEN_READONLY

Since: API Level 1

Flag for openDatabase(String, SQLiteDatabase.CursorFactory, int) to open the database for reading only. This is the only reliable way to open a database if the disk may be full.

Constant Value: 1 (0x00000001)

public static final int OPEN_READWRITE

Since: API Level 1

Flag for openDatabase(String, SQLiteDatabase.CursorFactory, int) to open the database for reading and writing. If the disk is full, this may fail even before you actually write anything.

Note that the value of this flag is 0, so it is the default.

Constant Value: 0 (0x00000000)

英语的意思说的很清楚就不解释了,自己看吧。

public static final int NO_LOCALIZED_COLLATORS

Since: API Level 1

Flag for openDatabase(String, SQLiteDatabase.CursorFactory, int) to open the database without support for localized collators.

This causes the collator LOCALIZED not to be created. You must be consistent when using this flag to use the setting the database was created with. If this is set, setLocale(Locale) will do nothing.

Constant Value: 16 (0x00000010)

4.经过上面的操作之后,我们就把数据库放到了我们的应用程序文件下面了,接下来就是需要对这个数据库进行操作了

要想操作数据库,必须在类中定义一个数据库变量

1).private SQLiteDatabase database;

2).打开数据库

public void openDateBase() {

// 这个函数就是调用什么的函数,上面函数返回值就是db this.database = this.openDateBase(DB_PATH "/" DB_NAME); }

3).关闭数据库

public void closeDatabase() { if (database != null && database.isOpen()) { this.database.close(); } }

至此:数据库的创建和打开和关闭管理接口就完成了,接下来就是什么时候用到它就调用就好了

5.怎么在其他的类中去调用这个数据库呢?

1).在其他的类中调用它,必须先要申明一个数据库操作变量

private SQLiteDatabase database;

2).在onCreate(Bundle)或者如果不是activity的类的话,需要再构造等函数中初始化

database = SQLiteDatabase.openOrCreateDatabase(DBManager.DB_PATH "/" DBManager.DB_NAME, null);

打开数据之后一定要记得随时关闭它,养成良好的习惯

database.close();

这样一来,数据库的初始化就完成了,我们后面在类中就利用这个database就可以了

3).从数据库中获取查询结果

Cursor cursor = database.rawQuery("SELECT * FROM T_City ORDER BY NameSort", null);

private ArrayList<CityModel> getCityNames() { ArrayList<CityModel> names = new ArrayList<CityModel>(); Cursor cursor = database.rawQuery("SELECT * FROM T_City ORDER BY NameSort", null); for (int i = 0; i < cursor.getCount(); i ) { cursor.moveToPosition(i);// CityModel cityModel = new CityModel(); cityModel.setCityName(cursor.getString(cursor.getColumnIndex("CityName"))); cityModel.setNameSort(cursor.getString(cursor.getColumnIndex("NameSort"))); names.add(cityModel); } return names; }

来看看rawQuery函数的原型:

public Cursor rawQuery (String sql, String[] selectionArgs)

Since: API Level 1

Runs the provided SQL and returns a Cursor over the result set.

Parameters

sql

the SQL query. The SQL string must not be ; terminated

selectionArgs

You may include ?s in where clause in the query, which will be replaced by the values from selectionArgs. The values will be bound as Strings.

Returns
  • A Cursor object, which is positioned before the first entry. Note that Cursors are not synchronized, see the documentation for more details.

参数:sql 就是提供的可以执行的sql语句,对数据库进行操作

参数:selectionArgs[] 就是查询的条件

返回值:是一个游标集

Android采用游标对从数据库中查询出来的结果进行随机的读写访问,在查询数据库后,将结果返回给游标(即android.database.Cursor)

接下来还需要学习一个函数 Cursor.moveToPosition(i)

public abstract boolean moveToPosition (int position)

Since: API Level 1

Move the cursor to an absolute position. The valid range of values is -1 <= position <= count.

This method will return true if the request destination was reachable, otherwise, it returns false.

Parameters

position

the zero-based position to move to.

Returns
  • whether the requested move fully succeeded.

这个函数 说白点就是这个意思: 将Cursor移动到指定位置(绝对位置) ,如果这个位置有值,返回true,如果这个位置没有值,返回false。

也即是说:我们想取游标当前位置的值的时候,最好先判断下该位置是不是有值,也就是数据库中这行有没有值的问题

到这里为止 我们这节就学习完了,

总结下:

这种操作数据库的方式是:

没有封装一个继承SQLiteOpenHelper类的数据库操作类,

没有选择调用getWriteableDatabase()或者getReadableDatabase()方法的时候系统去真正创建数据库

而是选择openOrCreateDatabase(数据库的路径,游标工厂,数据库的访问模式)来create一个数据库

在使用的时候我们定义一个Cursor 创建了一个游标,必须要执行查询操作的,我们采用了rawQuery()

前提条件就是我们已经有了数据库源文件。

0 人点赞