---------------------- 路漫漫其修远兮,吾将上下而求索。学无止境!----------------------
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 transaction和end transaction语句(或函数调用)来界定。事务由事务开始(begin transaction)和事务结束(end transaction)之间执行的全体操作组成。
事务的操作:
/**
* 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 次读出来的记录数不一样
---------------------- 路漫漫其修远兮,吾将上下而求索。学无止境!----------------------