android(18)_数据存储与访问_SQLite数据库_使用SQLiteDatabase操作SQLite数据库及事务

Android提供了一个名为SQLiteDatabase的类,该类封装了一些操作数据库的API,使用该类可以完成对数据进行添加(Create)、查询(Retrieve)、更新(Update)和删除(Delete)操作(这些操作简称为CRUD)。

execSQL()和rawQuery()方法。

对SQLiteDatabase的学习,我们应该重点掌握execSQL()和rawQuery()方法。 

  • execSQL()方法可以执行insert、delete、updateCREATE TABLE之类有更改行为的SQL语句;
    • execSQL()方法的使用例子:

      SQLiteDatabase db = ....;

      db.execSQL("insert into person(name, age) values('CSDN', 4)");

      db.close();

      执行上面SQL语句会往person表中添加进一条记录,在实际应用中, 语句中的“csdn”这些参数值会由用户输入界面提供,如果把用户输入的内容原样组拼到上面的insert语句, 当用户输入的内容含有单引号时,组拼出来的SQL语句就会存在语法错误。要解决这个问题需要对单引号进行转义,也就是把单引号转换成两个单引号。有些时候用户往往还会输入像“ & ”这些特殊SQL符号,为保证组拼好的SQL语句语法正确,必须对SQL语句中的这些特殊SQL符号都进行转义,显然,对每条SQL语句都做这样的处理工作是比较烦琐的。 SQLiteDatabase类提供了一个重载后的execSQL(String sql, Object[] bindArgs)方法,使用这个方法可以解决前面提到的问题,因为这个方法支持使用占位符参数(?)。使用例子如下:

      SQLiteDatabase db = ....;

      db.execSQL("insert into person(name, age) values(?,?)", new Object[]{"CSDN", 4}); 
      db.close();

      execSQL(String sql, Object[] bindArgs)方法的第一个参数为SQL语句,第二个参数为SQL语句中占位符参数的值,参数值在数组中的顺序要和占位符的位置对应。


  •  rawQuery()方法可以执行select语句。
    • 使用例子如下:  

      SQLiteDatabase db = ....;
      Cursor cursor = db.rawQuery(“select * from person”, null);
      while (cursor.moveToNext()) {
      int personid = cursor.getInt(0); //获取第一列的值,第一列的索引从0开始
      String name = cursor.getString(1);//获取第二列的值
      int age = cursor.getInt(2);//获取第三列的值
      }
      cursor.close();
      db.close(); 

      rawQuery()方法的第一个参数为select语句;

      第二个参数为select语句中占位符参数的值,如果select语句没有使用占位符,该参数可以设置为null。

      带占位符参数的select语句使用例子如下:
      Cursor cursor = db.rawQuery("select * from person where name like ? and age=?", new String[]{"%传智%", "4"});

Cursor

Cursor是结果集游标,用于对结果集进行随机访问,如果大家熟悉jdbc, 其实Cursor与JDBC中的ResultSet作用很相似。

  • moveToNext()方法可以将游标从当前行移动到下一行,如果已经移过了结果集的最后一行,返回结果为false,否则为true。
  • moveToPrevious()方法(用于将游标从当前行移动到上一行,如果已经移过了结果集的第一行,返回值为false,否则为true )
  • moveToFirst()方法(用于将游标移动到结果集的第一行,如果结果集为空,返回值为false,否则为true )
  • moveToLast()方法(用于将游标移动到结果集的最后一行,如果结果集为空,返回值为false,否则为true ) 。

事务

使用SQLiteDatabase的beginTransaction()方法可以开启一个事务,程序执行到endTransaction() 方法时会检查事务的标志是否为成功,如果程序执行到endTransaction()之前调用了setTransactionSuccessful()方法设置事务的标志为成功则提交事务,如果没有调用setTransactionSuccessful() 方法则回滚事务。

使用例子如下:  

SQLiteDatabase db = ....;
db.beginTransaction();//开始事务
try {
    db.execSQL("insert into person(name, age) values(?,?)", new Object[]{"传智播客", 4});
    db.execSQL("update person set name=? where personid=?", new Object[]{"传智", 1});
    db.setTransactionSuccessful();//调用此方法会在执行到endTransaction() 时提交当前事务,如果不调用此方法会回滚事务
} finally {
    db.endTransaction();//由事务的标志决定是提交事务,还是回滚事务

db.close(); 

上面两条SQL语句在同一个事务中执行。

实例

Person.java

package com.example.lession04_db.domain;

import java.io.Serializable;

/**
 * 封装的数据库实体bean
 * @author zhaoyazhi
 *
 */
public class Person implements Serializable {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private Integer id;
	private String name;
	private Integer age;
	private Integer account;

	public Person() {
		super();
		// TODO Auto-generated constructor stub
	}

	public Person(Integer id, String name, Integer age, Integer account) {
		super();
		this.id = id;
		this.name = name;
		this.age = age;
		this.account = account;
	}

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Integer getAge() {
		return age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}

	public Integer getAccount() {
		return account;
	}

	public void setAccount(Integer account) {
		this.account = account;
	}

	@Override
	public String toString() {
		return "Person [id=" + id + ", name=" + name + ", age=" + age
				+ ", account=" + account + "]";
	}

}


DBOpenHelper.java

package com.example.lession04_db.db;

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

public class DBOpenHelper extends SQLiteOpenHelper {
	// 数据库的名称
	private static final String name = "CSDN.db";
	// 数据库的版本
	private static final int version = 2;

	public DBOpenHelper(Context context) {
		// 第三个参数CursorFactory指定在执行查询时获得一个游标实例的工厂类,设置为null,代表使用系统默认的工厂类
		super(context, name, null, version);
		Log.v("DBSQLiteOpenHelper", "构造器......");
	}

	// 当数据库第一次创建的时候 执行的方法
	@Override
	public void onCreate(SQLiteDatabase db) {
		// execSQL来执行sql语句
		db.execSQL("create table person(personid integer primary key autoincrement,name varchar(20),age integer )");

		Log.v("DBSQLiteOpenHelper", "onCreate......创建执行一次");
	}

	// 当数据库的版本发生变化的时候执行的方法
	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		db.execSQL("alter table person add account integer");
		Log.v("DBSQLiteOpenHelper", "当数据库版本更新的时候执行........每次更新都执行 ");
	}

}


PersonDao.java

package com.example.lession04_db.dao;

import java.util.List;

import com.example.lession04_db.domain.Person;

import android.database.sqlite.SQLiteDatabase;


public interface PersonDao {

	
	/**
	 * 插入数据
	 * @param db
	 * @param entity
	 */
	public void insert(Person entity);
	/**
	 * 更新数据
	 * @param db
	 * @param entity
	 */
	public void update(Person entity);
	/**
	 * 删除数据
	 * @param db
	 * @param id
	 */
	public void delete(Integer id);
	/**
	 * 查询所有数据
	 * @param db
	 * @return
	 */
	public List<Person> findAll();
	
	/**
	 * 获取当前页信息
	 * @param db
	 * @param nowpage
	 * @param pagesize
	 * @return
	 */
	public List<Person> getNowPageInfo(int nowpage,int pagesize);
	
	/**
	 * 根据用户的id查询用户信息(条件查询)
	 * @param db
	 * @param id
	 * @return
	 */
	public Person findById(Integer id);
	
	/**
	 * 获取总记录
	 * @param db
	 * @return
	 */
	public long getCount();
       /**
	 * 事务处理
	 * @param db
	 * @return
	 */
void payment();}


PersonDaoImpl.java

package com.example.lession04_db.dao;

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

import com.example.lession04_db.db.DBOpenHelper;
import com.example.lession04_db.db.DBSQLiteOpenHelper;
import com.example.lession04_db.domain.Person;

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


public class PersonDaoImpl implements PersonDao {
	private DBOpenHelper dbOpenHelper;

	public PersonDaoImpl(Context context) {
		super();
		dbOpenHelper = new DBOpenHelper(context);
	}
	@Override
	public void insert(Person entity) {
		SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
		if (db.isOpen()) {
			db.execSQL(
					"insert into person(name,age,account) values(?,?,?)",
					new Object[] { entity.getName(), entity.getAge(),
							entity.getAccount() });
			db.close();
		}
	}

	@Override
	public void update( Person entity) {
		SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
		if (db.isOpen()) {
			db.execSQL(
					"update person set name=?,age=?,account=? where personid=?",
					new Object[] { entity.getName(), entity.getAge(),
							entity.getAccount(), entity.getId() });
			db.close();
		}

	}

	@Override
	public void delete( Integer id) {
		SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
		if (db.isOpen()) {
			db.execSQL("delete from person where personid=?",
					new Object[] { id });
			db.close();
		}

	}

	@Override
	public List<Person> findAll() {
		List<Person> persons = new ArrayList<Person>();
		SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
		if (db.isOpen()) {
			// 查询
			Cursor cursor = db.rawQuery(
					"select personid,name,age,account from person", null);
			// 判断是否含有下一个
			while (cursor.moveToNext()) {
				// 创建person对象
				Person person = new Person();
				// 为对象的属性赋值
				person.setId(cursor.getInt(0));
				person.setName(cursor.getString(1));
				person.setAge(cursor.getInt(2));
				person.setAccount(cursor.getInt(3));
				// 添加到集合中
				persons.add(person);
			}
		}

		return persons;
	}

	@Override
	public List<Person> getNowPageInfo( int nowpage,
			int pagesize) {
		SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
		// 开始记录
		int start = (nowpage - 1) * pagesize;

		List<Person> persons = new ArrayList<Person>();
		if (db.isOpen()) {
			// 查询
			Cursor cursor = db.rawQuery("select personid,name,age,account from person limit ?,?",
					new String[] { start + "", pagesize + "" });
			// 判断是否含有下一个
			while (cursor.moveToNext()) {
				// 创建person对象
				Person person = new Person();
				// 为对象的属性赋值
				person.setId(cursor.getInt(0));
				person.setName(cursor.getString(1));
				person.setAge(cursor.getInt(2));
				person.setAccount(cursor.getInt(3));
				// 添加到集合中
				persons.add(person);
			}
		}

		return persons;

	}

	@Override
	public Person findById( Integer id) {
		SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
		Person person =null;
		if (db.isOpen()) {
			// 查询
			Cursor cursor = db.rawQuery("select personid,name,age,account from person where personid = ?", new String[]{""+id});
			// 判断是否含有下一个
			if (cursor.moveToNext()) {
				person = new Person();
				// 创建person对象
				// 为对象的属性赋值
				person.setId(cursor.getInt(0));
				person.setName(cursor.getString(1));
				person.setAge(cursor.getInt(2));
				person.setAccount(cursor.getInt(3));

			}
		}

		return person;
	}
	@Override
	public long getCount() {
		SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
		Cursor cursor = db.rawQuery("select count(*) from person", null);
		cursor.moveToFirst();

		return cursor.getLong(0);

	}
	@Override
	public void payment() {
		SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
		db.beginTransaction();
		try {
			db.execSQL("update person set account=account-10 where personid=?",
					new Object[] { 1 });
			db.execSQL("update person set account=account+10 where personid=?",
					new Object[] { 2 });
			db.setTransactionSuccessful();// 设置事务标志为成功,在事务结束时才会提供事务,否则回滚事务

		} finally {
			db.endTransaction();
		}

	}

}


DBTest.java

package com.example.lession04_db.test;

import java.util.List;

import com.example.lession04_db.dao.PersonDao;
import com.example.lession04_db.dao.PersonDaoImpl;
import com.example.lession04_db.db.DBOpenHelper;
import com.example.lession04_db.domain.Person;

import android.database.sqlite.SQLiteDatabase;
import android.test.AndroidTestCase;
import android.util.Log;

public class DBTest extends AndroidTestCase {
	private static final String TAG = "DBTest";
	private PersonDao personDao;

	public void testDBCreate() throws Exception {
		DBOpenHelper dbOpenHelper = new DBOpenHelper(this.getContext());
		dbOpenHelper.getWritableDatabase();
	}

	public void insert() {
		// 创建数据库管理的对象
		personDao = new PersonDaoImpl(this.getContext());
		// 获取SQLiteDatabase实例对象才能创建数据库
		for (int i = 1; i < 10; i++) {
			Person entity = new Person(null, "zyz" + i, 20 + i, 1000 + i);
			personDao.insert(entity);
		}

	}

	public void update() {
		personDao = new PersonDaoImpl(this.getContext());

		Person entity = new Person(1, "xinxt", 29, 10000 * 2);

		personDao.update( entity);

	}

	public void delete() {

		personDao = new PersonDaoImpl(this.getContext());

		personDao.delete(  1);

	}

	public void findAll() {
		personDao = new PersonDaoImpl(this.getContext());
		List<Person> persons = personDao.findAll();

		for (Person p : persons) {
			System.out.println(p.toString());
		}
	}

	public void getNowPageInfo() {

		personDao = new PersonDaoImpl(this.getContext());

		List<Person> persons = personDao.getNowPageInfo( 1, 5);

		for (Person p : persons) {
			System.out.println(p.toString());
		}
	}

	public void findById() {

		personDao = new PersonDaoImpl(this.getContext());
		Person p = personDao.findById(  2);

		if (p != null) {
			System.out.println(p.toString());
		}

	}

	public void testCount() throws Throwable {
		personDao = new PersonDaoImpl(this.getContext());
		Log.i(TAG, personDao.getCount( ) + "");
	}

	// 有关事务的处理方式
	public void testTransaction() {
		// 创建数据库管理的对象
		DBOpenHelper db = new DBOpenHelper(this.getContext());
		// 获取SQLiteDatabase实例对象才能创建数据库
		SQLiteDatabase sdb = db.getWritableDatabase();

		Person entity = new Person(null, "xxxz", 30, 1000);

		sdb.beginTransaction();// 开启事务
		try {

			// 执行的第一个sql语句
			sdb.execSQL(
					"insert into person(name,age,account) values(?,?,?)",
					new Object[] { entity.getName(), entity.getAge(),
							entity.getAccount() });

			entity = new Person(10, "zzzxx", 30, 1000);

			// int i=1/0;
			// 执行的第二个sql语句
			sdb.execSQL(
					"update person set name=?,age=?,account=? where personid=?",
					new Object[] { entity.getName(), entity.getAge(),
							entity.getAccount(), entity.getId() });
			sdb.setTransactionSuccessful(); // 提交事务
		} catch (Exception e) {
			Log.v("csdn", e.getMessage());
		} finally {
			sdb.endTransaction();// 结束事务
		}
		sdb.close();

	}
	public void testPayment() throws Throwable {
		personDao = new PersonDaoImpl(this.getContext());
		personDao.payment();
	}
}



你可能感兴趣的:(数据库,android,sqlite,数据存储)