Android本地数据存储之SQLite关系型数据库 ——SQLiteDatabase
数据库的创建,获取,执行sql语句:
框架搭建:dao
思考:
1.数据库保存在哪里?
2.如何创建数据库?如何创建表?
3.如何更新数据库?如何更改表的列数据?
4.如何获取数据库?
5.如何修改数据库中的表的数据?
框架思想
思考:如何使得编程更加简单?
一个sql语言,容易写错;
1.使用占位符;
2.框架解析重建法:搭建框架,对增删改查功能进行单独封装,传入容器对象即可;
思考:
1.数据库保存在哪里?
data/data/包名/databases/xiaoo.db
2.如何创建数据库?如何创建表?
db.execSQL("CREATE TABLE person (personid integer primary key autoincrement, name varchar(20))");
3.如何更新数据库?如何更改表的列数据?
db.execSQL("ALTER TABLE person ADD phone VARCHAR(12) NULL ");
4.如何获取数据库?
5.如何修改数据库中的表的数据?
一、创建数据库打开助手:
二、创建dao
三、测试dao
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
public class MyDBOpenHelper extends SQLiteOpenHelper {
/**
*
* @param context 应用程序上下文
* @param name 数据库的名字
* @param factory 查询数据库的游标工厂 一般情况下 用sdk默认的
* @param version 数据库的版本 版本号必须不小1
*
*/
public MyDBOpenHelper(Context context) {
super(context, );
}
// 在mydbOpenHelper 在数据库第一次被创建的时候 会执行onCreate();
@Override
public void onCreate(SQLiteDatabase db) {
System.out.println("我被调用了 oncreate");
db.execSQL("CREATE TABLE person (personid integer primary key autoincrement, name varchar(20))");
}
// 通过version的增加来执行数据库版本更新,版本号改为6的同时,调用onUpgrade ,让程序员执行具体更新;
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
System.out.println("on update ");
db.execSQL("ALTER TABLE person ADD phone VARCHAR(12) NULL ");
}
}
二、创建dao
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
import cn.itcast.db.MyDBOpenHelper;
import cn.itcast.db.domain.Person;
public class PersonDao {
private static final String TAG = "PersonDao";
private MyDBOpenHelper dbOpenHelper;
// 在personDao被new出来的时候 就完成初始化
public PersonDao(Context context) {
dbOpenHelper = new MyDBOpenHelper(context);
// dbOpenHelper.getReadableDatabase()
// dbOpenHelper.getWritableDatabase()
}
// 增删改查
/**
* 往数据库添加一条数据
*/
public void add(String name, String phone) {
boolean result = find(name);
if (result)
return;
SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
if (db.isOpen()) {
db.execSQL("insert into person (name,phone) values (?,?)",
new Object[] { name, phone });
// 关闭数据库 释放数据库的链接
db.close();
}
}
/**
* 查找数据库的操作
*/
public boolean find(String name) {
boolean result = false;
SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
if (db.isOpen()) {
Cursor cursor = db.rawQuery("select * from person where name=?",
new String[] { name });
if (cursor.moveToFirst()) {
int index = cursor.getColumnIndex("phone"); // 得到phone在表中是第几列
String phone = cursor.getString(index);
Log.i(TAG, "phone =" + phone);
result = true;
}
// 记得关闭掉 cursor
cursor.close();
result = false;
// 释放数据库的链接
db.close();
}
return result;
}
/**
* 删除一条记录
*
* @param name
*/
public void delete(String name) {
SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
if (db.isOpen()) {
db.execSQL("delete from person where name =?",
new Object[] { name });
db.close();
}
}
/**
* 更新一条记录
*
*/
public void update(String name, String newname, String newphone) {
SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
if (db.isOpen()) {
db.execSQL("update person set name=? , phone=? where name=?",
new Object[] { newname, newphone, name });
db.close();
}
}
/**
* 查找全部
*/
public List<Person> getAllPersons() {
List<Person> persons=null;
SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
if (db.isOpen()) {
persons = new ArrayList<Person>();
Cursor cursor = db.rawQuery("select * from person ", null);
while (cursor.moveToNext()) {
Person person = new Person();
int nameindex = cursor.getColumnIndex("name");
int phoneindex = cursor.getColumnIndex("phone");
String name = cursor.getString(nameindex);
String phone = cursor.getString(phoneindex);
person.setName(name);
person.setNumber(phone);
persons.add(person);
}
cursor.close();
db.close();
}
return persons;
}
}
三、单元测试:测试dao
1.配置
instrumentation 和 uses-library
<instrumentation
android:name="android.test.InstrumentationTestRunner" //使用测试框架中的哪个测试运行器
android:targetPackage="cn.xiaoo.db" /> //测试哪个工程?
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<uses-library android:name="android.test.runner" /> //该程序需要添加哪个jar包(用于测试)?
2.编程测试
package cn.itcast.db.dao.test;
import java.util.List;
import cn.itcast.db.dao.PersonDao;
import cn.itcast.db.domain.Person;
import android.test.AndroidTestCase;
public class TestPersonDao extends AndroidTestCase {
PersonDao dao;
// 测试在执行测试代码时候的流程
//1 .new TestPersonDao 框架new出来
//2. 调用 setUp()
//3. testAdd() 这个时候 上下文 才被创建出来
/* @Override
protected void setUp() throws Exception {
dao = new PersonDao(getContext());
super.setUp();
}*/
public void testAdd() throws Exception{
PersonDao dao = new PersonDao(getContext());
;i<;i++){
dao.add("+i);
}
}
public void testdelete() throws Exception{
PersonDao dao = new PersonDao(getContext());
dao.delete("lisi99");
}
public void testupdate() throws Exception{
PersonDao dao = new PersonDao(getContext());
dao.update(");
}
public void testFindAll() throws Exception{
PersonDao dao = new PersonDao(getContext());
List<Person> persons = dao.getAllPersons();
assertEquals(, persons.size());
}
/**
* 测试的流程:
*/
/*
[2012-10-05 13:47:51 - db] ------------------------------
[2012-10-05 13:47:51 - db] Android Launch! //系统启动
[2012-10-05 13:47:51 - db] adb is running normally. //调试桥正常运行
[2012-10-05 13:47:51 - db] Performing android.test.InstrumentationTestRunner JUnit launch //运行测试运行器,启动JUnit
[2012-10-05 13:47:51 - db] Automatic Target Mode: using existing emulator 'emulator-5554' running compatible AVD '2.3.3_QVGA'
[2012-10-05 13:47:53 - db] Application already deployed. No need to reinstall.//不需要重新安装
[2012-10-05 13:47:53 - db] Launching instrumentation android.test.InstrumentationTestRunner on device emulator-5554//在设备上运行测试运行器
[2012-10-05 13:47:53 - db] Collecting test information //收集运行信息
[2012-10-05 13:47:56 - db] Sending test information to Eclipse //发送测试信息到Eclipse
[2012-10-05 13:47:56 - db] Running tests... //执行代码
[2012-10-05 13:47:58 - db] Test run finished //执行完毕
*/
}
框架思想
思考:如何使得编程更加简单?
一条sql语句,容易写错;
操作表
insert into person (name,phone) values (?,?)---------public long insert(String table, String nullColumnHack, ContentValues values)
delete from person where name =?---------------------public int delete(String table, String whereClause, String[] whereArgs)
update person set name=? , phone=? where name=?------public int update(String table, ContentValues values, String whereClause, String[] whereArgs)
select * from person where name=?--------------------public Cursor query(boolean distinct, String table, String[] columns,
String selection, String[] selectionArgs, String groupBy,
String having, String orderBy, String limit)
insert:在哪张表插入哪些数据?string string contentvalues
delete:在哪张表删除哪些数据?String String String[]
update:在哪张表的那条数据上更改什么数据? String ContentValues String String[]
query:是否保证唯一?查哪张表?查哪些列?
什么查询条件?占位符值?分组?
包含?排序?区间?
操作数据库:
CREATE TABLE person (personid integer primary key autoincrement, name varchar())
ALTER TABLE person ADD phone VARCHAR() NULL
怎办办?
1.使用占位符;
2.框架解析重建法:搭建框架,对增删改查功能进行单独封装,传入容器对象即可;
.原生: db.execSQL("insert into person (name,age) values ("xiaoli",20)");
.站位符:db.execSQL(});
.框架 :
ContentValues values = new ContentValues();
values.put("name", name);
values.put("age", age);
db.insert("person", null, values);
public void add(String name, int age) {
SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
if (db.isOpen()) {
ContentValues values = new ContentValues();
values.put("name", name);
values.put("age", age);
// 如果 contentvalues为空
db.insert("person", null, values); // 组拼sql语句完成的添加的操作
// insert into person name values (NULL) ;
db.close();
}
}
最复杂的方法是查询:query
我们一起来看看底层是怎么封装的:
public static String buildQueryString(
boolean distinct, String tables, String[] columns, String where,
String groupBy, String having, String orderBy, String limit) {
if (TextUtils.isEmpty(groupBy) && !TextUtils.isEmpty(having)) {
throw new IllegalArgumentException(
"HAVING clauses are only permitted when using a groupBy clause");
}
if (!TextUtils.isEmpty(limit) && !sLimitPattern.matcher(limit).matches()) {
throw new IllegalArgumentException("invalid LIMIT clauses:" + limit);
}
StringBuilder query = );
query.append("SELECT ");
if (distinct) {
query.append("DISTINCT ");
}
) {
appendColumns(query, columns);
} else {
query.append("* ");
}
query.append("FROM ");
query.append(tables);
appendClause(query, " WHERE ", where);
appendClause(query, " GROUP BY ", groupBy);
appendClause(query, " HAVING ", having);
appendClause(query, " ORDER BY ", orderBy);
appendClause(query, " LIMIT ", limit);
return query.toString();
}
另一种增删改查:dao
import java.util.ArrayList;
import java.util.List;
import cn.itcast.db.MyDBOpenHelper;
import cn.itcast.db.domain.Person;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
public class PersonDBDao {
private Context context;
MyDBOpenHelper dbOpenHelper;
public PersonDBDao(Context context) {
this.context = context;
dbOpenHelper = new MyDBOpenHelper(context);
}
/**
* 添加一条记录
*/
public void add(String name, int age) {
SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
if (db.isOpen()) {
// db.execSQL("insert into person (name,age) values (?,?)",new
// Object[]{name,age});
// db.execSQL("insert into person ",null) // 不合法的sql语句
ContentValues values = new ContentValues();
values.put("name", name);
values.put("age", age);
// 如果 contentvalues为空
db.insert("person", null, values); // 组拼sql语句完成的添加的操作
// insert into person name values (NULL) ;
db.close();
}
}
/**
* 删除一条记录
*/
public void delete(String name) {
SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
if (db.isOpen()) {
db.delete("person", "name=?", new String[] { name });
db.close();
}
}
/**
* 数据库的更改操作
*/
public void update(String name, String newname, int newage) {
SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
if (db.isOpen()) {
ContentValues values = new ContentValues();
values.put("name", newname);
values.put("age", newage);
db.update("person", values, "name=?", new String[] { name });
db.close();
}
}
/**
* 数据库的查询操作
*/
public boolean find(String name) {
boolean result = false;
SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
if (db.isOpen()) {
// select * from person
Cursor cursor = db.query("person", null, "name=?",
new String[] { name }, null, null, null);
if (cursor.moveToFirst()) {
result = true;
}
cursor.close();
db.close();
}
return result;
}
/**
* 查询所有信息
*/
public List<Person> findAll() {
List<Person> persons = null;
SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
if (db.isOpen()) {
Cursor cursor = db.query("person", null, null, null, null, null,
null);
persons = new ArrayList<Person>();
while (cursor.moveToNext()) {
Person person = new Person();
String name = cursor.getString(cursor.getColumnIndex("name"));
person.setName(name);
int age = cursor.getInt(cursor.getColumnIndex("age"));
person.setAge(age);
persons.add(person);
}
cursor.close();
db.close();
}
return persons;
}
/**
* 查询所有信息
*/
public Cursor findAllbyCursor() {
SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
if (db.isOpen()) {
/*Cursor cursor = db.query("person", null, null, null, null, null,
null);*/
Cursor cursor = db.rawQuery("select personid as _id,age,name from person", null);
return cursor;
// 注意了 一定不要把数据库 关闭了
}
return null;
}
/**
* 银行转账的方法
* 1.开始事务:db.beginTransaction();
* 2.设置事务成功:db.setTransactionSuccessful();
* 3.结束事务:db.endTransaction();
* 4.关闭连接:db.close();
*/
public void transaction() {
SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
if (db.isOpen()) {
try {
// 开启数据库的事务
db.beginTransaction();
// 给张三设置1000块钱的账户
db.execSQL("update person set account=? where name=?",
, "zhangsan98" });
// 把张三的账户扣除200块钱
db.execSQL("update person set account=account-? where name=?",
, "zhangsan98" });
// 出现了异常
// 把张三的钱给李四
//初始化李四账户 为 0
db.execSQL("update person set account=? where name=?",
, "lisi" });
db.execSQL("update person set account=account+? where name=?",
, "lisi" });
db.setTransactionSuccessful();
}
// 显示的设置事务是否成功
catch (Exception e) {
// TODO: handle exception
} finally {
db.endTransaction();
db.close();
}
}
}
}
Android本地数据存储之SQLite关系型数据库 ——SQLiteDatabase的更多相关文章
- Android本地数据存储复习
Android本地数据存储复习 Android无论是应用层还是系统层都需要在本地保存一些数据,尤其在应用层中使用的就更为普遍,大体有这么几种:SharedPreference,file,sqlite数 ...
- Spring Boot干货系列:(八)数据存储篇-SQL关系型数据库之JdbcTemplate的使用
Spring Boot干货系列:(八)数据存储篇-SQL关系型数据库之JdbcTemplate的使用 原创 2017-04-13 嘟嘟MD 嘟爷java超神学堂 前言 前面几章介绍了一些基础,但都是静 ...
- Android本地数据存储: ASimpleCache
一:前言 在上一篇博客Android本地数据存储: Reservoir 博客中,我提到,除了Reservoir库,还可以采用ASimpleCache开源库,来实现本地数据存储.昨天并没有仔细的对比Re ...
- Android之ListView,AsyncTask,GridView,CardView,本地数据存储,SQLite数据库
版权声明:未经博主允许不得转载 补充 补充上一节,使用ListView是用来显示列表项的,使用ListView需要两个xml文件,一个是列表布局,一个是单个列表项的布局.如我们要在要显示系统所有app ...
- Android本地数据存储: Reservoir
一:前言 今天做项目,准备使用本地存储,把一些数据存在本地磁盘上,比如用户名.密码这样的.其实大家都知道,这种情况最常用的就是SharedPreferences了,我也不例外,脑子里第一个想到的就是用 ...
- 理解 Android 本地数据存储 API
利用首选项.SQLite 和内部及外部内存 API 对于需要跨应用程序执行期间或生命期而维护重要信息的应用程序来说,能够在移动设备上本地存储数据是一种非常关键的功能.作为一名开发人员,您经常需要存储诸 ...
- android之数据存储之SQLite
SQLite开源轻量级数据库,支持92-SQL标准,主要用于嵌入式系统,只占几百K系统资源此外,SQLite 不支持一些标准的 SQL 功能,特别是外键约束(FOREIGN KEY constrain ...
- 大数据时代的数据存储,非关系型数据库MongoDB
在过去的很长一段时间中,关系型数据库(Relational Database Management System)一直是最主流的数据库解决方案,他运用真实世界中事物与关系来解释数据库中抽象的数据架构. ...
- Android:数据存储之SQLite
Android在运行时集成了SQLite , 所以每个Android应用程序都可以使用SQLite数据库. 我们通过SQLiteDatabase这个类的对象操作SQLite数据库,而且不需要身份验证. ...
随机推荐
- jQuery基础(1) -- jQuery 语法
通过 jQuery,您可以选取(查询,query) HTML 元素,并对它们执行"操作"(actions).jQuery 语法jQuery 语法是通过选取 HTML 元素,并对选取 ...
- 启动tomcat时 错误: 代理抛出异常 : java.rmi.server.ExportException: Port already in use: 1099的解决办法
一.问题描述 今天一来公司,在IntelliJ IDEA 中启动Tomcat服务器时就出现了如下图所示的错误:
- ajax请求下拉列表框的实现(面向对象封装类)
实现的效果图 <?php class Car{ private $carColor; private $carType; public function __construct($carColo ...
- Sublime Text3快捷键汇总
选择类 Ctrl+D 选中光标所占的文本,继续操作则会选中下一个相同的文本. Alt+F3 选中文本按下快捷键,即可一次性选择全部的相同文本进行同时编辑.举个栗子:快速选中并更改所有相同的变量名.函数 ...
- Distinct
SELECT 指令让我们能够读取表格中一个或数个栏位的所有资料.这将把所有的资料都抓出,无论资料值有无重复.在资料处理中,我们会经常碰到需要找出表格内的不同资料值的情况.换句话说,我们需要知道这个表格 ...
- JavaScript学习笔记——变量和数据类型
一.javascript命名规范 1. 严格区分大小写 2. 变量的命名必须以字母或 _或 $开头,余下的部分可以是任意的字母,数字,或者是 _或者是$ 3.不能用关键字或者是保留字命名. 4.jav ...
- 面向对象编程OOP-1
在下面的例子中, 我们定义了 Student类作为 Person类的子类. 之后我们重定义了sayHello() 方法并添加了 sayGoodBye() 方法 // 定义Person构造器 funct ...
- JS中call和apply
作用: 替换当前对象的方法中的this. 理解: call和apply是为了动态改变this出现的,当一个object没有某个方法,但是其他的有,我们可以借助call或apply用其它对象的方法来操作 ...
- Linq 中按照多个值进行分组(GroupBy)
Linq 中按照多个值进行分组(GroupBy) .GroupBy(x => new { x.Age, x.Sex }) group emp by new { emp.Age, emp.Sex ...
- OC-改错题
1,类方法中不能访问成员变量 2,id后不能加*(因为id相当于NSObject *) 3,id类型的变量不能用点语法 4,类对象只能调用类方法,不能调用对象方法 .description #impo ...