这几天状态不太好,所以今天就谈一点,关于android下的sqlite数据库的创建,增删改查的操作以及数据的事务。
创建好工程后,要穿件数据库,我们要用到SQLiteOpenHelper,SQLiteOpenHelper 是用于数据库创建与打开的帮助类。
Java中对数据库的操作流程是:
1、加载jdbc的驱动
2、连接到数据库
3、准备sql语句,增删改查
而android中对数据库的操作可以省去前两步,引用数据库后可以直接使用SQL语句。
首先创建一个继承于数据库的类:
这是工程里出现一个新的类:
PersonSqliteOpenHelper.java:
package com.example.databasesdemo;
/**
* 创建数据库的方法,继承于SQLiteOpenHelper
*/
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class PersonSqliteOpenHelper extends SQLiteOpenHelper {
// 利用SQLiteOpenHelper创建sqlite数据库
public PersonSqliteOpenHelper(Context context) {
super(context, "personInfo.db", null, 1);
}
// 第一次创建数据库时使用
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL("create table personInfo (id integer primary key autoincrement, name varchar(20), number varchar(20))");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
这里还未建立数据库,我们需要测试一下,建立一个android Junit测试类:
代码如下:
package com.example.databasesdemo.test;
import android.test.AndroidTestCase;
import com.example.databasesdemo.PersonSqliteOpenHelper;
public class TestCreateDB extends AndroidTestCase {
public void testCreateDB() throws Exception {
// 创建一个数据库
PersonSqliteOpenHelper helper = new PersonSqliteOpenHelper(getContext());
// 获取一个可写的数据库
helper.getWritableDatabase();
}
}
测试运行后,就会生成一个db文件
这里介绍一个工具,叫SQLite Expert Professional,可以操作db文件,我们把生成的db文件导出到桌面,用这个软件查看:
数据库建立好之后,我们开始对数据库进行增删改查的操作:
之前的PersonSqliteOpenHelper.java中有一个onUpgrade方法没有用,当版本号变化后,就会调用这个方法,例如我们现在将建好的表进行修改,增加一个account条目:(记得要改上面的版本号)
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.i(tag, "数据库版本号变化了");//在日志里写入信息
db.execSQL("alter table personInfo add account varchar(20)");
}
运行然后导出查看db文件:
接下来顺便提一下基本操作的SQL语句:
图片中的内容可以简化为下面的几条例句:
添加语句:insert into person (name,number) values ('zhangsan','110')
查询全部的语句:select * from person
查询具体内容的语句:select * from person where name='zhangsan'
更新条目的语句:update person set number='119' where name = 'zhangsan'
删除一条记录:delete from person where name='zhangsan'
android下有两种方法对数据库操作,一种是直接用SQL语句,还有一种是运用系统API操作,Google工程师将SQL语句封装好了,便于我们使用,在这里,我主要介绍API 的运用,SQL语句的方法会写在下面的代码注释中,以便以后参考其原理。
先自行建立personInfo类,定义其属性,id,name,number,account四个属性。
然后写DAO方法,
personInfoDAO.java:
package com.example.databasesdemo.dao;
import java.util.ArrayList;
import java.util.List;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import com.example.databasesdemo.PersonSqliteOpenHelper;
import com.example.databasesdemo.domain.personInfo;
/**
* 用系统API实现对数据库的操作
*/
public class personInfoDAO {
private PersonSqliteOpenHelper helper;
// 在构造方法里完成helper的初始化
public personInfoDAO(Context context) {
helper = new PersonSqliteOpenHelper(context);
}
// 向数据库添加一条数据
public long add(String name, String number, int string) {
SQLiteDatabase db = helper.getWritableDatabase();
/*
* 之前的方法:
* db.execSQL("insert into personInfo (name,number) values (?,?)", new
* Object[] { name, number });
*/
ContentValues value = new ContentValues();
value.put("name", name);
value.put("number", number);
value.put("account", string);
/*
* Returns:the row ID of the newly inserted row, or -1 if an error
* occurred 可以利用返回值来判断数据是否插入成功
*/
long result = db.insert("personInfo", null, value);
// 操作完数据库记得关闭
db.close();
return result;
}
// 查询记录是否存在
public boolean find(String name) {
SQLiteDatabase db = helper.getReadableDatabase();
/*
* 之前的方法: Cursor cursor =
* db.rawQuery("select * from personInfo where name=?",new String[] {
* name });
*/
Cursor cursor = db.query("personInfo", null, "name=?",
new String[] { name }, null, null, null);
boolean result = cursor.moveToNext();
cursor.close();
db.close();
return result;
}
// 修改条目
public int update(String name, String newNumber) {
SQLiteDatabase db = helper.getReadableDatabase();
/*
* 之前的方法:db.execSQL("update personInfo set number=? where name = ?", new
* Object[] { newNumber, name });
*/
ContentValues value = new ContentValues();
value.put("number", newNumber);
/*
* Return: the number of rows affected
*/
int num = db.update("personInfo", value, "name=?",
new String[] { name });
db.close();
return num;
}
// 删除条目
public int delete(String name) {
SQLiteDatabase db = helper.getWritableDatabase();
/*
* 之前的方法:db.execSQL("delete from personInfo where name='zhangsan'",new
* Object[] { name });
*/
// 返回移除的行数,如果移除失败则返回0
int num = db.delete("personInfo", "name=?", new String[] { name });
db.close();
return num;
}
// 查询返回全部数据库的信息
public List<personInfo> findAll() {
List<personInfo> list = new ArrayList<personInfo>();
SQLiteDatabase db = helper.getReadableDatabase();
/*
* 之前的方法:Cursor cursor = db.rawQuery("select * from personInfo", null);
*/
Cursor cursor = db.query("personInfo", new String[] { "id", "name",
"number" }, null, null, null, null, null);
while (cursor.moveToNext()) {
int id = cursor.getInt(cursor.getColumnIndex("id"));
String name = cursor.getString(cursor.getColumnIndex("name"));
String number = cursor.getString(cursor.getColumnIndex("number"));
int account = cursor.getInt(cursor.getColumnIndex("account"));
personInfo personInfo = new personInfo(id, name, number, account);
list.add(personInfo);
}
db.close();
return list;
}
// 通过姓名查询返回某一个条目
public void fingByName(String name) {
SQLiteDatabase db = helper.getReadableDatabase();
/*
* 之前的方法:Cursor cursor =
* db.rawQuery("select * from personInfo where name = ?", new String[] {
* name });
*/
Cursor cursor = db.query("personInfo", null, "name=?",
new String[] { name }, null, null, null);
int id = cursor.getInt(cursor.getColumnIndex("id"));
String number = cursor.getString(cursor.getColumnIndex("number"));
int account = cursor.getInt(cursor.getColumnIndex("account"));
personInfo personInfo = new personInfo(id, name, number, account);
personInfo.toString();
cursor.close();
db.close();
}
}
接着我们在测试类中进行测试每个DAO方法:
package com.example.databasesdemo.test;
import java.util.List;
import java.util.Random;
import android.test.AndroidTestCase;
import com.example.databasesdemo.PersonSqliteOpenHelper;
import com.example.databasesdemo.dao.personInfoDAO;
import com.example.databasesdemo.domain.personInfo;
public class TestCreateDB extends AndroidTestCase {
public void testCreateDB() throws Exception {
// 创建一个数据库
PersonSqliteOpenHelper helper = new PersonSqliteOpenHelper(getContext());
// 获取一个可写的数据库
helper.getWritableDatabase();
}
public void addTest() throws Exception {
personInfoDAO dao = new personInfoDAO(getContext());
// dao.add("xiaoming", "110", 23445);
// dao.add("xiaohong", "120", 5435);
long number = 4330000l;
Random r = new Random();
for (int i = 0; i < 50; i++) {
dao.add("xiaohong" + i, Long.toString(number + i), r.nextInt(5000));
}
}
public void findTest() throws Exception {
personInfoDAO dao = new personInfoDAO(getContext());
boolean result = dao.find("xiaoming");
assertEquals(true, result);
}
public void updateTest() throws Exception {
personInfoDAO dao = new personInfoDAO(getContext());
dao.update("xiaoming", "120");
}
public void fingByNameTest() throws Exception {
personInfoDAO dao = new personInfoDAO(getContext());
dao.fingByName("xiaoming");
}
public void deleteTest() throws Exception {
personInfoDAO dao = new personInfoDAO(getContext());
dao.delete("xiaoming");
}
public void findAllTest() throws Exception {
personInfoDAO dao = new personInfoDAO(getContext());
List<personInfo> list = dao.findAll();
for (personInfo person : list) {
System.out.println(person.toString());
}
}
}
在这里我要介绍一种工具,可以在cmd命令行中查看sqlite数据库:
操作示例:
这个工具非常非常非常非常的方便,我很喜欢啊啊啊啊~~~
最后一点,我们简单的谈谈数据库的事务,在JavaWeb的数据库阶段大家都学过,这里不赘述,所以把代码贴出来,一看就懂。
这个方法写在测试类中:
// 事务操作
public void transaction() throws Exception {
PersonSqliteOpenHelper helper = new PersonSqliteOpenHelper(getContext());
SQLiteDatabase db = helper.getWritableDatabase();
// 事务的开始
db.beginTransaction();
try {
db.execSQL("update person set account = account-1000 where name=?",
new Object[] { "xiaoming" });
db.execSQL("update person set account = account+1000 where name=?",
new Object[] { "xiaohong" });
// 标记数据库事务执行成功
db.setTransactionSuccessful();
} finally {
db.endTransaction();
db.close();
}
}
这里用到了beginTransaction(),文档中是这样介绍的:
Begins a transaction in EXCLUSIVE mode.
Transactions can be nested. When the outer transaction is ended all of the work done in that transaction and all of the nested transactions will be committed or rolled back. The changes will be rolled back if any transaction is ended without being marked as clean (by calling setTransactionSuccessful). Otherwise they will be committed.
Here is the standard idiom for transactions:
db.beginTransaction();
try {
...
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
按照这个格式就可以了。