Android -- SQLite 数据库创建,增删改查,事务处理
1. 概述
在Android平台上,集成了一个嵌入式关系型数据库—SQLite,SQLite3支持
NULL、INTEGER、REAL(浮点数字)、TEXT(字符串文本)和BLOB(二进制对象)数据类型,虽然它支持的类型只有五种,但实际上sqlite3也接受varchar(n)、char(n)、decimal(p,s)
等数据类型,只不过在运算或保存时会转成对应的五种数据类型。 SQLite最大的特点是你可以把各种类型的数据保存到任何字段中,而不用关心字段声明的数据类型是什么。例如:可以在Integer类型的字段中存放字符串,或者在布尔型字段中存放浮点数,或者在字符型字段中存放日期型值。但有一种情况例外:定义为INTEGER
PRIMARY KEY的字段只能存储64位整数, 当向这种字段保存除整数以外的数据时,将会产生错误。 另外,
SQLite 在解析CREATE TABLE
语句时,会忽略 CREATE TABLE
语句中跟在字段名后面的数据类型信息,如下面语句会忽略 name字段的类型信息:
CREATE TABLE person (personid integer primary key autoincrement, name varchar(20))
SQLite可以解析大部分标准SQL语句,如:
查询语句:select * from
表名 where
条件子句 group by
分组字句 having ... order by
排序子句
如:select * from person
select * from person order by id desc
select name from person group by name having count(*)>1
分页SQL与mysql类似,下面SQL语句获取5条记录,跳过前面3条记录
select * from Account limit 5 offset 3 或者
select * from Account limit 3,5
插入语句:insert into
表名(字段列表) values(值列表)。如:
insert into person(name, age) values(‘传智’,3)
更新语句:update
表名 set 字段名=值
where 条件子句。如:update person set name=‘传智‘
where id=10
删除语句:delete from
表名 where 条件子句。如:delete from person
where id=10
为了实现对数据库版本进行管理,SQLiteOpenHelper类提供了两个重要的方法,分别是onCreate(SQLiteDatabase db)和onUpgrade(SQLiteDatabase
db, int oldVersion, int newVersion),前者用于初次使用软件时生成数据库表,后者用于升级软件时更新数据库表结构。当调用SQLiteOpenHelper的getWritableDatabase()或者getReadableDatabase()方法获取用于操作数据库的SQLiteDatabase实例的时候,如果数据库不存在,Android系统会自动生成一个数据库,接着调用onCreate()方法,onCreate()方法在初次生成数据库时才会被调用,在onCreate()方法里可以生成数据库表结构及添加一些应用使用到的初始化数据。onUpgrade()方法在数据库的版本发生变化时会被调用,一般在软件升级时才需改变版本号,而数据库的版本是由程序员控制的,假设数据库现在的版本是1,由于业务的变更,修改了数据库表结构,这时候就需要升级软件,升级软件时希望更新用户手机里的数据库表结构,为了实现这一目的,可以把原来的数据库版本设置为2(有同学问设置为3行不行?当然可以,如果你愿意,设置为100也行),并且在onUpgrade()方法里面实现表结构的更新。当软件的版本升级次数比较多,这时在onUpgrade()方法里面可以根据原版号和目标版本号进行判断,然后作出相应的表结构及数据更新。
public class DatabaseHelper extends SQLiteOpenHelper {
//类没有实例化,是不能用作父类构造器的参数,必须声明为静态
private static final String name = "itcast";//数据库名称
private static final int version = 1; //数据库版本
public DatabaseHelper(Context context) {
//第三个参数CursorFactory指定在执行查询时获得一个游标实例的工厂类,设置为null,代表使用系统默认的工厂类
super(context, name, null, version);
}
@Override public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE IF NOT EXISTS person (personid integer primary key autoincrement, name varchar(20), age INTEGER)");
}
@Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL(" ALTER TABLE person ADD phone VARCHAR(12) NULL ");//往表中增加一列
// DROP TABLE IF EXISTS person
删除表
}
}
在实际项目开发中,当数据库表结构发生更新时,应该避免用户存放于数据库中的数据丢失。
Android sqlite3工具的使用
1 cmd à adb shell
首先挂载到linux
2 cd data/data/com.android.contacts.provider
3 cd database
4 sqlite3 contacts 打开数据库
eg: sqlite3 contacts.db
5 .tables 查看所有的表
eg: .table
6 .schema 查看所有的创建表、视图的语句
eg: .schema
7 .help 查看帮助
eg: .help
8 .header(s) NO |OFF是否显示列头信息
eg: headers ON
9 .mode MODE ?table?
指定数据显示风格 eg: .mode column
10 .nullValue NULL空值数据显示问题
eg: .nullValue NULL
2. 示例代码
NoteSQLiteOpenHelper.java, 继承实现抽象类SQLiteOpenHelper
public class NoteSQLiteOpenHelper extends SQLiteOpenHelper { private static final String TAG = "NoteSQLiteOpenHelper";
/**
* context 上下文 name 数据库的名称 cursorfactory 游标工厂 一般设置null 默认游标工厂 version 数据库的版本
* 版本号从1开始的
*
* @param context
*/
public NoteSQLiteOpenHelper(Context context) {
super(context, "note.db", null, 3);
} /**
* oncreate 方法 会在数据库第一创建的时候的是被调用 适合做数据库表结构的初始化
*/
@Override
public void onCreate(SQLiteDatabase db) {
Log.i(TAG, "oncreate 方法被调用了...");
db.execSQL("create table account (id integer primary key autoincrement , name varchar(20), money varchar(20) )");
} /*
* 当数据库的版本号发生变化的时候,会调用这个方法
*/
@Override
public void onUpgrade(SQLiteDatabase db, int arg1, int arg2) {
Log.i(TAG,"onupdate 方法被调用了 ,在这个方法里面做更新数据库表结构的操作");
//db.execSQL(sql); //alter table account add ... 添加修改表结构语句
} }
NoteBean.java, javabean
public class NoteBean {
private int id;
private float money;
private String name; @Override
public String toString() {
return "NoteBean [id=" + id + ", money=" + money + ", name=" + name
+ "]";
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public float getMoney() {
return money;
}
public void setMoney(float money) {
this.money = money;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public NoteBean(int id, float money, String name) {
this.id = id;
this.money = money;
this.name = name;
}
public NoteBean(){ } }
NoteDao.java, dao接口实现, 方式一:直接用SQL语句
/**
* 记账本的dao
*
* @author Administrator
*
*/
public class NoteDao {
// 因为 任何一个操作都是需要 得到 NoteSQLiteOpenHelper helper
// 把他放在构造方法里面初始化
private NoteSQLiteOpenHelper helper; public NoteDao(Context context) {
helper = new NoteSQLiteOpenHelper(context);
} /**
* 添加一条账目信息 到数据库
*
* @param name
* 花销的名称
* @param money
* 金额
*/
public void add(String name, float money) {
SQLiteDatabase db = helper.getWritableDatabase();
db.execSQL("insert into account (name,money) values (?,?)",
new Object[] { name, money });
// 记住 关闭.
db.close();
} public void delete(int id) {
SQLiteDatabase db = helper.getWritableDatabase();
db.execSQL("delete from account where id=?", new Object[] { id });
db.close();
} public void update(int id, float newmoney) {
SQLiteDatabase db = helper.getWritableDatabase();
db.execSQL("update account set money =? where id=?", new Object[] {
newmoney, id });
db.close();
} /**
* 返回数据库所有的条目
*
* @return
*/
public List<NoteBean> findAll() {
// 得到可读的数据库
SQLiteDatabase db = helper.getReadableDatabase();
List<NoteBean> noteBeans = new ArrayList<NoteBean>();
// 获取到数据库查询的结果游标
Cursor cursor = db.rawQuery("select id,money,name from account ", null);
while (cursor.moveToNext()) {
int id = cursor.getInt(cursor.getColumnIndex("id"));
String name = cursor.getString(cursor.getColumnIndex("name"));
float money = cursor.getFloat(cursor.getColumnIndex("money"));
NoteBean bean = new NoteBean(id, money, name);
noteBeans.add(bean);
bean = null;
} db.close();
return noteBeans;
} /**
* 模拟一个转账的操作. 使用数据库的事务
*
* @throws Exception
*/
public void testTransaction() throws Exception {
// 得到可写的数据库
SQLiteDatabase db = helper.getWritableDatabase();
db.beginTransaction(); // 开始事务
try {
db.execSQL("update account set money = money - 5 where id=? ",
new String[] { "2" });
db.execSQL("update account set money = money + 5 where id=? ",
new String[] { "3" });
//标记数据库事务执行成功
db.setTransactionSuccessful();
} catch (Exception e) {
// TODO: handle exception
} finally {
db.endTransaction();//关闭事务.
db.close();
} } }
NoteDao2.java, dao方式二: 用android提供的API
public class NoteDao2 {
private NoteSQLiteOpenHelper helper; public NoteDao2(Context context) {
helper = new NoteSQLiteOpenHelper(context);
} /**
* 添加一条账目信息 到数据库
*
* @param name
* 花销的名称
* @param money
* 金额
*
* @return true 插入成功 false 失败
*/
public boolean add(String name, float money) {
SQLiteDatabase db = helper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("name", name);
values.put("money", money);
long rawid = db.insert("account", null, values);
db.close();
if (rawid > 0) {
return true;
} else {
return false;
}
} public boolean delete(int id) {
SQLiteDatabase db = helper.getWritableDatabase();
int result = db.delete("account", "id=?", new String[] { id + "" });
db.close();
if (result > 0) {
return true;
} else {
return false;
}
} public boolean update(int id, float newmoney) {
SQLiteDatabase db = helper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("id", id);
values.put("money", newmoney);
int result = db.update("account", values, "id=?", new String[] { id
+ "" });
db.close();
if (result > 0) {
return true;
} else {
return false;
}
} /**
* 返回数据库所有的条目
*
* @return
*/
public List<NoteBean> findAll() {
// 得到可读的数据库
SQLiteDatabase db = helper.getReadableDatabase();
List<NoteBean> noteBeans = new ArrayList<NoteBean>();
Cursor cursor = db.query("account", new String[] { "id", "name",
"money" }, null, null, null, null, null);
while (cursor.moveToNext()) {
int id = cursor.getInt(cursor.getColumnIndex("id"));
String name = cursor.getString(cursor.getColumnIndex("name"));
float money = cursor.getFloat(cursor.getColumnIndex("money"));
NoteBean bean = new NoteBean(id, money, name);
noteBeans.add(bean);
bean = null;
}
db.close();
return noteBeans; }
}
TestNoteDao.java 测试类
public class TestNoteDao extends AndroidTestCase {
NoteDao dao ; /**
* 测试框架初始化完毕后 初始化数据的操作
*/ @Override
protected void setUp() throws Exception {
super.setUp();
dao = new NoteDao(getContext());
}
/**
* 测试框架执行完毕后 擦屁股的操作
*/
@Override
protected void tearDown() throws Exception {
super.tearDown();
} public void testAdd() throws Exception { for (int i = 0; i < 20; i++) {
dao.add("3月"+i+"号打酱油", 2.58f+i);
}
} public void testupdate() throws Exception{
//NoteDao dao = new NoteDao(getContext());
dao.update(2, 9.88f);
} public void testDelete() throws Exception{
//NoteDao dao = new NoteDao(getContext());
dao.delete(1);
} public void testFindAll() throws Exception{
//NoteDao dao = new NoteDao(getContext());
List<NoteBean> beans = dao.findAll();
for(NoteBean bean:beans){
System.out.println(bean.toString());
}
} public void testTrans() throws Exception{
dao.testTransaction();
}
}
Android -- SQLite 数据库创建,增删改查,事务处理的更多相关文章
- [Android] SQLite数据库之增删改查基础操作
在编程中常常会遇到数据库的操作,而Android系统内置了SQLite,它是一款轻型数据库,遵守事务ACID的关系型数据库管理系统,它占用的资源非常低,可以支持Windows/Linux/Un ...
- Android学习---数据库的增删改查(sqlite CRUD)
上一篇文章介绍了sqlite数据库的创建,以及数据的访问,本文将主要介绍数据库的增删改查. 下面直接看代码: MyDBHelper.java(创建数据库,添加一列phone) package com. ...
- Android中Sqlite数据库进行增删改查
今天这篇文章写Sqlite数据库,通过一个小案例来完整讲一下数据库常见的CRUD操作. 先对知识点总结: SQLite数据库 轻量级关系型数据库 创建数据库需要使用的api:SQLiteOpenHel ...
- android 对sqlite数据库的增删改查等各种操作
转载:http://blog.csdn.net/vrix/article/details/6717090 package com.sqlite.main; import java.io.File; i ...
- Android下利用SQLite数据库实现增删改查
1: 首先介绍如何利用adb查看数据库 1: adb shell 2: cd /data/data/包名/databases 3: sqlite3 数据库 4 接下来就可以进行数据库的sql语法 ...
- Android对Sqlite数据库的增删改查
SqLite 数据库 Google 为我们提供了sqlite相关的api SqLiteOpenHelper 这是一个抽象的类 如果想要使用的话,需要其他的类去继承他 SqLiteDatabase 类 ...
- Android下数据库操作——增删改查
Android下数据库第一种方式增删改查 1.创建一个帮助类的对象,调用getReadableDatabase方法,返回一个SqliteDatebase对象 2.使用SqliteDat ...
- greendao对SQLite数据库的增删改查操作
利用greendao操作数据库时,都是以对象或者对象的list来进行增删改查的操作,操作的结果都是用一个list来接收的!!! 1.增加一条记录 Stu stu01=new Stu();stu01.s ...
- SQLite数据库以及增删改查的案例
Android使用开源的与操作系统无关的SQL数据库——SQLite 一:在命令行下创建数据库: 1.启动模拟器后,打开命令行,执行adb shell 2.进入所在工程目录 3.执行sqlite3 m ...
- Android学习---SQLite数据库的增删改查和事务(transaction)调用
上一篇文章中介绍了手工拼写sql语句进行数据库的CRUD操作,本文将介绍调用sqlite内置的方法实现CRUD操作,其实质也是通过拼写sql语句. 首先,创建一个新的android项目: 其次,查看代 ...
随机推荐
- iOS 7.1 UITapGestureRecognizer 不好用的解决办法
UITapGestureRecognizer *tap3 = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(o ...
- * 和 ?在 shell 命令行中与在正则表达式中的区别
Linux 正则表达式 你有没有想过,在 shell 命令行中的 *,?和正则表达式中的*,?是否一样? 自打好多年前接触 DOS,就知道了* 和?这两个通配符(Wildcard),象 dir *.* ...
- IE、FF脚本兼容性问题
1.window.event IE有这个对象:FF没有,FF通过参数传递 2.获取事件源 IE:srcElement FF:target 3.添加与去除事件 IE:element.attachEven ...
- Visual Studio 2010 如何改用 Beyond Compare 作为 TFS 的比较工具
Beyond Compare 是一套非常实用的文件及文件夹比较软件,不仅可以快速比较出两个文件夹的不同之处,还可以详细的比较文件之间的内容差异.最近改用 TFS 进行版本控管之后,说实在的还是习惯使用 ...
- oracle 实现多字段匹配一个关键字查询语句
oracle 实现多字段匹配一个关键字查询语句:有两种方法(经测试,10g中不能用,11g才行): 第一种. select * from table where ('字段名1' ||'字段名2' || ...
- 巨蟒python全栈开发-第23天 内置常用模块2
一.今日主要内容 1.nametuple:(命名元组,本质还是元组) 命名元组=>类似创建了一个类 结构化时间其实是个命名元组 2.os 主要是针对操作系统的 一般用来操作文件系统 os.mak ...
- Backtracking is a form of recursion.
w https://www.cis.upenn.edu/~matuszek/cit594-2012/Pages/backtracking.html Starting at Root, your opt ...
- Storm-源码分析-Topology Submit-Executor-mk-threads
对于executor thread是整个storm最为核心的代码, 因为在这个thread里面真正完成了大部分工作, 而其他的如supervisor,worker都是封装调用. 对于executor的 ...
- java容器的线程安全性
参考:https://www.cnblogs.com/yjd_hycf_space/p/7760248.html 线程安全的: Vector HashTable StringBuffer 线程不安全的 ...
- [译]理解Windows消息循环
出处:http://www.cnblogs.com/zxjay/archive/2009/06/27/1512372.html 理解消息循环和整个消息传送机制对Windows编程来说非常重要.如果对消 ...