1、SQLite简介
SQLite是一个进程内的库,实现了自给自足的、无服务器的、零配置的、事务性的 SQL 数据库引擎。它是一个零配置的数据库,这意味着与其他数据库一样,您不需要在系统中配置。就像其他数据库,SQLite 引擎不是一个独立的进程,可以按应用程序需求进行静态或动态连接。SQLite 直接访问其存储文件。
SQLite优点
- 不需要一个单独的服务器进程或操作系统
- SQLite不需要配置
- 单一文件,数据库中所有的信息(比如表、视图等)都包含在一个文件内。这个文件可以自由复制到其它目录或其它机器上。
- SQLite是轻量级的,完全配置时小于400kb
- SQLite事务是完全兼容ACID的,允许多个进程或线程安全访问
- 开源
- 跨平台/可移植性
- 弱类型字段,同一列中的数据可以是不同类型
SQLite数据类型
每个存储在 SQLite 数据库中的值都具有以下存储类之一:
储存类 | 描述 |
NULL | 值是一个空值 |
INTEGER | 值是一个带符号的整数,根据值的大小存储在1、2、3、4、6、8字节中 |
REAL | 值是一个浮点值,存储为8字节的IEEE浮点数字 |
TEXT | 值是一个文本字符串,使用数据库编码(UTF-8、UTF-16BE 或 UTF-16LE)存储。 |
BLOB | 值是一个 blob 数据,完全根据它的输入存储 |
SQLite的存储类稍微比数据类更普遍。INTEGER储存类包含6种不同的不同长度的整数类型。
SQLite亲和类型
SQLite支持列的亲和类型概念。任何列仍然可以存储任何类型的数据,当数据插入时,该字段的数据将会优先采用亲缘类型作为该值的存储方式。具体可以查看下面链接:
2、SQLiteDatabase
SQLiteDatabase是Android中创建、删除、执行SQL命令等其它常见数据库管理方法的类。
SQLiteDatabase的常用方法 :
最重要的是execSQL和query方法。execSQL可以执行一个非SELECT的SQL语句或任何其他返回数据的SQL语句,query用来执行查询语句。
查询数据
查询数据是通过Cursor类来实现的,当我们使用SQLiteDatabase.query()时,会得到一个Cursor对象,Cursor指向就是没一条数据。它提供很多有关查询的方法。
public Cursor query(String table,String[] columns,String selection,String[] selectionArgs,String groupBy,String having,String orderBy,String limit);
各个参数的意义说明:
参数table:指定查询的表名
参数columns:列名称数组
参数selection:条件字句,相当于where
参数selectionArgs:条件字句,参数数组
参数groupBy:分组列
参数having:分组条件
参数orderBy:排序列
参数limit:分页查询限制
参数Cursor:返回值,相当于结果集ResultSet
Cursor是一个游标接口,提供了遍历查询结果的方法,如移动指针方法move(),获得列值方法getString()等.
Cursor游标常用方法
方法名称 | 方法描述 |
getCount() | 获得总的数据项数 |
isFirst() | 判断是否第一条记录 |
isLast() | 判断是否最后一条记录 |
moveToFirst() | 移动到第一条记录 |
moveToLast() | 移动到最后一条记录 |
move(int offset) | 移动到指定记录 |
moveToNext() | 移动到下一条记录 |
moveToPrevious() | 移动到上一条记录 |
getColumnIndexOrThrow(String columnName) | 根据列名称获得列索引 |
getInt(int columnIndex) | 获得指定列索引的int类型值 |
getString(int columnIndex) | 获得指定列索引的String类型值 |
3、SQLiteOpenHelper
SQLiteOpenHelper是对SQLiteDatabase的封装,用这个类我们能够方便的管理和操作数据库。SQLIteOpenHelper是一个抽象类,使用时需要继承这个类。
public class MyDBHelper extends SQLiteOpenHelper {
private static final String CREATE_BOOK = "create table if not exists Book " +
"(id integer primary key autoincrement,author text,price real,pages integer,name text)";
private static final String CREATE_GORY = "create table Category(" +
"id integer primary key autoincrement," +
"category_name text," +
"category_code integer)";
private Context mContext;
/**
*SQLiteOpenHelper 有3个构造方法
* @param context 上下文
* @param name 数据库名
* @param factory 游标,可以为null,则使用默认的游标工厂
* @param version 数据库的版本号
*/
public MyDBHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
mContext = context;
}
/*
errorHandler sqlite报告数据库损坏时使用,或null以使用默认错误处理程序
*/
public MyDBHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version, DatabaseErrorHandler errorHandler) {
super(context, name, factory, version, errorHandler);
}
/*
openParams 一个用来打开SQLiteDatabase的配置参数 API 28增加
*/
// public MyDBHelper(Context context, String name, int version, SQLiteDatabase.OpenParams openParams) {
// super(context, name, version, openParams);
// }
/**
* 数据库第一次建立时被调用
* 重写抽象方法
* @param db
*/
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_BOOK);
db.execSQL(CREATE_GORY);
Toast.makeText(mContext,"create success",Toast.LENGTH_SHORT).show();
}
/**
* 数据库更新时使用
* 重写抽象方法
* @param db
* @param oldVersion
* @param newVersion
*/
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//先删除Book和Category表,然后新建表
db.execSQL("drop table if exists Book");
db.execSQL("drop table if exists Category");
onCreate(db);
}
}
使用SQLiteOpenHelper需要继承SQLiteOpenHelper,并实现onCreate和onUpgradel两个方法。
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private static final int REQUES_CODE = 0 ;
private Button bt_create_db,add_data,update_data,delect_data,query_data;
private MyDBHelper myDBHelper;
SQLiteDatabase db;
/**
* ContentValues类型的一个封装了列名称和列值的Map
*/
private ContentValues values;
private static final String TAG = "MainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
requestPermissions();
bt_create_db = findViewById(R.id.bt_create_bt);
add_data = findViewById(R.id.add_data);
update_data = findViewById(R.id.update_data);
delect_data = findViewById(R.id.delect_data);
query_data = findViewById(R.id.query_data);
//myDBHelper = new MyDBHelper(this,"BookStore",null,1);
/*
更新数据库
*/
myDBHelper = new MyDBHelper(this,"BookStore",null,2);
bt_create_db.setOnClickListener(this);
add_data.setOnClickListener(this);
update_data.setOnClickListener(this);
delect_data.setOnClickListener(this);
query_data.setOnClickListener(this);
values = new ContentValues();
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.bt_create_bt:
/**
* 创建数据库有两种方法:
* 1、getReadableDatabase()
* 2、getWritableDatabase()
* 这个两种方法都能创建或者打开一个现有的数据库,不同在于,当数据库不可写入的时候,getReadableDatabase()创建的
* 对象将会以只读的方式打开数据库,getWritableDatabase()将会出现异常。
*/
db = myDBHelper.getWritableDatabase();
break;
case R.id.add_data:
if(db == null) {
db = myDBHelper.getWritableDatabase();
}
values.put("name","The Da Vinci code");
values.put("author","Dan Brown");
values.put("pages",454);
values.put("price",16.96);
//插入数据
//参数1 表名称,
//参数2 空列的默认值
//参数3 ContentValues类型的一个封装了列名称和列值的Map;
db.insert("Book",null,values);
values.clear();
values.put("name","The Lost Symbol");
values.put("author","Dan Brown");
values.put("pages",510);
values.put("price",19.95);
db.insert("Book",null,values);
values.clear();
break;
case R.id.update_data:
if(db == null) {
db = myDBHelper.getWritableDatabase();
}
values.put("price",10.99);
//调用SQLiteDatabase的update(String table,ContentValues values,String whereClause, String[] whereArgs)方法
//更新数据,参数:1表名 2要更新的数据 3和4是要更新的约束条件,为null,则更新所有行
db.update("Book",values,"name = ?",new String[]{"The Da Vinci code"});
break;
case R.id.delect_data:
//参数1 表名称
//参数2 删除条件
//参数3 删除条件值数组
Toast.makeText(this,"删除数据",Toast.LENGTH_SHORT).show();
if(db == null) {
db = myDBHelper.getWritableDatabase();
}
db.delete("Book","pages > ?",new String[]{"500"});
break;
case R.id.query_data:
if(db == null) {
db = myDBHelper.getWritableDatabase();
}
//查询表中所有数据
Cursor cursor = db.query("Book",null,null,null,null,null,null);
if(cursor.moveToFirst()) {
do {
//遍历Cursor对象,取出数据并打印
Toast.makeText(this,"查询数据",Toast.LENGTH_SHORT).show();
String name = cursor.getString(cursor.getColumnIndex("name"));
String author = cursor.getString(cursor.getColumnIndex("author"));
int pages = cursor.getInt(cursor.getColumnIndex("pages"));
double price = cursor.getDouble(cursor.getColumnIndex("price"));
Log.d(TAG,"book name is " + name);
Log.d(TAG,"book author is " + author);
Log.d(TAG,"book pages is " + pages);
Log.d(TAG,"book price is " + price);
} while (cursor.moveToNext());
}
cursor.close();
break;
}
}
}
使用adb命令查看数据库:
1.在命令行窗口输入adb shell回车,就进入了Linux命令行,现在就可以使用Linux的命令了。
2.ls回车,显示所有的东西,其中有个data。
3.cd data回车,再ls回车,cd data回车,ls回车后就会看到很多的com................,那就是系统上的应用程序包名,找到你数据库程序的包名,然后进入。
4.进去后在查看所有,会看到有databases,进入databases,显示所有就会发现你的数据库名字,这里使用的是"BookStore"。
5.sqlite3 BookStore回车就进入了你的数据库了,然后“.schema”就会看到该应用程序的所有表及建表语句。
6.之后就可以使用标准的SQL语句查看刚才生成的数据库及对数据执行增删改查了。
注:ls,cd等命令都是linux的基本命令,不了解的同学可以看看有关这方面的资料。
下面介绍几个在SQLite中常用到的adb命令:
查看
.database 显示数据库信息;
.tables 显示表名称;
.schema 命令可以查看创建数据表时的SQL命令;
.schema table_name 查看创建表table_name时的SQL的命令;
进入sqlite数据库后,能够执行SQL语句,比于:select * from Book; 然后按Enter键,一定要在后面加上“;”