Android的数据库存储:SQLite关系型数据库,集成在Android里

显式支持5种数据类型:NULL, INTEGER, REAL(浮点数), TEXT(字符串文本),

BLOB(二进制对象)

也支持varchar char decimal等类型,只是在运算和保存时会转成对应的五种数据类型

特点:无数据类型

1,可将任意支持的数据保存在数据库的任意字段中而不用关心字段声明的数据类型是什么

2,数据超过字段声明的最大长度也不会出错

例外:被定义为INTEGER PRIMARY KEY(主键)的字段只能储存64位整数

在编写create table语句时,非主键的字段可以省略数据类型

分页与mysql类似:

获取5条记录,跳过前面3条记录

select * from Account limit 5 offset 3

select * from Account limit 3,5

提供获取添加记录后自增长的id值:select last_insert_rowid()

实例:在Android中创建一个程序实现对数据库的增删改查

应用程序需要的功能:

1,自动创建数据库(第一次使用软件时自动创建,使用抽象类SQLiteOpenHelper.getReadableDatabase或者getWritableDatabase())

//继承这个抽象才能使用,重写两个方法

public class DBOpenHelper extends

SQLiteOpenHelper{//特殊:这个父类是没有调用默认构造函数的,通过工具软件自动修正

//构造方法

public DBOpenHelper(Context context){

//参3是游标工厂对象,null代表使用系统默认的游标

//参4是数据库的版本号不能为 0

//会保存在应用包中的/databases/生成数据库的名称.db

文件夹下

super(context,"生成数据库的名称.db",null,2);

}

public void onCreate (SQLiteDatabase

db){//在数据库每一次被创建的时候调用如果数据库已经存在就不会被调用

//类似初始化方法,这里用于生成数据库表,SQLiteDatabase这个类可以实现增删改查的操作

db.execSQL("create table

person(personid integer primary key autoincrement, name

varchar(20))");

}

//数据库文件版本号发生改变时被调用

public void onUpgrade(SQLiteDatabase db, int

oldVersion, int newVersion){

//假设软件升级数据要在person表添加一个phone字段,将版本号设为2,会自动调用这个方法执行下面语句

db.execSQL("alter table person

add phone varchar(12) null");

}

}

测试类:

public class PersonServiceTest extends AndroidTestCase{

public void testCreateDB() throws

Exception{

DBOpenHelper dbOpenHelper=new

DBOpenHelper(getContext());

dbOpenHelper.getWritableDatabase();

}

}

使用SQliteExpert可以查看SQLite数据库生成的文件

如果要在Android系统中使用SQLite数据库,就要在数据库中创建一张名为:android_metadata的表来记录本地化语言信息,会自动创建的

dbOpenHelper.getWritableDatabase()方法内部运行原理:第一运行软件,先检查数据库是否存在,如果存在就锁定数据库。然后对比构造方法传进来的数据库名字(数据库以文件的形式存在),名字不为空就打开或者创建数据库(私有操作模式)并且得到数据库的对象。第一次生成的数据库版本号默认为0,对比构造方法传进来的版本号(1),不相等就开始事务。如果当前版本号等于0就执行onCreate()初始化方法创建数据库表,如果不为0就执行onUpgrade()方法修改数据库,最后都需要修改数据库版本号。

第n+1次运行软件:数据库已经存在,此时数据库版本号为1,对比构造方法传进来的版本号(2),因为当前版本号不为0,不会执行onCreate()方法,而且版本号不相同就会执行onUpgrade()方法更行数据库。

2,数据库创建后,不用加载驱动不用创建连接因为Android内部已经做好,只需要使用SQLiteDatabase的实例对象

2.1建一个对应person表的javabean

2.2建一个对应person表的增删改查操作的业务bean

public class PersonService{

//操作某个数据库,需要使用SQLiteOpenHelper的实现类对象

private DBOpenHelper dbOpenHelper;

public PersonService(Context context){

this.dbOpenHelper=new

DBOpenHelper(context);

}

//増

public void save(Person person){

//通过数据库助手对象取得数据库(操作)对象

SQLiteDatabase

db=dbOpenHelper.getWriteableDatabase();

//db和db1都是指向同一个对象,因为dbOpenHelper本身内部有缓存功能,如果是dbOpenHelper和dbOpenHelper1就不是

SQLiteDatabase

db1=dbOpenHelper.getWriteableDatabase();

//用占位符可以避免特殊输入的错误(单引号的)

db.execSQL("insert into

person(name, phone) values(?,?)",new

Object[]{person.getName(),person.getPhone()});

db.close();//当应用只有一个地方使用数据库时可以不关闭来提高响应速度

}

//删

public void delete(int id){

SQLiteDatabase

db=dbOpenHelper.getWriteableDatabase();

db.execSQL("delete from person

where personid=?",new Object[]{id});

}

//改

public void update(Person person){

SQLiteDatabase

db=dbOpenHelper.getWriteableDatabase();

db.execSQL("update person set

name=?,phone=? where personid=?",new

Object[]{person.getName(),person.getPhone(),person.getId()});

}

//查

public Person find(int id){

//转用getReadableDatabase()因为查找是读取不用写数据库,其实这个方法里封装里getWriteableDatabase()。首先会调用getWriteableDatabase()来获取操作对象,如果出现异常(数据库是可以有默认空间容量的,如果满了就获取不了对象就会出现异常)。异常捕获后用其他方法以只读模式来打开数据库。建议只读时使用getReadableDatabase()方法。在数据库没满时,两个方法的结果是一样的,只有数据库控件满时才不同。

SQLiteDatabase

db=dbOpenHelper.getReadableDatabase();

//参数规定是数组,返回一个结果集的游标

Cursor

cursor=db.rawQuery("select * from person where personid=?",new

String[]{id.toString});

if(cursor.moveToFirst()){

//获得数据的方法比较间接,只能用索引,再调用另外的方法用名字获得索引

int

personid=cursor.getInt(cursor.getColumnIndex("personid"));

String

name=cursor.getString(cursor.getColumnIndex("name"));

String

phone=cursor.getInt(cursor.getColumnIndex("phone"));

Person

person=new Person();

person.setId(personid);

person.setName(name);

person.setPhone(phone);

cursor.close();

return

person;

}

cursor.close();

return null;

}

//分页查全部

public List getScrollDate(int offset,int

maxResult){

List persons=new

ArrayList();

SQLiteDatabase

db=dbOpenHelper.getReadableDatabase();

Cursor

cursor=db.rawQuery("select * from person order by personid asc

limit ?,?",new

String[]{String.valueOf(offset),String.valueOf(maxResult)});

while(cursor.moveToNext()){

int

personid=cursor.getInt(cursor.getColumnIndex("personid"));

String

name=cursor.getString(cursor.getColumnIndex("name"));

String

phone=cursor.getInt(cursor.getColumnIndex("phone"));

Person

person=new Person();

person.setId(personid);

person.setName(name);

person.setPhone(phone);

persons.add(person);

}

cursor.close();

return persons;

}

//表的数据总条数

public long getCount(){

SQLiteDatabase

db=dbOpenHelper.getReadableDatabase();

Cursor

cursor=db.rawQuery("select count(*) from person",null);

cursor.moveToFirst();

long

result=cursor.getLong(0);

cursor.close();

return result;

}

}

测试类:

public class PersonServiceTest extends AndroidTestCase{

public void testCreateDB() throws

Exception{

DBOpenHelper dbOpenHelper=new

DBOpenHelper(getContext());

dbOpenHelper.getWritableDatabase();

}

//保存

public void testSave() throws Exception{

PersonService service=new

PersonService(this.getContext());

Person person=new

Person();

person.setName("liu");

person.setPhone("123456");

service.save(person);

}

//删除

public void testDelete() throws Exception{

PersonService service=new

PersonService(this.getContext());

service.delete(1);

}

//更新

public void testUpdate() throws Exception{

PersonService service=new

PersonService(this.getContext());

Person

person=service.find(1);//先找到再更新

person.setName("zhang");

service.update(person);

}

//查找

public void testFind() throws Exception{

PersonService service=new

PersonService(this.getContext());

Person

person=service.fing(1);

System.out.println(person.getName());

}

//分页

public void testScrollDate() throws

Exception{

PersonService service=new

PersonService(this.getContext());

List

persons=service.getScrollDate(0,5);//跳过0条获取5条,(5,5)跳过前面5条获取5条

for(Person

person:persons){

System.out.println(person.getId());

}

}

//统计总条数

public void testCount() throws Exception{

PersonService service=new

PersonService(this.getContext());

long

result=service.getCount();

System.out.println(result);

}

}

备注:为什么PersonService service=new

PersonService(this.getContext());这条语句不写成这个测试类的全局属性?因为如果写成全局就是这个类的属性,然而上下文对象是在这个类被实例话过后才会被创建,所以写成全局实例化时传入的上下文就会为空,在单元测试的类中是这样,其他不确定,但是可以通过重写setUp()方法来改变这种情况

除了execSQL() 和

rawQuery()方法外,SQLiteDatabase还专门提供了insert(),delete(),update(),query()(不用写sql语句函数内部构造)

用以上4个方法对业务bean进行改写

public class PersonService{

private DBOpenHelper dbOpenHelper;

public PersonService(Context context){

this.dbOpenHelper=new

DBOpenHelper(context);

}

//増

public void save(Person person){

SQLiteDatabase

db=dbOpenHelper.getWriteableDatabase();

//用于配置插入表中所有字段的数据

ContentValues values=new

ContentValues();

values.put("name",person.getName());

values.put("phone",person.getPhone());

//2参是NULL值字段,当3参的数据为空既插入sql语句value(null)时,就会用到2参的数据,假如2参是"name"则sql语句会组装成

insert into person (name) values(null)这样就不会有语法错误。假如insert into

person (personid) values(null)插入空主键的话,SQLite也不会有错,内部会转换为自增的值

db.insert("person",null,values);

db.close();

}

//删

public void delete(int id){

SQLiteDatabase

db=dbOpenHelper.getWriteableDatabase();

db.delete("person","personid=?",new

String[]{id.toString()});

}

//改

public void update(Person person){

SQLiteDatabase

db=dbOpenHelper.getWriteableDatabase();

ContentValues values=new

ContentValues();

values.put("name",person.getName());

values.put("name",person.getName());

db.update("person",values,"personid=?",new

String[]{person.getId().toString()});

}

//查

public Person find(int id){

SQLiteDatabase

db=dbOpenHelper.getReadableDatabase();

Cursor

cursor=db.query("person",new

String[]{"personid","name","phone"},"personid=?",null,null,null);

if(cursor.moveToFirst()){

int

personid=cursor.getInt(cursor.getColumnIndex("personid"));

String

name=cursor.getString(cursor.getColumnIndex("name"));

String

phone=cursor.getInt(cursor.getColumnIndex("phone"));

Person

person=new Person();

person.setId(personid);

person.setName(name);

person.setPhone(phone);

cursor.close();

return

person;

}

cursor.close();

return null;

}

//分页查全部

public List getScrollDate(int offset,int

maxResult){

List persons=new

ArrayList();

SQLiteDatabase

db=dbOpenHelper.getReadableDatabase();

Cursor

cursor=db.query("person",null,null,null,null,null,"personid

asc",offset+","+maxResult);

while(cursor.moveToNext()){

int

personid=cursor.getInt(cursor.getColumnIndex("personid"));

String

name=cursor.getString(cursor.getColumnIndex("name"));

String

phone=cursor.getInt(cursor.getColumnIndex("phone"));

Person

person=new Person();

person.setId(personid);

person.setName(name);

person.setPhone(phone);

persons.add(person);

}

cursor.close();

return persons;

}

//表的数据总条数

public long getCount(){

SQLiteDatabase

db=dbOpenHelper.getReadableDatabase();

Cursor

cursor=db.query("person",new

String[]{"count(*)"},null,null,null,null,null);

cursor.moveToFirst();

long

result=cursor.getLong(0);

cursor.close();

return result;

}

}

android视频教程_创建数据库与完成数据添删改查,17_创建数据库与完成数据添删改查...相关推荐

  1. Android复习07【创建数据库、insert()插入数据、查看数据库、根据列索引获取参数值、根据列名-返回索引、增删改查数据、数据分页、修改表结构、Room框架】

    2020-04-09-星期四-第八周 目   录 创建数据库 insert()方法 查看数据库(Save as保存) 菜鸟教程---SQLite数据库 根据 列索引 获取 参数值 列比较多---根据列 ...

  2. 根据excel列动态创建mysql表_根据数据库字段动态生成excel模版下载,上传模版获取数据存入数据库(poi 反射)...

    环境:mysql5.7.28 java8 Spring boot 2.2.4 mybatis-plus3.10 动态:根据需求,用户可以选择对应的字段生成excle模版 下载 poi 反射:poi是e ...

  3. Android基础_数据存储

    2019独角兽企业重金招聘Python工程师标准>>> Android基础_数据存储 Android数据存储的几种形式 继承SQLiteOpenHelper public class ...

  4. Android读出Excel报表数据然后导出写入到SQLite数据库

    Android读出Excel报表数据然后导出写入到SQLite数据库 假设现在有一个excel.xls位于Android手机外部存储器的根目录下,数据报表为: 需要把excel.xls的数据导出,写入 ...

  5. Android数据存储(三)----- SQLite数据库存储

    SQLite是Android系统内置的数据库,是一种轻量级的关系型数据库,它运算速度快,占用资源少,非常适合在移动设备上使用.同时,它不仅支持标准的SQL语法,还遵循了数据库的ACID事务. 一.创建 ...

  6. 查看android数据库sqlite3中的表及数据、手机上直接编辑数据库

    找到一篇关于Sqlite的好文章,擅自保存下来,希望作者不要怪罪.. 转自: http://www.apkbus.com/android-60977-1-1.html 最近涉及到数据库的操作,要察看手 ...

  7. 大数据 数据库 评测_为什么腾讯QQ的大数据平台选择了这款数据库?

    导读:本文带你了解一个开源的.高性能的时序型数据库--InfluxDB. 作者:韩健来源:大数据DT(ID:hzdashuju) 00 为什么QQ要选择InfluxDB?从2016年起,笔者在腾讯公司 ...

  8. 千万级别数据查询优化_从千万级数据查询来聊一聊索引结构和数据库原理

    在日常工作中我们不可避免地会遇到慢SQL问题,比如笔者在之前的公司时会定期收到DBA彪哥发来的Oracle AWR报告,并特别提示我某条sql近阶段执行明显很慢,可能要优化一下等.对于这样的问题通常大 ...

  9. azure云数据库_从Azure Databricks将数据加载到Azure SQL数据库

    azure云数据库 In this article, we will learn how we can load data into Azure SQL Database from Azure Dat ...

  10. android(9)_数据存储和访问3_scard基本介绍

    使用Activity的openFileOutput()保存文件的方法,文件存储在手机空间,通常情况下,手机的存储空间不是很大,存储小文件确定.假设你要存储大文件,如视频,是不可行. 对于这样大的文件, ...

最新文章

  1. 一步一步SharePoint 2007之十六:注册并配置一个网站用户
  2. 机器学习和计算机视觉的20大图像数据集
  3. linux Makefile 中使用 shell命令
  4. JEECMS8——系列文档
  5. 搜索引擎排名不友好的五个地点-SEO
  6. impdp导入mysql_Oracle数据库的impdp导入操作以及dba_directories使用方法
  7. 怎么恢复oracle的包,【学习笔记】使用dbms_backup_restore包恢复数据库
  8. 企业正确进行数字化转型的7个秘诀
  9. 唐中印 项目管理实战专家简介
  10. phpcms v9宽字节注入问题
  11. phantomjs linux java_PhantomJS 在linux上使用
  12. 『伪原创工具 』英文在线伪原创工具
  13. Error: ImageIO: PNG invalid PNG file: iDOT doesn't point to valid IDAT chunk
  14. 图benchmark
  15. ddr2之OCD、ODT和Post CAS技术
  16. 数据挖掘Task 5: 模型融合
  17. leetcode 1567
  18. android仿微信发状态图片上传
  19. 基于 Paraview 扩展与实现——(2)
  20. 俺同学的QQ签名,我晕~

热门文章

  1. java逻辑删除代码_MybatisPlus实现逻辑删除功能
  2. 隐私计算技术|深度解读可信隐私计算框架“隐语”
  3. 包装严重的IT行业,作为面试官,我是如何甄别应聘者的包装程度
  4. 工业通讯总线RS485和RS232
  5. uni-app 登录功能(2)
  6. myeclipse未能启动服务器,myeclipse启动服务器时,tomcat出错问题
  7. 王凯1987计算机系,王凯-专家人物-中国水网
  8. Excel·VBA考勤打卡记录统计出勤小时
  9. 如何在AD上重定向电脑加域后默认保存位置?
  10. Android开发Tips(5)