Android学习笔记——数据库SQLite

1、什么是SQLite以及SQLite特点

这个不讲

2、SQLite的数据类型

类型说明
NULL类型为空
VARCHAR(n)长度不固定,但有最大限制(n)的字串,n最大不能超过4000
CHAR(n)长度固定为n的字串,n的大小不能超过254
INTEGER值被表示为整数
REAL浮动的数值
TEXT文本字符串
BLOBBLOB数据块,存进去和读出来的格式保持一致
DATE日期,即年月日
TIME时间,时分秒

这些数据类型都是SQL92标准中规定的标准数据库数据类型(见下表)。

SQL数据库数据类型详解

数据类型类型描 述
bit整型bit 数据类型是整型,其值只能是0、1或空值。这种数据类型用于存储只有两种可能值的数据,如Yes 或No、True 或Fa lse 、On 或Off
int整型int 数据类型可以存储从- 231(-2147483648)到231 (2147483 647)之间的整数。存储到数据库的几乎所有数值型的数据都可以用这种数据类型。这种数据类型在数据库里占用4个字节
smallint整型smallint 数据类型可以存储从- 215(-32768)到215(32767)之间的整数。这种数据类型对存储一些常限定在特定范围内的数值型数据非常有用。这种数据类型在数据库里占用2 字节空间
tinyint整型tinyint 数据类型能存储从0到255 之间的整数。它在你只打算存储有限数目的数值时很有用。 这种数据类型在数据库中占用1 个字节
numeric精确数值型numeric数据类型与decimal 型相同
decimal精确数值型decimal 数据类型能用来存储从-1038-1到1038-1的固定精度和范围的数值型数据。使用这种数据类型时,必须指定范围和精度。 范围是小数点左右所能存储的数字的总位数。精度是小数点右边存储的数字的位数
money货币型money 数据类型用来表示钱和货币值。这种数据类型能存储从-9220亿到9220 亿之间的数据,精确到货币单位的万分之一
smallmoney货币型smallmoney 数据类型用来表示钱和货币值。这种数据类型能存储从-214748.3648 到214748.3647 之间的数据,精确到货币单位的万分之一
float近似数值型float 数据类型是一种近似数值类型,供浮点数使用。说浮点数是近似的,是因为在其范围内不是所有的数都能精确表示。浮点数可以是从-1.79E+308到1.79E+308 之间的任意数
real近似数值型real 数据类型像浮点数一样,是近似数值类型。它可以表示数值在-3.40E+38到3.40E+38之间的浮点数
datetime日期时间型datetime数据类型用来表示日期和时间。这种数据类型存储从1753年1月1日到9999年12月3 1日间所有的日期和时间数据, 精确到三百分之一秒或3.33毫秒
Smalldatetime日期时间型smalldatetime 数据类型用来表示从1900年1月1日到2079年6月6日间的日期和时间,精确到一分钟
cursor特殊数据型cursor 数据类型是一种特殊的数据类型,它包含一个对游标的引用。这种数据类型用在存储过程中,而且创建表时不能用
timestamp特殊数据型timestamp 数据类型是一种特殊的数据类型,用来创建一个数据库范围内的唯一数码。 一个表中只能有一个timestamp列。每次插入或修改一行时,timestamp列的值都会改变。尽管它的名字中有“time”, 但timestamp列不是人们可识别的日期。在一个数据库里,timestamp值是唯一的
Uniqueidentifier特殊数据型Uniqueidentifier数据类型用来存储一个全局唯一标识符,即GUID。GUID确实是全局唯一的。这个数几乎没有机会在另一个系统中被重建。可以使用NEWID 函数或转换一个字符串为唯一标识符来初始化具有唯一标识符的列
char字符型char数据类型用来存储指定长度的定长非统一编码型的数据。当定义一列为此类型时,你必须指定列长。当你总能知道要存储的数据的长度时,此数据类型很有用。例如,当你按邮政编码加4个字符格式来存储数据时,你知道总要用到10个字符。此数据类型的列宽最大为8000 个字符
varchar字符型varchar数据类型,同char类型一样,用来存储非统一编码型字符数据。与char 型不一样,此数据类型为变长。当定义一列为该数据类型时,你要指定该列的最大长度。 它与char数据类型最大的区别是,存储的长度不是列长,而是数据的长度
text字符型text 数据类型用来存储大量的非统一编码型字符数据。这种数据类型最多可以有231-1或20亿个字符
nchar统一编码字符型nchar 数据类型用来存储定长统一编码字符型数据。统一编码用双字节结构来存储每个字符,而不是用单字节(普通文本中的情况)。它允许大量的扩展字符。此数据类型能存储4000种字符,使用的字节空间上增加了一倍
nvarchar统一编码字符型nvarchar 数据类型用作变长的统一编码字符型数据。此数据类型能存储4000种字符,使用的字节空间增加了一倍
ntext统一编码字符型ntext 数据类型用来存储大量的统一编码字符型数据。这种数据类型能存储230 -1或将近10亿个字符,且使用的字节空间增加了一倍
binary二进制数据类型binary数据类型用来存储可达8000 字节长的定长的二进制数据。当输入表的内容接近相同的长度时,你应该使用这种数据类型
varbinary二进制数据类型varbinary 数据类型用来存储可达8000 字节长的变长的二进制数据。当输入表的内容大小可变时,你应该使用这种数据类型
image二进制数据类型image 数据类型用来存储变长的二进制数据,最大可达231-1或大约20亿字节

3、SQLite的常用方法

方法名称方法表示含义
openOrCreateDatabase(String path , SQLiteDatabase.CursorFactory factory)打开或创建数据库
insert(String table , String nullColumnHack , ContentValues values)插入一条记录
delete(String table , String whereClause , String[] whereArgs)删除一条记录
query(String table , String[] columns , String selection , String[] selectionArgs , String groupBy , String having , String orderBy)查询一条记录
update(String table , ContentValues values , String whereClause , String[] whereArgs)修改记录
execSQL(String sql)执行一条SQL语句
close()关闭数据库

4.常用方法的具体用法

4.1 打开或创建数据库。

打开或者创建一个名为test.db的数据库,方法的第一个参数是test.db的路径,第二个参数是打开或创建的方式,第三个参数是SQLiteDatabase.CursorFactory则是一个产生Cursor对象的工厂类 , 这个后面再讲,此处打开或新建一个数据库只要填null即可。

        SQLiteDatabase database = openOrCreateDatabase("test.db", Context.MODE_PRIVATE,null);

4.2创建一张表

这里我们用执行SQL语句的方式创建了一张表。属性为:id(主键,并且会自动增加),VARCHAR类型的 name , INTEGER类型的age.

database.execSQL("CREATE TABLE person (_id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR, age INTEGER)");

4.3插入数据

插入数据有两种方法

4.3.1 Insert方法

ContentValues contentValues = new ContentValues();
    contentValues.put("name","abby");
    contentValues.put("age",23);
    database.insert("person",null,contentValues);

insert方法中共有三个参数:

db.insert(String table, String nullColumnHack, ContentValues values);  
  • 第一个是表的名称,
  • 第二个参数表示如果插入的数据每一列都为空的话,需要指定此行中某一列的名称,
  • 第三个参数是一个ContentValues的变量,是键值对组成的map

4.3.2 execSQL方法

Person person = new Person();
person.name = "abby";
person.age = 23;
database.execSQL("INSERT INTO person VALUES (NULL , ? , ?)", new Object[]{person.name, person.age});

这句可以看出来是执行了一条SQL语句。

4.4更新数据

更新数据也有两种不同的方式

4.4.1 update方法

contentValues = new ContentValues();
contentValues.put("age",35);
database.update("person",contentValues,"name = ?" , new String[]{"Jerry"});

update 方法共有四个参数:

db.update(String table, Contentvalues values, String whereClause, String whereArgs);  
  • 第一个参数是表的名称
  • 第二个参数是contentValues类型的变量
  • 第三个参数是表示WHERE表达式
  • 第四个参数表示占位符的实际参数值

4.4.2 execSQL方法

使用sql语言,这里不再详述。

4.5 查询数据

4.5.1 rawQuery方法

    Cursor c = database.rawQuery("SELECT * FROM person WHERE age >= ?", new String[]{"33"});
    while (c.moveToNext()) {
        int _id = c.getInt(c.getColumnIndex("_id"));
        String name = c.getString(c.getColumnIndex("name"));
        int age = c.getInt(c.getColumnIndex("age"));
        Log.i("db", "_id=>" + _id + ", name=>" + name + ", age=>" + age);
    }
    c.close();

我们查看log 可以看到:

03-22 15:38:03.328 7782-7782/test.abby.com.animtest I/db: _id=>2, name=>Jerry, age=>35

rawQuery方法是最简单的查询数据的方法:

db.rawQuery(String sql, String[] selectionArgs);  

他将所有的SQL语句都组织到一个字符串中,使用占位符代替实际参数,selectionArgs就是占位符实际参数集;

4.5.2 query方法

db.query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy);  

-

db.query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit);  

-

db.query(String distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit);  

下面的几种参数都很类似,columns表示要查询的列所有名称集,selection表示WHERE之后的条件语句,可以使用占位符,groupBy指定分组的列名,having指定分组条件,配合groupBy使用,orderBy指定排序的列名,limit指定分页参数,distinct可以指定“true”或“false”表示要不要过滤重复值。需要注意的是,selection、groupBy、having、orderBy、limit这几个参数中不包括“WHERE”、“GROUP BY”、“HAVING”、“ORDER BY”、“LIMIT”等SQL关键字。
最后,他们同时返回一个Cursor对象,代表数据集的游标,有点类似于JavaSE中的ResultSet。(引用【Android中SQLite应用详解】)

4.5.3 Cursor 对象

上述所有的查询方法返回的都是个cursor对象,Cursor在查询数据时用的非常频繁,这里专门开一个小节对cursor进行讲解。
Cursor 是每行的集合,在使用他时你需要牢牢的记住这一点,而且使用时,你需要知道每一列的名称以及数据类型。cursor的所有数据都是通过下标获得的。

cursor的常用方法:

  • c.move(int offset); //以当前位置为参考,移动到指定行
  • c.moveToFirst(); //移动到第一行
  • c.moveToLast(); //移动到最后一行
  • c.moveToPosition(int position); //移动到指定行
  • c.moveToPrevious(); //移动到前一行
  • c.moveToNext(); //移动到下一行
  • c.isFirst(); //是否指向第一条
  • c.isLast(); //是否指向最后一条
  • c.isBeforeFirst(); //是否指向第一条之前
  • c.isAfterLast(); //是否指向最后一条之后
  • c.isNull(int columnIndex); //指定列是否为空(列基数为0)
  • c.isClosed(); //游标是否已关闭
  • c.getCount(); //总数据项数
  • c.getPosition(); //返回当前游标所指向的行数
  • c.getColumnIndex(String columnName);//返回某列名对应的列索引值
  • c.getString(int columnIndex); //返回当前行指定列的值
  • c.getColumnCount() ;//返回列数
  • c.copyStringToBuffer(int columnIndex, CharArrayBuffer buffer) ;//在缓冲区中检索请求的列的文本,并将其存储
  • c.getColumnIndexOrThrow(String columnName) ;//从0开始获得指定列的名称,如果没有,就抛出IllegalArgumentException 异常。
  • c.getColumnName(int columnIndex) ;//从给定的索引返回列名
  • c.getColumnNames() ;//返回一个字符串数组的列名

4.6 关闭数据库

当使用数据库后,最后一定要关闭数据库,否则会抛出SQLiteException
关闭数据库的方法非常简单:

database.close();

给出包括上面内容的完整代码:

 protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    SQLiteDatabase database = openOrCreateDatabase("test.db", Context.MODE_PRIVATE,null);
    database.execSQL("DROP TABLE IF EXISTS person");
    database.execSQL("CREATE TABLE person (_id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR, age INTEGER)");

    Person person = new Person();
    person.name = "Abby";
    person.age = 23;
    database.execSQL("INSERT INTO person VALUES (NULL , ? , ?)", new Object[]{person.name, person.age});

    ContentValues contentValues = new ContentValues();
    contentValues.put("name","Jerry");
    contentValues.put("age",25);
    database.insert("person",null,contentValues);

    contentValues = new ContentValues();
    contentValues.put("age",35);
    database.update("person",contentValues,"name = ?" , new String[]{"Jerry"});


    Cursor c = database.rawQuery("SELECT * FROM person WHERE age >= ?", new String[]{"33"});
    while (c.moveToNext()) {
        int _id = c.getInt(c.getColumnIndex("_id"));
        String name = c.getString(c.getColumnIndex("name"));
        int age = c.getInt(c.getColumnIndex("age"));
        Log.i("db", "_id=>" + _id + ", name=>" + name + ", age=>" + age);
    }
    c.close();

    database.close();
}

4.7 SQLiteOpenHelper

在实际开发中,为了能够更好的管理和维护数据库,我们常常会会封装一个继承自SQLiteOpenHelper类的数据库操作类,然后以这个类为基础,再封装我们的业务逻辑方法。现在我们来讲一讲具体用法:

首先创建一个名为DBHelper的类继承SQLiteOpenHelper,并建立构造函数,以及重写onCreate 和 onUpgrade方法

public class DBHelper extends SQLiteOpenHelper {
public DBHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
    super(context, name, factory, version);
}

public DBHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version, DatabaseErrorHandler errorHandler) {
    super(context, name, factory, version, errorHandler);
}

@Override
public void onCreate(SQLiteDatabase db) {

}

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

}
}

其中,onCreate方法是数据库首次创建时会执行的方法,所以初始化数据的操作可以放在这里面。

onUpgrade方法是当打开数据库时传入的版本号与当前的版本号不同时会调用该方法。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值