SQLite
安卓内置数据库为非常轻量级的SQLite,同SQL语法一致,本文会记录一下SQLite数据库的使用及基本的增删改查操作。
- SQLite与 MySql的不同之处
主键自增长:SQLite是 autoincrement,MySql 是auto_increment
主键: SQLite 主键一般定义为 _id,在做查询时要求主键列名必须是 _id(本身不是_id ,可以起别名 ),不然拿不到主键值。
例如:
db.execSQL("create table person(_id integer primary key autoincrement,name varchar(20),monary integer(10))");
- 表结构的简单介绍
SQLite是一个轻量级的数据库,他支持在表格的末尾增加字段和修改表名的操作,但是不支持删除字段及更改一个已经存在的字段的类型。
创建数据库
SQLiteOpenHelper
创建数据库主要使用SQLiteOpenHelpe,创建数据库时一般需要继承该类并实现它的构造方法,除此之外还有两个方法onCreate(创建数据库) 与 onUpgrade(更新数据库) 需要被复写,在安卓中一旦创建了一个数据库的表,那么这个表会一直存在于应用的文件夹中,除非程序被卸载,所以创建完毕后只能通过onUpgrade来更新数据库。
class MyHelper extends SQLiteOpenHelper {
public MyHelper(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
}
@Override
public void onCreate(SQLiteDatabase db) {
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
-
构造函数中四个参数的意义:
- context:代表在哪个上下文中打开数据库
- name:数据库的名字,如果不指定,该数据库写在内存当中,指定,写在本地文件中
- factory:就是cursor,用于对数据的操作,一般为null
- version:代表数据库的版本,最低为1
-
onCreate()方法
一般在该函数中创建表,需要注意的是表只会创建一次 -
onUpgrade()
用于更新数据库,三个参数分别为数据库、旧版本号、新版本号 -
getWriterDatbas/getReadableDatabase
这两个方法都可以创建并打开数据库,他们都是返回一个SQLiteDatabase对象,这个对象就是我们实际用来操作数据库的对象,但是当内存空间已满,getReadableDatabase就返回一个只读的SQLiteDatabase
MyHelper myHelper = new MyHelper(this, "Demo.db", null, 1);
SQLiteDatabase sqLiteDatabase = myHelper.getReadableDatabase();
SQLiteDatabase
对数据库进行”增、删、改、查”的操作都是通过这个类来实现的,SQLiteOpenHelper通过getWritableDatabase()或者getReadableDatabase()方法返回这个类型的对象。
该类还能打开第三方的数据库例如我们要打开项目中files文件夹下的数据库
String path = new File(context.getFilesDir(), "antivirus.db" )
.getAbsolutePath();
SQLiteDatabase db = SQLiteDatabase.openDatabase(path, null,
SQLiteDatabase. OPEN_READONLY);
增删改查
- 增
手动方式:
execSQL(insert into 表名(字段值1,字段值2) values (?,?),new Object[]{"",""});
API方式:
//ContentValues是一个对象,用于封装我们要插入的数据
ContentValues con = new ContentValues();
con.putString("key","value");
//nullColumnHack代表着如果没有插入ContentValues对象或该对象没有内容时,用什么值进行替代,这个大多设置为null,该方法回一个long类型数字,-1代表插入失败,否则返回该行的id
flag = insert("表名",nullColumnHack,ContentValues);
- 删
手动方式
execSQL("delete from 表名 where 条件 = ?",new Object[]{"对应的站位符"});
API
delate("表名","条件例如name=?",new String[]{});
返回int数值,代表删除了几行数据
- 改
手动方式
execSQL("update 表名 set 字段名 = ?where 条件",new String[]{"占位符1"。。。});
API
update("表名",ContentValues对象,"判断条件例如name=?",new String[]{"占位符赋值"});
- 查
手动方式
rawQuery(“select name,pwd from user”);
该方法返回一个Cursor对象,可以通过该对象的 moveToNext()来移动游标
getString(int值,就是你查询的字段的排序,从0开始)也可以写成:
getString(c.getColumnIndex(“字段名”));来获取该字段对应的值
Cursor cursor = rawQuery("select name,pwd from user");
// 遍历所有的元素
if(cursot.moveToFirst()){
do{
String name=cursor.getString(cursor.getColumnIndex("pages"));
String name=curosr.getString(cursor.getColumnIndex("name"));
}while(cursor.moveToNext());
}
cursor.close(); // 在这里释放掉所有的元素
API方式:
query("表名",new String[]{"字段名"},筛选条件where,填充where条件的String[]数组,分组筛选条件,having筛选条件,ordetBy排序查询条件,分页查询条件limit);
当字段名设置为null时,返回所有字段,后面的筛选条件设置null代表返回所有行,同样是返回一个Cursor对象,同上获取字段值
分页查询: select * from black_list limit 10 offset 20 从20后面查询10条 也就是21到30条
-
where子句的条件种类
- 比较运算符
>
>=
<
<=
=
!=可以用<>替代
- 逻辑运算符
and 条件交集
or 条件并集
not条件取反
Not 效率极低
- between…and…
区间取值
相当于>= and <=
注意:between小值 and大值
select * from pro where id>=2 and id<=9;
等同于
select * from pro where id between 2 and 9;
- in
可以比较多个值
相当于 or or or ……
select * from pro where id=1 or id=3 or id=5 or id=7 or id=9;
等同于
select * from pro where id in(1,3,5,7,9);
- null值操作
is null; 判断为空
is not null; 判断不为空(not 字段 is null)
数据库中null值不能使用=号比较
- like
模糊查询
通配符使用:
1. % 匹配所有(0~多个任意字符)
2. _ 匹配一个任意字符
select * from 列表名 where name like %要匹配的字符%;
- 事务
代表多个事件同生共死,只要有一个发生了异常,那么数据则不改变
try{
//①开启事务:
SQLDatabase对象.beginTransaction();
//②逻辑代码,例如,银行的转账操作,一个账户数额减少,一个账户数额增加
......
//③设置事务成功
db.setTransactionSuccessful();
}catch{
//处理语句
}finally{
// ④关闭事务已经设置了事务执行成功,那么提交事务, sql语句生效反之,数据回滚,之前执行的 sql语句全部无效
db.endTransaction();
}