SQLite---使用约束
背景
在使用SQLite建表的时候,通常会使用
_id
作为唯一标示,使用
PRIMARY KEY
与
AUTOCREMENT
进行修饰,而主键是不可以重复的。但是在这张表中还有其他的Column也不允许重复,则可以使用Unique约束。
常用的约束有:
- Unique:确保该列中的所有值是不同的
- Not Null:确保被该约束修饰的列不会有空值
- Default:当该字段没有值时,使用默认值填充
- Primary Key:确保该列可以唯一标示一条数据,不会重复
- Check:确保该列的值都满足条件,如果不满足,则无法插入
举例
现在有一张表,记录了本设备最近使用的App历史记录,并且按照进入的时间进行排序显示。当同一个App重复进入的时候,则需要覆盖原有Row。
那么这张表拥有四列:
-
_id
:自增标志ID -
app_name
:访问的APP名,必须唯一 -
access_time
:访问时间 -
access_count
:访问次数,检测值必须大于0次
步骤
-
在建表时,为唯一列设置
Unique
属性 -
在建表时,加入
Conflict
处理策略 -
在插入时,决定
Conflict
处理策略
注意:无论是建表时决定Conflict的处理策略还是插入时决定处理策略,
Unique
属性都是必须的
建表实现
创建
app_access_table
表,其中:
-
_id
:使用Primary Key
约束,自增 -
app_name
:使用Unique
,当有冲突时,则替换该条 -
access_time
:使用Default
约束,默认值为10000 -
aacess_count
:使用Check
约束,检查是否大于0
CREATE TABLE IF NOT EXISTS app_access_table (
_id INTEGER PRIMARY KEY AUTOINCREMENT ,
app_name TEXT UNIQUE ON CONFLICT REPLACE ,
access_time LONG DEFAULT 10000 ,
access_count INTEGER CHECK(access_count>0)
)
该建表语句决定了,当有新数据插入时,如果有相同
app_name
的话,则使用
Replace
策略替换原有数据
插入实现
创建
app_access_table
表,其中:
-
_id
:主键,自增 -
app_name
:只有Unique
约束 -
access_time
:默认值为10000
CREATE TABLE IF NOT EXISTS app_access_table (
_id INTEGER PRIMARY KEY AUTOINCREMENT ,
app_name TEXT UNIQUE ,
access_time LONG DEFAULT 10000 ,
access_count INTEGER CHECK(access_count>0)
)
在数据插入时使用
insertWithOnConflict
来决定冲突时,该如何处理,此处使用
SQLiteDatabase.CONFLICT_REPLACE
来决定数据冲突时,替换该条数据
db.insertWithOnConflict(TABLE_NAME, null, values, SQLiteDatabase.CONFLICT_REPLACE);
值得注意的是,SQLiteDatabase在面对Replace的处理是,首先删除原有的行,然后再把新的这一行添加到表中,替换完后,
_id
字段会发生变化。
其他处理策略:
-
CONFLICT_ROLLBACK =1
当冲突发生时,立即回滚,结束当前的Transaction,并且会返回
SQLITE_CONSTRAINT
错误码。如果没有Transaction的话,那么就和ABORT
一样 - CONFLICT_ABORT = 2 当冲突发生时,不会执行Rollback,而会保留之前的数据。这是默认行为
- CONFLICT_FAIL =3