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

来源:互联网 发布:美慧树课堂软件下载 编辑:程序博客网 时间:2024/04/29 07:49

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;}@Overridepublic 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", "构造器......");}// 当数据库第一次创建的时候 执行的方法@Overridepublic 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......创建执行一次");}// 当数据库的版本发生变化的时候执行的方法@Overridepublic 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);}@Overridepublic 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();}}@Overridepublic 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();}}@Overridepublic void delete( Integer id) {SQLiteDatabase db = dbOpenHelper.getWritableDatabase();if (db.isOpen()) {db.execSQL("delete from person where personid=?",new Object[] { id });db.close();}}@Overridepublic 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;}@Overridepublic 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;}@Overridepublic 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;}@Overridepublic long getCount() {SQLiteDatabase db = dbOpenHelper.getWritableDatabase();Cursor cursor = db.rawQuery("select count(*) from person", null);cursor.moveToFirst();return cursor.getLong(0);}@Overridepublic 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();}}