Android自学之sqlite数据的基本操作和事物的简单应用

来源:互联网 发布:大疆地面站软件下载 编辑:程序博客网 时间:2024/06/10 20:29

  SQLite 是一款轻量级的关系型数据库, 它的运算速度非常快,占用资源很少, 通常只需要几百 K的内存就足够了, 因而特别适合在移动设备上使用。 SQLite不仅支持标准的 SQL 语法,还遵循了数据库的 ACID 事务,所以只要你以前使用过其他的关系型数据库,就可以很快地上手 SQLite。而 SQLite 又比一般的数据库要简单得多,它甚至不用设置用户名和密码就可以使用。Android正是把这个功能极为强大的数据库嵌入到了系统当中,使得本地持久化的功能有了一次质的飞跃。

前面一篇关于SharedPreferences存储毕竟只适用于去保存一些简单的数据和键值对,当需要存储大量复杂的关系型数据的时候,你就会发现以上两种存储方式很难应付得了。比如我们手机的短信程序中可能会有很多个会话,每个会话中又包含了很多条信息内容,并且大部分会话还可能各自对应了电话簿中的某个联系人。很难想象如何用文件或者SharedPreferences来存储这些数据量大、结构性复杂的数据吧?但是使用数据库就可以做得到。


具体流程就贴代码吧

xml代码:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"  >   <Button        android:id="@+id/create_database"       android:layout_width="match_parent"       android:layout_height="wrap_content"       android:text="Create database"/>   <Buttonandroid:id="@+id/add_data"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="Add data"/>      <Buttonandroid:id="@+id/update_data"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="Update data"/>      <Buttonandroid:id="@+id/delete_data"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="Delete data"/>      <Buttonandroid:id="@+id/query_data"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="Query data"/>      <Buttonandroid:id="@+id/replace_data"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="Replace data"/>   </LinearLayout>


java代码:

MyDatabaseHelper.java

package com.example.databasetest;import android.content.Context;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteDatabase.CursorFactory;import android.database.sqlite.SQLiteOpenHelper;import android.widget.Toast;public class MyDatabaseHelper extends SQLiteOpenHelper {public static final String CREATE_BOOK = "create table book ("+ "id integer primary key autoincrement, "+ "author text, "+ "price real, "+ "pages integer, "+ "name text)";public static final String CREATE_CATEGORY = "create table Category ("+ "id integer primary key autoincrement, "+ "category_name text, "+ "category_code integer)";private Context mContext;public MyDatabaseHelper(Context context, String name, CursorFactory factory, int version){super(context, name, factory, version);mContext = context;}@Overridepublic void onCreate(SQLiteDatabase db) {// TODO Auto-generated method stubdb.execSQL(CREATE_BOOK);db.execSQL(CREATE_CATEGORY);Toast.makeText(mContext, "Create succeeded", Toast.LENGTH_SHORT).show();}//用于对数据库升级  插入新表,如果数据库本身已存在,则调用次函数,删除两张表,然后重新调用onCreate@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {// TODO Auto-generated method stub//db.execSQL("drop table if exists Book");//db.execSQL("drop table if exists Category");//onCreate(db);switch (oldVersion) {case 1:db.execSQL(CREATE_CATEGORY);case 2:db.execSQL("alter table Book add column category_id integer");default:}//这里请注意一个非常重要的细节,switch 中每一个 case的最后都是没有使用 break的,//为什么要这么做呢?这是为了保证在跨版本升级的时候, 每一次的数据库修改都能被全部执//行到。比如用户当前是从第二版程序升级到第三版程序的,那么 case 2中的逻辑就会执行。//而如果用户是直接从第一版程序升级到第三版程序的,那么 case 1和 case 2中的逻辑都会执//行。使用这种方式来维护数据库的升级,不管版本怎样更新,都可以保证数据库的表结构是//最新的,而且表中的数据也完全不会丢失了。}}

MainActivity.java

package com.example.databasetest;import java.io.File;import android.os.Bundle;import android.os.Environment;import android.app.Activity;import android.content.ContentValues;import android.database.Cursor;import android.database.sqlite.SQLiteDatabase;import android.util.Log;import android.view.Menu;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.Toast;public class MainActivity extends Activity {private MyDatabaseHelper dbHelper;public static final String ExtSD_PATH = Environment.getExternalStorageDirectory().getPath();public static final String SYS_PATH = ExtSD_PATH + "/HC-DT5X"; @Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);//String string = Environment.getExternalStorageDirectory().getPath();//判断文件夹是否存在 File sysFolder = new File(SYS_PATH);                  if (!sysFolder.exists()){          sysFolder.mkdirs();          } dbHelper = new MyDatabaseHelper(this, SYS_PATH + "/BookStore.db", null, 3);Button createDatabase = (Button) findViewById(R.id.create_database);createDatabase.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {dbHelper.getWritableDatabase();}});Button addData = (Button) findViewById(R.id.add_data);addData.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubSQLiteDatabase db = dbHelper.getWritableDatabase();ContentValues values = new ContentValues();//开始组装第一条数据values.put("name", "The Da Vinci Code");values.put("author", "Dan Brown");values.put("pages", 454);values.put("price", 16.96);db.insert("Book", null, values);//插入数据values.clear();//开始组装第二条数据values.put("name", "The Lost Symbol");values.put("author", "Dan Brown");values.put("pages", 510);values.put("price", 19.95);db.insert("Book", null, values);//db.execSQL("insert into Book (name, author, pages, price) values(?, ?, ?, ?)",//new String[] { "The Da Vinci Code", "Dan Brown", "454", "16.96" });//db.execSQL("insert into Book (name, author, pages, price) values(?, ?, ?, ?)",//new String[] { "The Lost Symbol", "Dan Brown", "510", "19.95" });//Toast.makeText(MainActivity.this, "Insert succeeded", Toast.LENGTH_SHORT).show();}});Button updateData = (Button) findViewById(R.id.update_data);updateData.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {SQLiteDatabase db = dbHelper.getWritableDatabase();ContentValues values = new ContentValues();values.put("price", 10.99);db.update("Book", values, "name = ?", new String[] { "The Da Vinci Code" });//更新数据库//db.execSQL("update Book set price = ? where name = ?", new String[] { "10.99",//"The Da Vinci Code" });//Toast.makeText(MainActivity.this, "Update succeeded", Toast.LENGTH_SHORT).show();}});Button deleteButton = (Button) findViewById(R.id.delete_data);deleteButton.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {SQLiteDatabase db = dbHelper.getWritableDatabase();db.delete("Book", "pages > ?", new String[] { "500" });//删除数据//db.execSQL("delete from Book where pages > ?", new String[] { "500" });//Toast.makeText(MainActivity.this, "Del succeeded", Toast.LENGTH_SHORT).show();}});Button queryButton = (Button) findViewById(R.id.query_data);queryButton.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {SQLiteDatabase db = dbHelper.getWritableDatabase();//db.rawQuery("select * from Book", null);// 查询Book表中所有的数据Cursor cursor = db.query("Book", null, null, null, null, null, null);if (cursor.moveToFirst()) {do {// 遍历Cursor对象,取出数据并打印String name = cursor.getString(cursor.getColumnIndex("name"));String author = cursor.getString(cursor.getColumnIndex("author"));int pages = cursor.getInt(cursor.getColumnIndex("pages"));double price = cursor.getDouble(cursor.getColumnIndex("price"));Log.d("MainActivity", "book name is " + name);Log.d("MainActivity", "book author is " + author);Log.d("MainActivity", "book pages is " + pages);Log.d("MainActivity", "book price is " + price);} while (cursor.moveToNext());}cursor.close();}});//事物的应用Button replaceData = (Button) findViewById(R.id.replace_data);replaceData.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {SQLiteDatabase db = dbHelper.getWritableDatabase();db.beginTransaction(); // 开启事务try {db.delete("Book", null, null);//if (true) {//// 在这里手动抛出一个异常,让事务失败//throw new NullPointerException();//}ContentValues values = new ContentValues();values.put("name", "Game of Thrones");values.put("author", "George Martin");values.put("pages", 720);values.put("price", 20.85);db.insert("Book", null, values);db.setTransactionSuccessful(); // 事务已经执行成功} catch (Exception e) {e.printStackTrace();} finally {db.endTransaction(); // 结束事务}}});}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.main, menu);return true;}}


注意:

主要的流程都完成了,但并不代表所有工作都完成了,现在最重要的一步是别忘记在AndroidManifest.xml中给文件添加可读和可写的权限(因为数据库本身也是文件哦),当然如果你已经添加过那就没有问题了,下边红色的字体:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/></span>

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.example.databasetest"    android:versionCode="1"    android:versionName="1.0" >    <uses-sdk        android:minSdkVersion="8"        android:targetSdkVersion="17" />   <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>     <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>        <uses-permission android:name="android.permission.WRITE_SETTINGS" />    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" >    </uses-permission>    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" >    </uses-permission>    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" >    </uses-permission>    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" >    </uses-permission>    <uses-permission android:name="android.permission.INTERNET" />            <uses-permission android:name="android.permission.READ_PHONE_STATE" />        <application        android:allowBackup="true"        android:icon="@drawable/ic_launcher"        android:label="@string/app_name"        android:theme="@style/AppTheme" >        <activity            android:name="com.example.databasetest.MainActivity"            android:label="@string/app_name" >            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>    </application></manifest>



到这里所有工作都已经完成了,可以手动去运行试试哦,具体代码我会传到csdn上。。。

















1 0
原创粉丝点击