热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Android中SQLiteDatabase操作【附源码】

像我们做的很多应用程序及网站一样,基本都是对数据库进行增删改查来实现相应的功能。那么Android开发也一样,不过由于在移动客户端应用,所以不会像sqlserver、mysql那么复杂,Andr

  像我们做的很多应用程序及网站一样,基本都是对数据库进行增删改查来实现相应的功能。那么Android开发也一样,不过由于在移动客户端应用,所以不会像sql server、mysql那么复杂,Android应用程序支持本地数据库,SQLiteDatabase,通俗的说就是在手机上我们开发的应用程序中创建一个数据库,然后我们可以在手机上对我们的数据进行增删改查,不过这并不是绝对的,像前段时间我们开发一个小组OA,需要多人使用,功能简单,但需要大家连接到一个数据库中进行数据读取操作,所以这种情况下就要考虑到用mysql这样的数据库,最后选择了用php操作后台,然后然会Android进行数据处理,不过对于我们使用的2G网络很多程度上对速度还是有影响的。缓存这一块接触的比较少,计划等到Android这一块学的差不多了再研究其稍底层的一些开发。

  这篇文章主要向大家分享如何操作SQLiteDatabase。 

  当然首先我们要了解SQLiteDatabase,它具有很多优点:

SQLite特性:

    1. 轻量级

    2. 独立性

    3. 隔离性

        SQLite数据库中所有的信息(比如表、视图、触发器等)都包含在一个文件内,方便管理和维护。

    4. 跨平台

    5. 多语言接口

    6. 安全性

        SQLite数据库通过数据库级上的独占性和共享锁来实现独立事务处理。这意味着多个进程可以在同一时间从同一数据库读取数据,但只有一个可以写入数据。在某个进程或现成向数据库执行操作之前,必须获得独占锁定。在发出独占锁定以后,其他的读或写操作将不会再发生。

 

创建和打开数据库:

    openOrCreateDatabase(),自动检测是否存在这个数据库,如果存在则打开,否则创建,创建成功会返回一个SQLiteDatabase对象,否则抛出异常FileNotFoundException

        mSQLiteDatabase = this.openOrCreateDatabase("abc.db",MODE_PRIVATE,null);

创建表:

    execSQL()

        String Create_Table = "Create table table1...";

        mSQLiteDatabase.execSQL(Create_Table);

 

向表中添加数据:

    insert方法需要把数据打包到ContentValues中,ContentValues其实就是一个MapKey值是字段名称,Value值是字段的值。通过ContentValuesput方法就可以把数据放到ContentValues对象中,然后插入到表中:

        ContentValue cv = new ContentValues();

        cv.put(table_num,1);

        mSQLiteDatabase.insert(TABLE_NAME,null,cv);

 

从表中删除数据:

    delete():

        mSQLiteDatabase.delete("abc.db","where...",null);

 

修改表数据:

    update():

        ContentValues cv = new ContentValues();

        cv.put(TABLE_NUM,3);

        mSQLiteDatabase.update("table1",cv,"num"+"="+Integer.toString(0),null);

 

  当然,插入、删除和修改操作也可以通过execSQL(sql)方法来实现。

 

关闭数据库:

        mSQLiteDatabase.close();

 

删除指定表:

        mSQLiteDatabase.execSQL("DROP TABLE table1");

 

删除数据库:

        this.deleteDatabase("abc.db");

 

查询表中的某条记录:

        通过Cursor类实现,当使用SQLiteDatabase.query()方法时,会得到一个Cursor对象,Cursor指向的就是每一条数据。它提供了很多有关查询的方法:

            

方法  

说明

move

以当前位置为参考,将Cursor移动到指定的位置,成功返回true

moveToPosition

将Cursor移动的指定的位置,返回boolean

moveToNext

将Cursor向前移动一个位置,返回boolean

moveToLast

将Cursor向后移动一个位置,返回boolean

moveToFirst

将Cursor移动的第一行,返回boolean

isBeforeFirst

返回Cursor是否指向第一项数据之前

isAfterLast

返回Cursor是否指向最后一项数据之后

isClosed

返回Cursor是否关闭

isFirst

返回Cursor是否指向第一项数据

isLast

返回Cursor是否指向最后一项数据

isNull

返回指定位置的值是否为null

getCount

返回总的数据项数

getInt

返回当前行指定索引的数据

 例如:

        Cursor cur = mSQLiteDatabase.rawQuery("select * from table",null);

        if(cur != null)

        {

            if(cur.moveToFirst())

            {

                do{

                    int numColumn = cur.getColumnIndex("num");

                    int num = cur.getInt(numColumn);

                  }while(cur.moveToNext());

            }

        }

     使用SQLiteDatabase数据库后要及时关闭,否则可能会抛出SQLiteException异常。    

 

上面的方法像大部分基础语法书上一样直接执行sql语句的形式,那么在Android中为了简化用户操作以及提高性能,Android系统提供了SQLiteOpenHelper,封装了常用的数据库操作方法。利用它我们可以很轻松的完成对数据库的增删改查。  

 首先我们创建一个DBHelper类继承SQLiteOpenHelper,用它来完成数据库的初始化工作:创建数据库,创建表等操作。

他包含一些借口方法,在下面的注释里已经注释的很详细,就不再罗嗦。

 1 package com.example.core;
2
3 import android.content.Context;
4 import android.database.sqlite.SQLiteDatabase;
5 import android.database.sqlite.SQLiteDatabase.CursorFactory;
6 import android.database.sqlite.SQLiteOpenHelper;
7
8 public class DBHelper extends SQLiteOpenHelper{
9
10 public DBHelper(Context context) {
11 //创建数据库名为march_test.db的数据库
12 super(context,"march_test.db",null,1);
13 }
14
15 /* (non-Javadoc)
16 * 数据库每次被创建时调用
17 * @see android.database.sqlite.SQLiteOpenHelper#onCreate(android.database.sqlite.SQLiteDatabase)
18 */
19 @Override
20 public void onCreate(SQLiteDatabase db) {
21 //创建数据库表
22 String create_sql = "CREATE TABLE student(id integer primary key autoincrement," +
23 "name varchar(20),age integer not null)";
24 db.execSQL(create_sql);
25 }
26
27 /* (non-Javadoc)
28 * 版本号发生变化时执行
29 * @see android.database.sqlite.SQLiteOpenHelper#onUpgrade(android.database.sqlite.SQLiteDatabase, int, int)
30 */
31 @Override
32 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
33 // TODO Auto-generated method stub
34 String alter_sql = "ALTER TABLE student ADD money integer";
35 db.execSQL(alter_sql);
36 }
37
38 }

  通过实例化这个类,可以创建一个名为march_test.db的数据库。包含数据表student。可以文件系统中看到:

  路径为data/data/包名/databases/数据库名:

    

 

  这种db格式的数据库在这里给大家推荐一个非常好用的工具SQLite Expert Professional,非常好用,在网上也很好找到。他mysql workbench等数据库可视化工具一样给我们提供了可视化数据库操作,软件界面如下:

    

  我们可以把我们创建的表在文件系统中导出来然后放到这里查看。

 

  首先要声明我们要操作的数据类型类:

 1 package com.example.sqllite;
2
3 public class Student{
4
5 private Integer id;
6 private String name;
7 private Integer age;
8
9 public Student(Integer id, String name, Integer age) {
10 super();
11 this.id = id;
12 this.name = name;
13 this.age = age;
14 }
15
16 public Student(String name , Integer age){
17 super();
18 this.name = name;
19 this.age = age;
20 }
21
22 public Integer getId() {
23 return id;
24 }
25
26 public void setId(Integer id) {
27 this.id = id;
28 }
29
30 public String getName() {
31 return name;
32 }
33
34 public void setName(String name) {
35 this.name = name;
36 }
37
38 public Integer getAge() {
39 return age;
40 }
41
42 public void setAge(Integer age) {
43 this.age = age;
44 }
45
46 @Override
47 public String toString() {
48 return "Student [id=" + id + ", name=" + name + ", age=" + age + "]";
49 }
50
51 }

 

 

下面要编写对数据库的增删改查类,它继承我们上面创建的SQLiteOpenHelper为基类的DBHelper类:

  1 package com.example.core;
2
3 import java.util.ArrayList;
4 import java.util.List;
5
6 import android.content.Context;
7 import android.database.Cursor;
8 import android.database.sqlite.SQLiteDatabase;
9
10 import com.example.sqllite.Student;
11
12 /**
13 * @author fanchangfa
14 *数据库操作类
15 *增删改查
16 *获取分页查询数据
17 *获取表中记录总数
18 */
19 public class DbServer{
20
21 private DBHelper dbhelper;
22
23 public DbServer(Context context){
24 this.dbhelper = new DBHelper(context);
25 }
26
27 /**
28 * 增加信息
29 * @param student 增加的学生信息
30 */
31 public void add(Student student){
32 SQLiteDatabase db = dbhelper.getWritableDatabase();
33 db.execSQL("insert into student(name , age) values(?,?)",
34 new Object[]{student.getName(),student.getAge()});
35 }
36
37 /**
38 * 删除信息
39 * @param id 要删除的学生id
40 */
41 public void delete(Integer id){
42 SQLiteDatabase db = dbhelper.getWritableDatabase();
43 db.execSQL("delete from student where id = ?",new Object[]{id});
44 }
45
46 /**
47 * 修改指定id的学生信息
48 * @param stu 包括修改学生的id,以及修改的信息
49 */
50 public void alter(Student stu){
51 SQLiteDatabase db = dbhelper.getWritableDatabase();
52 db.execSQL("update student set name=?,age=? where id=?",
53 new Object[]{stu.getName(),stu.getAge(),stu.getId()});
54 }
55
56 /**
57 * 查找信息
58 * @param id 要查找的学生id
59 */
60 public Student find(Integer id){
61 SQLiteDatabase db = dbhelper.getReadableDatabase();
62 Cursor cursor = db.rawQuery("select * from student where id = ?",new String[]{id.toString()});
63
64 if(cursor.moveToFirst()) //如果查询结果集中有数据,将游标指向第一条记录
65 {
66 int sid = cursor.getInt(cursor.getColumnIndex("id"));
67 String name = cursor.getString(cursor.getColumnIndex("name"));
68 int age = cursor.getInt(cursor.getColumnIndex("age"));
69
70 return new Student(sid , name , age);
71 }
72
73 cursor.close();
74
75 return null;
76 }
77
78 /**
79 * 分页查询数据
80 * @param start 分页开始记录数
81 * @param end 分页结束记录数
82 * @return 查询结果集
83 */
84 public List page(int start , int end){
85 SQLiteDatabase db = dbhelper.getReadableDatabase();
86 List page = new ArrayList();
87 Cursor cur = db.rawQuery("select id,name,age from student order by id limit ?,?",
88 new String[]{String.valueOf(start),String.valueOf(end)});
89
90 while(cur.moveToNext()){
91 int id = cur.getInt(cur.getColumnIndex("id"));
92 String name = cur.getString(cur.getColumnIndex("name"));
93 int age= cur.getInt(cur.getColumnIndex("age"));
94 page.add(new Student(id,name,age));
95 }
96
97 cur.close();
98
99 return page;
100 }
101
102 /**
103 * 返回指定分页数据
104 * @param start
105 * @param end
106 * @return Cursor型数据
107 */
108 public Cursor curpage(int start , int end){
109 SQLiteDatabase db = dbhelper.getReadableDatabase();
110 Cursor cur = db.rawQuery("select id as _id,name,age from student order by id limit ?,?",
111 new String[]{String.valueOf(start),String.valueOf(end)});
112
113 cur.moveToFirst();
114
115 return cur;
116 }
117
118 /**
119 * 获取表记录总数
120 * @return
121 */
122 public long getCount(){
123 SQLiteDatabase db = dbhelper.getReadableDatabase();
124
125 Cursor cur = db.rawQuery("select count(*) from student",null);
126 cur.moveToFirst();
127
128 long count = cur.getLong(0);
129
130 cur.close();
131
132 return count;
133 }
134
135 /**
136 * 执行事务
137 */
138 public void transaction(){
139 SQLiteDatabase db = dbhelper.getWritableDatabase();
140 db.beginTransaction();
141
142 try{
143 db.execSQL("update student set age = 21 where id =5");
144 db.execSQL("update student set age= 22 where id=6");
145 db.setTransactionSuccessful();
146 //事务默认有commit、rollback,默认为False,即非提交状态,需要设置为commit
147 }
148 finally{
149 db.endTransaction();
150 }
151
152 }
153 }

 

 

具体操作代码中已经注释完善,可以进行试验。

下面要对其进行测试:

编写测试单元如下:

 1 package com.example.test;
2
3 import java.util.List;
4
5 import com.example.core.DbServer;
6 import com.example.sqllite.Student;
7
8 import android.test.AndroidTestCase;
9 import android.util.Log;
10
11 /**
12 * @author fanchangfa
13 * 数据库操作单元测试
14 * 测试DbServer中数据的增删改查
15 *
16 */
17 public class DbServerTest extends AndroidTestCase{
18
19 //控制台打印信息标志
20 private static final String TAG = "SQLtest";
21
22 /**
23 * 添加数据测试
24 */
25 public void addTest(){
26 DbServer dbserver = new DbServer(this.getContext());
27 for(int i = 0 ; i<20 ; i++)
28 {
29 Student stu = new Student("fanchangfa"+i,20);
30 dbserver.add(stu);
31 }
32 }
33
34 public void deleteTest(){
35 DbServer dbserver = new DbServer(this.getContext());
36 dbserver.delete(2);
37 }
38
39 public void alterTest(){
40 DbServer dbserver = new DbServer(this.getContext());
41 Student stu = dbserver.find(3);
42 stu.setName("liuzihang");
43 stu.setAge(25);
44 dbserver.alter(stu);
45 }
46
47 /**
48 * 测试数据库查找
49 * 根据提供id返回记录结果
50 */
51 public void findTest(){
52 DbServer dbserver = new DbServer(this.getContext());
53 Student stu = dbserver.find(5);
54 Log.i(TAG, stu.toString());
55 }
56
57 /**
58 * 数据库查找分页测试
59 */
60 public void findpage(){
61 DbServer dbserver = new DbServer(this.getContext());
62 List students = dbserver.page(0, 8);
63
64 for(Student stu : students){
65 Log.i(TAG,stu.toString());
66 }
67
68 }
69
70 /**
71 * 执行事务测试
72 */
73 public void transactionTest(){
74 DbServer dbserver = new DbServer(this.getContext());
75 dbserver.transaction();
76 }
77
78 }

 

经验证,没有问题,由于此文件系统和操作比较麻烦,我将自己写的实例放到这里共大家下载,此实例中包括数据库的操作以及SQLite中事物的使用,以及将在下一篇写的关于ListView显示数据的几种方法,界面虽然很难看,不过这只是demo,希望多多谅解,有问题多多交流。希望这里会是我们拥有共同爱好的程序员们相互交流共同进步的平台,而不是只是为了增加访问量而将文章放在这里。

 


推荐阅读
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • 本文讨论了如何优化解决hdu 1003 java题目的动态规划方法,通过分析加法规则和最大和的性质,提出了一种优化的思路。具体方法是,当从1加到n为负时,即sum(1,n)sum(n,s),可以继续加法计算。同时,还考虑了两种特殊情况:都是负数的情况和有0的情况。最后,通过使用Scanner类来获取输入数据。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • vue使用
    关键词: ... [详细]
  • 本文介绍了解决Netty拆包粘包问题的一种方法——使用特殊结束符。在通讯过程中,客户端和服务器协商定义一个特殊的分隔符号,只要没有发送分隔符号,就代表一条数据没有结束。文章还提供了服务端的示例代码。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • ZSI.generate.Wsdl2PythonError: unsupported local simpleType restriction ... [详细]
author-avatar
程璇
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有