客户端数据库(SQLite)

时间:2021-12-23 19:04:42

</pre><pre name="code" class="plain">

一提到数据库,就不得不提sql语句,确实相对来说sql语句太容易出错了,我们也应该更加的细心

为了方便,安卓倒是把sql语句封装成一个方法,也更方便我们去操作,对此本文对sql不多加涉及

前面的文章提到过持久化技术,SQLite也属于其中一种,相对于SharedPreference它的优点在于能存储更多的数据。

SQLite的有点有以下几种:

1.支持标准的SQL语言

2.遵循了数据库ACID的事务

3.轻量级的关系型数据库


对于数据库的操作无外乎增、删、改、查,当然SQLite还支持事务(事务的特性就是保证让某一系列的操作要么全部完成,要么一个都不会完成,如银行转账)

下面贴一下代码

package com.example.databasetext;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;

public class MyDatabaseHelper extends SQLiteOpenHelper {
	/**
	 * sql语句含义: primary key 主键 autoincrement 自增长 text 文本类型 real 浮点型 integer 整型
	 * blob 二进制型
	 */
	private static final String CREATE_BOOK = "create table Book("
			+ "id integer primary key autoincrement,"
			+ "author text,"
			+ "price real," 
			+ "pages integer," 
			+ "name text"
			+"category_id integer)";//用户新要求增加的一列

	private static final String CREATE_CATRGORY = "create table Category" +
			"(id integer primary key autoincrement," +
			"category_name text," +
			"category_code integer)";

	Context context;

	public MyDatabaseHelper(Context context, String name,
			CursorFactory factory, int version) {
		super(context, name, factory, version);
		this.context = context;

	}
	
	/**
	 * 创建表格
	 */
	@Override
	public void onCreate(SQLiteDatabase db) {
		db.execSQL(CREATE_BOOK);
		db.execSQL(CREATE_CATRGORY);
//		Toast.makeText(context, "Create succeeded", Toast.LENGTH_SHORT).show();
	}
	
	/**
	 * 更新表格
	 * 如何执行onUpgrade()方法,在构造方法中,版本的参数,大于之前输入的参数即可
	 */
	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		/**
		 * DROP语句,如果数据库已经存在Book或者Category表格,就将他们删除
		 * 再重新调用onCreate()创建表格
		 * 如果不删除,出现已经存在的表格就会报错。
		 * 这种方式会造成数据丢失
		 */
//		db.execSQL("drop table if exists Book");
//		db.execSQL("drop table if exists Category");
//		onCreate(db);
		/**
		 * 最佳的更新表格的方式
		 * 注意!!!!不要用break,要保证跨版升级的时候,每一次的数据库修改都能被全部执行到 
		 * 这样可以保证数据库的表结构是最新的,而且表中的数据也不会丢失
		 */
		switch (oldVersion) {
		case 1://如果当前版本是1,只会创建一张 Catrgory表,如果直接安装第二版的话,会两张表一起创建
			//当用户是使用第二版覆盖第一版的时候,就只会创建Catrgort表
			db.execSQL(CREATE_CATRGORY);
		case 2://使用alter命令为Book表增加一个category_id列
			db.execSQL("alter table Bood add colum category_id integer");
		default:
		}
	}

}
关于最佳的更新表格方式,详见郭霖大神的《第一行代码》

package com.example.databasetext;

import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.app.Activity;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

public class MainActivity extends Activity {

	private MyDatabaseHelper dbHelper;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		dbHelper = new MyDatabaseHelper(this, "BookStore", null, 2);
		Button button = (Button) findViewById(R.id.create_database);
		Button addData = (Button) findViewById(R.id.add_data);
		Button updateData = (Button) findViewById(R.id.update_data);
		Button deleteData = (Button) findViewById(R.id.delete_data);
		Button queryData = (Button) findViewById(R.id.query_data);
		Button replaceData = (Button) findViewById(R.id.replace_data);
		/**
		 * 新建或更新数据库的点击事件
		 */
		button.setOnClickListener(new OnClickListener() {
			@Override
			public void onClick(View v) {
				dbHelper.getWritableDatabase();
			}
		});
		/**
		 * 添加数据的点击事件
		 */
		addData.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				// 获取SQLiteDatabase对象
				SQLiteDatabase db = dbHelper.getWritableDatabase();
				// insert添加数据的第三个参数,用于添加数据
				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");
				/**
				 * 第一个参数为表,第二个参数一般为null,第三个参数用来添加数据
				 */
				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);
			}
		});

		/**
		 * 更新数据的点击事件
		 */
		updateData.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				SQLiteDatabase db = dbHelper.getWritableDatabase();
				ContentValues values = new ContentValues();
				values.put("price", 10.99);
				/**
				 * 第三个参数对应的是SQL语句的where部分,表示去更新所有name=?的行。?是一个占位符
				 * 可以通过第四个参数提供的字符串数组为第三个参数中的每个占位符指定相应的内容
				 * 不指定就更新所以行
				 */
				db.update("Book", values, "name = ?",
						new String[] { "The Da Vinci Code" });
			}
		});
		
		/**
		 * 删除数据的点击事件
		 */
		deleteData.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				SQLiteDatabase db = dbHelper.getWritableDatabase();
				db.delete("Book", "pages>?", new String[]{"500"});
			}
		});
		
		/**
		 * 查询数据的点击事件
		 */
		queryData.setOnClickListener(new OnClickListener() {
			
			@Override
			public void onClick(View v) {
				SQLiteDatabase db = dbHelper.getWritableDatabase();
				//查询Book表中所有数据
				Cursor cursor = db.query("Book", null, null, null, null, null, null);
				if (cursor.moveToFirst()) {//将光标设置到第一行,即从第一行开始读取数据
					do {
						//遍历所有Cursor对象,取出数据并打印
						//通过getColumnIndex的索引获取数据
						String name = cursor.getString(cursor.getColumnIndex("name"));
						String author = cursor.getString(cursor.getColumnIndex("author"));
						String pages = cursor.getString(cursor.getColumnIndex("pages"));
						String price = cursor.getString(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();//要关闭cursor
			}
		});
		
		/**
		 * 事务的点击事件
		 * 使用事物替换后的数据,主键依然会自增长,如果最后的数据是9,就会增长为10
		 * 如果最后的数据是删除掉的10,也会增长为11
		 */
		replaceData.setOnClickListener(new OnClickListener() {
			
			@Override
			public 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();//结束事务
				}
			}
		});
	}

}