SQLite 是一款内置到移动设备上的轻量型的数据库,SQLite 数据库是无类型的,可以向一个integer 的列中添加一个字符串。
嵌入式的数据库,体积小 功能强大。
有大量相似数据的时候使用数据库存储。
在Android平台上,集成了一个嵌入式关系型数据库—SQLite,SQLite3支持 NULL、INTEGER、REAL(浮点数字)、TEXT(字符串文本)和BLOB(二进制对象)数据类型,虽然它支持的类型只有五种,但实际上sqlite3也接受varchar(n)、char(n)、decimal(p,s) 等数据类型,只不过在运算或保存时会转成对应的五种数据类型。 SQLite最大的特点是你可以把各种类型的数据保存到任何字段中,但是主键只能是Integer类型的。
Sqlite数据库一般要求主键是_id,当然也可以是id.
一般数据采用的固定的静态数据类型,而SQLite采用的是动态数据类型,会根据存入值自动判断。
SQLite具有以下常用的数据类型:
NULL: 这个值为空值;
VARCHAR(n):长度不固定且其最大长度为 n 的字串,n不能超过 4000;
CHAR(n):长度固定为n的字串,n不能超过 254;
INTEGER: 值被标识为整数,依据值的大小可以依次被存储为1,2,3,4,5,6,7,8;
REAL: 所有值都是浮动的数值,被存储为8字节的IEEE浮动标记序号;
TEXT: 值为文本字符串,使用数据库编码存储(TUTF-8, UTF-16BE or UTF-16-LE);
BLOB: 值是BLOB数据块,以输入的数据格式进行存储。如何输入就如何存储,不改变格式;
DATA :包含了 年份、月份、日期;
TIME: 包含了 小时、分钟、秒;
1. 创建数据管理类:
SQLiteOpenHelper 是Android 提供的一个抽象工具类,负责管理数据库的创建、升级工作。如果我们想创建数据库,就需要自定义一个类继承SQLiteOpenHelper,然后覆写其中的抽象方法。
SqliteOpenHelper的方法介绍:
1、getReadableDatabase() 创建或者打开一个可读写的数据库,如果出现问题(磁盘满等),则打开一个只读的数据库。
2、getWritableDatabase() 获得一个可读写的数据库。如果磁盘满则会抛异常。
3、onCreate(SQLiteDatabase db) 只有第一次创建这个数据库的时候调用。一般在这个方法中创建数据的相应表。
4、onOpen(SQLiteDatabase db) 当每次打开数据库的时候都会调用。这个方法很少使用
5、onUpgrade(SQLiteDatabase db,int oldVersion,int newVersion) 当升级数据库即数据库的版本号发生改变的时候调用,一般如果需要修改表结构就写在这里.
//db.execSQL(“alert 表名 add 列名列数据类型”);
6、close() 关闭打开的所有数据库对象
2. 实例化数据库管理类,创建数据库
SQLiteOpenHelper 有两个方法均可返回SQLiteDatabase 对象:
一、getWritableDatabase():
该方法返回的对象和另外一个方法返回的对象没有任何差异,返回的对象对数据库都可以进行读、写操作,当磁盘已满或者权限不足的情况下该方法会抛出异常。
二、getReadableDatabase():
跟另外一个方法相比,在磁盘已满的情况下,该方法不会抛出异常,而是返回一个只读的数据库操作对象。
根据这两种方法返回对象的差异,如果需要对数据库进行查询操作则推荐使用后者,如果添加、修改、删除数据则推荐使用前者。
SQLiteOpenHelper
/**
* Created by : xiaoyehai
* Create date : 2019/9/11 20:33
* description :数据库管理类,负责管理数据库的创建、升级工作
*/
public class MyDbHelper extends SQLiteOpenHelper {
//数据库名字
public static final String DB_NAME = "my.db";
//数据库版本
public static final int DB_VERSION = 1;
public MyDbHelper(Context context) {
super(context, DB_NAME, null, DB_VERSION);
}
/**
* 在数据库首次创建的时候调用,创建表以及可以进行一些表数据的初始化
*
* @param db
*/
@Override
public void onCreate(SQLiteDatabase db) {
//创建表
//_id为主键并且自增长一般命名为_id
String sql = "create table person(_id integer primary key autoincrement,name text)";
db.execSQL(sql);
//可以给表初始化一些数据
//db.execSQL("insert into person(name) values('小米')");
}
/**
* 数据库升级的时候回调该方法,在数据库版本号DB_VERSION升级的时候才会调用
*
* @param db
* @param oldVersion
* @param newVersion
*/
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
//给表添加一个字段
//db.execSQL("alter table person add age integer");
}
/**
* 数据库打开的时候回调该方法
*
* @param db
*/
@Override
public void onOpen(SQLiteDatabase db) {
super.onOpen(db);
Log.e("xyh", "onOpen: ");
}
}
数据库操作类,封装数据库的增删改查方法
/**
* Created by : xiaoyehai
* Create date : 2019/9/11 20:39
* description : 数据库操作类
*/
public class DataBaseDao {
private final MyDbHelper mDbHelper;
public DataBaseDao(Context context) {
//实例化数据库管理类
mDbHelper = new MyDbHelper(context);
}
/**
* 插入
*
* @param list
*/
public void insert(List<PersonBean> list) {
SQLiteDatabase db = mDbHelper.getWritableDatabase();
if (db.isOpen()) {
for (int i = 0; i < list.size(); i++) {
db.execSQL("insert into person(name) values(" + "'" + list.get(i).getName() + "'" + ")");
}
db.close();
}
}
/**
* 更新
*
* @param id
* @param personBean
*/
public void update(int id, PersonBean personBean) {
SQLiteDatabase db = mDbHelper.getWritableDatabase();
if (db.isOpen()) {
db.execSQL("update person set name=? where _id=?", new Object[]{personBean.getName(), id});
db.close();
}
}
/**
* 根据id删除
*/
public void delete(int id) {
SQLiteDatabase db = mDbHelper.getWritableDatabase();
if (db.isOpen()) {
db.execSQL("delete from person where _id=?", new Object[]{id});
db.close();
}
}
/**
* 删除所有
*/
public void deleteAll() {
SQLiteDatabase db = mDbHelper.getWritableDatabase();
if (db.isOpen()) {
db.execSQL("delete from person");
//设置id从1开始(sqlite默认id从1开始),若没有这一句,id将会延续删除之前的id
db.execSQL("update sqlite_sequence set seq=0 where name='person'");
db.close();
}
}
/**
* 查询所有
*/
public List<PersonBean> queryAll() {
List<PersonBean> list = new ArrayList<>();
SQLiteDatabase db = mDbHelper.getReadableDatabase();
if (db.isOpen()) {
Cursor cursor = db.rawQuery("select * from person", null);
while (cursor.moveToNext()) {
//int id = cursor.getInt(0);
int _id = cursor.getInt(cursor.getColumnIndex("_id"));
String name = cursor.getString(cursor.getColumnIndex("name"));
PersonBean personBean = new PersonBean(_id, name);
list.add(personBean);
}
cursor.close();
db.close();
}
return list;
}
/**
* 根据id查询
*/
public List<PersonBean> query(int id) {
List<PersonBean> list = new ArrayList<>();
SQLiteDatabase db = mDbHelper.getReadableDatabase();
if (db.isOpen()) {
Cursor cursor = db.rawQuery("select * from person where _id=?", new String[]{id + ""});
while (cursor.moveToNext()) {
//int id = cursor.getInt(0);
int _id = cursor.getInt(cursor.getColumnIndex("_id"));
String name = cursor.getString(cursor.getColumnIndex("name"));
PersonBean dataBean = new PersonBean(_id, name);
list.add(dataBean);
}
cursor.close();
db.close();
}
return list;
}
}
Activity代码
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private Button btn_add;
private Button btn_delete;
private Button btn_update;
private Button btn_query;
private ListView mListView;
private DataBaseDao mDataBaseDao;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
mDataBaseDao = new DataBaseDao(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_add: //添加
addData();
break;
case R.id.btn_delete: //删除
deleteData();
break;
case R.id.btn_update: //更新
updateData();
break;
case R.id.btn_query: //查询
queryData();
break;
}
}
private void queryData() {
List<PersonBean> list = mDataBaseDao.queryAll(); //查询全部
//List list = mDataBaseDao.query(32); //根据id查询
MyAdapter myAdapter = new MyAdapter(this, list, R.layout.item_list);
mListView.setAdapter(myAdapter);
}
private void updateData() {
PersonBean personBean = new PersonBean("赵丽颖更新", 100);
mDataBaseDao.update(6, personBean);
}
private void deleteData() {
//mDataBaseDao.delete(5); //根据id删除
mDataBaseDao.deleteAll(); //删除所有
}
private void addData() {
List<PersonBean> list = new ArrayList<>();
for (int i = 1; i <= 10; i++) {
PersonBean personBean = new PersonBean("赵丽颖" + i, 10 + i);
list.add(personBean);
}
mDataBaseDao.insert(list);
}
private void initView() {
btn_add = (Button) findViewById(R.id.btn_add);
btn_delete = (Button) findViewById(R.id.btn_delete);
btn_update = (Button) findViewById(R.id.btn_update);
btn_query = (Button) findViewById(R.id.btn_query);
mListView = (ListView) findViewById(R.id.listview);
btn_add.setOnClickListener(this);
btn_delete.setOnClickListener(this);
btn_update.setOnClickListener(this);
btn_query.setOnClickListener(this);
}
}
实体类
/**
* Created by : xiaoyehai
* Create date : 2019/9/11 20:40
* description :实体类
*/
public class PersonBean {
private int id; //主键,自增长,不需要设置
private String name;
private int age;
public PersonBean() {
}
public PersonBean(String name, int age) {
this.name = name;
this.age = age;
}
public PersonBean(int id, String name) {
this.id = id;
this.name = name;
}
public PersonBean(int id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
注意点:
/**
* 删除所有
*/
public void deleteAll() {
SQLiteDatabase db = mDbHelper.getWritableDatabase();
if (db.isOpen()) {
db.execSQL("delete from person");
//设置id从1开始(sqlite默认id从1开始),若没有这一句,id将会延续删除之前的id
db.execSQL("update sqlite_sequence set seq=0 where name='person'");
db.close();
}
}
BLOB (binary large object),二进制大对象,是一个可以存储二进制文件的容器。
在计算机中,BLOB常常是数据库中用来存储二进制文件的字段类型。
BLOB是一个大文件,典型的BLOB是一张图片或一个声音文件,由于它们的尺寸,必须使用特殊的方式来处理(例如:上传、下载或者存放到一个数据库)。
Android数据库中存取图片通常使用两种方式,一种是保存图片所在路径,二是将图片以二进制的形式存储(sqlite3支持BLOB数据类型)。对于两种方法的使用,好像第二种方法不如第一种方法更受程序员欢迎,他们认为,在很多数据库语言里,处理大字段都是不容易的,像图片这样的文件放在数据库里会有问题:对数据库的读写速度永远赶不上文件系统的处理速度,使数据库变得巨大;但也有很多人认为像图片这样的数据存放在数据库中也有好处:易于备份,且备份速度绝对比备份文件快,比较容易数据迁移等等。其实这两种方法都有优缺点,具体使用哪种方法要视情况而定。个人倾向于使用数据库存取图片,因为个人认为存到数据库里的数据不会因外部数据的变化而丢失改变,比如你拍照获得一张图片,如果是将路径存到数据库,当这张照片被删除之后,下次读取数据库就得不到想要的结果了。