Android 漫游之路------SQLite的基本操作、事务管理

---------------------- 路漫漫其修远兮吾将上下而求索。学无止境!----------------------

微笑Sqlite

 

SQLite,是一款轻型的数据库,是遵守ACID的关联式数据库管理系统,它的设计目标是嵌入式的,而且目前已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了。它能够支持Windows/Linux/Unix等等主流的操作系统,同时能够跟很多程序语言相结合,比如 Tcl、C#、PHP、Java等,还有ODBC接口,同样比起Mysql、PostgreSQL这两款开源世界著名的数据库管理系统来讲,它的处理速度比他们都快。SQLite第一个Alpha版本诞生于2000年5月。 至今已经有12个年头,SQLite也迎来了一个版本 SQLite 3已经发布。

 

SQLite的创建:

1.继承SQLiteOpenHelper

2.重写构造函数和抽象方法

3.实现这个继承类

 

PersonSQLiteOpenHelper.java

package com.lee.sql;

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

public class PersonSQLiteOpenHelper extends SQLiteOpenHelper {

	/**
	 * 数据库的构造方法
	 * @param context 
	 * @param name 数据库名字
	 * @param factory 数据库查询的结果集
	 * @param version 数据库版本
	 */
	public PersonSQLiteOpenHelper(Context context) {
		super(context, "Person.db", null, 1);
		// TODO Auto-generated constructor stub
	}

	/**
	 * 数据库第一次被创建
	 */
	@Override
	public void onCreate(SQLiteDatabase db) {
		// TODO Auto-generated method stub
		db.execSQL("create table person (id integer primary key autoincrement,name varchar(20),age integer)");
		
	}

	@Override
	public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {
		// TODO Auto-generated method stub

	}

}

TestPersonDB.java

package com.lee.sql.test;

import java.util.List;

import com.lee.sql.PersonSQLiteOpenHelper;

import android.test.AndroidTestCase;

public class TestPersonDB extends AndroidTestCase {

	public void testCreateDB() throws Exception {
		PersonSQLiteOpenHelper helper = new PersonSQLiteOpenHelper(getContext());
		//没有这一句,数据库不会创建
		helper.getWritableDatabase();
	}
}


SQLite的增删改查,可以使用两种方式,一种是使用sql语句进行操作,而另一种则是使用封装后的api对数据库进行操作:

方式一:使用SQL语句

package com.lee.sql.dao;

import java.util.ArrayList;
import java.util.List;

import com.lee.sql.PersonSQLiteOpenHelper;
import com.lee.sql.model.Person;

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

public class PersonDao {

	private PersonSQLiteOpenHelper helper;

	public PersonDao(Context context) {
		helper = new PersonSQLiteOpenHelper(context);
	}

	/**
	 * 增加学生
	 * 
	 * @param name
	 * @param age
	 */
	public void addPerson(String name, int age) {
		SQLiteDatabase db = helper.getWritableDatabase();
		db.execSQL("insert into person(name,age) values(?,?)", new Object[] {
				name, age });
		db.close();
	}

	/**
	 * 根据姓名删除学生
	 * 
	 * @param name
	 */
	public void deletePerson(String name) {
		SQLiteDatabase db = helper.getWritableDatabase();
		db.execSQL("delete from person where name=?", new Object[] { name });
		db.close();
	}

	/**
	 * 根据姓名修改年龄
	 * 
	 * @param name
	 * @param age
	 */
	public void updataPerson(String name, int age) {
		SQLiteDatabase db = helper.getWritableDatabase();
		db.execSQL("update person set age = ? where name= ?", new Object[] {
				age, name });
		db.close();
	}

	/**
	 * 按照姓名查找,找到返回true
	 * 
	 * @param name
	 * @return
	 */
	public boolean findByName(String name) {
		SQLiteDatabase db = helper.getWritableDatabase();
		// 得到Cursor结果集
		Cursor cursor = db.rawQuery("select * from person where name = ?",
				new String[] { name });
		boolean result = cursor.moveToNext();
		db.close();
		return result;
	}

	/**
	 * 查询所有的信息,返回集合
	 * 
	 * @return
	 */
	public List<Person> findAll() {
		List<Person> persons = new ArrayList<Person>();
		SQLiteDatabase db = helper.getWritableDatabase();
		// 得到Cursor结果集
		Cursor cursor = db.rawQuery("select * from person", null);
		while (cursor.moveToNext()) {
			int id = cursor.getInt(0);
			String name = cursor.getString(1);
			int age = cursor.getInt(2);
			Person person = new Person(name, age, id);
			persons.add(person);
		}
		db.close();
		return persons;
	}

}

方式二:使用封装后的api

package com.lee.sql.dao;

import java.util.ArrayList;
import java.util.List;

import com.lee.sql.PersonSQLiteOpenHelper;
import com.lee.sql.model.Person;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

public class PersonDao2 {

	private PersonSQLiteOpenHelper helper;

	public PersonDao2(Context context) {
		helper = new PersonSQLiteOpenHelper(context);
	}

	/**
	 * 增加学生
	 * 
	 * @param name
	 * @param age
	 */
	public void addPerson(String name, int age) {
		SQLiteDatabase db = helper.getWritableDatabase();
		//ContentValues,类似map
		ContentValues values = new ContentValues();
		values.put("name", name);
		values.put("age", age);
		db.insert("person", null, values);
		db.close();
	}

	/**
	 * 根据姓名删除学生
	 * 
	 * @param name
	 */
	public void deletePerson(String name) {
		SQLiteDatabase db = helper.getWritableDatabase();
		db.delete("person", "name = ?", new String[]{name});
		db.close();
	}

	/**
	 * 根据姓名修改年龄
	 * 
	 * @param name
	 * @param age
	 */
	public void updataPerson(String name, int age) {
		SQLiteDatabase db = helper.getWritableDatabase();
		ContentValues values = new ContentValues();
		values.put("age", age);
		db.update("person", values, "name=?", new String[]{name});
		db.close();
	}

	/**
	 * 按照姓名查找,找到返回true
	 * 
	 * @param name
	 * @return
	 */
	public boolean findByName(String name) {
		SQLiteDatabase db = helper.getWritableDatabase();
		// 得到Cursor结果集
		Cursor cursor = db.query("person", null, "name=?", new String[]{name}, null, null, null);
		boolean result = cursor.moveToNext();
		db.close();
		return result;
	}

	/**
	 * 查询所有的信息,返回集合
	 * 
	 * @return
	 */
	public List<Person> findAll() {
		List<Person> persons = new ArrayList<Person>();
		SQLiteDatabase db = helper.getWritableDatabase();
		// 得到Cursor结果集
		Cursor cursor = db.query("person", null, null, null, null, null, null);
		while (cursor.moveToNext()) {
			int id = cursor.getInt(0);
			String name = cursor.getString(1);
			int age = cursor.getInt(2);
			Person person = new Person(name, age, id);
			persons.add(person);
		}
		db.close();
		return persons;
	}

}

测试类:TestPersonDB.java

package com.lee.sql.test;

import java.util.List;

import com.lee.sql.PersonSQLiteOpenHelper;
import com.lee.sql.dao.PersonDao2;
import com.lee.sql.model.Person;

import android.test.AndroidTestCase;

public class TestPersonDB extends AndroidTestCase {

	public void testCreateDB() throws Exception {
		PersonSQLiteOpenHelper helper = new PersonSQLiteOpenHelper(getContext());
		// 没有这一句,数据库不会创建
		helper.getWritableDatabase();
	}

	/**
	 * 测试添加学生
	 * 
	 * @throws Exception
	 */
	public void testAddPerson() throws Exception {
		PersonDao2 personDao = new PersonDao2(getContext());
		personDao.addPerson("小刚", 12);
	}

	/**
	 * 测试删除学生
	 */
	public void testDeletePerson() {
		PersonDao2 personDao = new PersonDao2(getContext());
		personDao.deletePerson("小刚");
	}

	/**
	 * 测试修改学生信息
	 */
	public void testUpdatePerson() {
		PersonDao2 personDao = new PersonDao2(getContext());
		personDao.updataPerson("xiaohong", 30);
	}

	/**
	 * 测试是否存在某姓名的学生
	 */
	public void TestFindByName() {
		PersonDao2 personDao = new PersonDao2(getContext());
		boolean retVal = personDao.findByName("xiaohong");
		assertEquals(true, retVal);
	}

	/**
	 * 测试查询所有学生,并输出学生信息
	 */
	public void TestFindAll() {
		PersonDao2 personDao = new PersonDao2(getContext());
		List<Person> persons = personDao.findAll();
		for (Person person : persons) {
			System.out.println(person);
		}
	}

}



微笑事务

 

概念

事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。事务通常由高级数据库操纵语言或编程语言(如SQL,C++或Java)书写的用户程序的执行所引起,并用形如begin transactionend transaction语句(或函数调用)来界定。事务由事务开始(begin transaction)和事务结束(end transaction)之间执行的全体操作组成。

例如:在 关系数据库中,一个事务可以是一条SQL语句,一组SQL语句或整个程序。
 
特性
事务是恢复和 并发控制的基本单位。
事务应该具有4个属性:原子性、一致性、隔离性、持久性。这四个属性通常称为 ACID特性
原子性(atomicity)。一个事务是一个不可分割的工作单位,事务中包括的诸操作要么都做,要么都不做。
一致性(consistency)。事务必须是使 数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。
隔离性(isolation)。一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
持久性(durability)。持续性也称永久性(permanence),指一个事务一旦提交,它对 数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。

 

事务的操作:

/**
	 * SQLite的事务管理
	 */
	public void transation() {
		SQLiteDatabase db = helper.getWritableDatabase();
		// 事务开始
		db.beginTransaction();
		//事务的处理
		try {
			db.execSQL("update person set age = age-1 where name = 'xiaohong'");
			db.execSQL("update person set age = age+1 where name = 'xiaolan'");
			//事务处理成功
			db.setTransactionSuccessful();
		} finally {
			//结束事务
			db.endTransaction();
		}

	}

事务管理中的--脏读、不可重复读、幻读

1、脏读:脏读就是指当一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另外一个事务也访问这个数据,然后使用了这个数据。
例如:
  张三的工资为5000,事务A中把他的工资改为8000,但事务A尚未提交。
  与此同时,
  事务B正在读取张三的工资,读取到张三的工资为8000。
  随后,
  事务A发生异常,而回滚了事务。张三的工资又回滚为5000。
  最后,
  事务B读取到的张三工资为8000的数据即为脏数据,事务B做了一次脏读。

2、不可重复读:是指在一个事务内,多次读同一数据。在这个事务还没有结束时,另外一个事务也访问该同一数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改,那么第一个事务两次读到的的数据可能是不一样的。这样就发生了在一个事务内两次读到的数据是不一样的,因此称为是不可重复读。
例如:
  在事务A中,读取到张三的工资为5000,操作没有完成,事务还没提交。
  与此同时,
  事务B把张三的工资改为8000,并提交了事务。
  随后,
  在事务A中,再次读取张三的工资,此时工资变为8000。在一个事务中前后两次读取的结果并不致,导致了不可重复读。

3、幻读:是指当事务不是独立执行时发生的一种现象,例如第一个事务对一个表中的数据进行了修改,这种修改涉及到表中的全部数据行。同时,第二个事务也修改这个表中的数据,这种修改是向表中插入一行新数据。那么,以后就会发生操作第一个事务的用户发现表中还有没有修改的数据行,就好象发生了幻觉一样。
例如:
  目前工资为5000的员工有10人,事务A读取所有工资为5000的人数为10人。
  此时,
  事务B插入一条工资也为5000的记录。
  这是,事务A再次读取工资为5000的员工,记录为11人。此时产生了幻读。

4、提醒
不可重复读的重点是修改:
同样的条件,你读取过的数据,再次读取出来发现值不一样了
幻读的重点在于新增或者删除:
同样的条件,第 1 次和第 2 次读出来的记录数不一样

 

 

---------------------- 路漫漫其修远兮吾将上下而求索。学无止境!---------------------- 

我的博客:http://blog.csdn.net/helloxiaobi

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值