Android提供了一个名为SQLiteDatabase的类,该类封装了一些操作数据库的API,使用该类可以完成对数据进行添加(Create)、查询(Retrieve)、更新(Update)和删除(Delete)操作(这些操作简称为CRUD)。
对SQLiteDatabase的学习,我们应该重点掌握execSQL()和rawQuery()方法。
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});execSQL(String sql, Object[] bindArgs)方法的第一个参数为SQL语句,第二个参数为SQL语句中占位符参数的值,参数值在数组中的顺序要和占位符的位置对应。
使用例子如下:
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是结果集游标,用于对结果集进行随机访问,如果大家熟悉jdbc, 其实Cursor与JDBC中的ResultSet作用很相似。
使用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语句在同一个事务中执行。
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 + "]"; } }
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", "当数据库版本更新的时候执行........每次更新都执行 "); } }
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();}
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(); } } }
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(); } }