Android 数据存储之SQLite数据库
来源:互联网 发布:淘宝换身份证开店 编辑:程序博客网 时间:2024/05/03 06:24
转载请标明出处: http://blog.csdn.net/airsaid/article/details/52419418
本文出自:周游的博客
- 前言
- SQLiteDatabase
- 创建数据库和表
- 操作数据库
- insert
- dalete
- update
- query
- 实例
- 事务
- SQLiteOpenHelper
- 方法
- 实例
前言
Android中有许多的数据存储方式,如果我们有少量的数据需要存储,那么使用:SharedPreferences、文件存储就可以了。但是如果有大量数据需要进行读写,那么就需要使用到数据库了。Android中内置了SQLite数据库,而SQLite数据库是一个真正轻量级的数据库,它并没有后台进程,整个数据库就对应于一个文件。Android也给我们提供了大量的API,使用起来很方便。
SQLiteDatabase
Android提供了SQLiteDatabase对象来管理数据库,SQLiteDatabase有提供方法来创建,删除,执行SQL命令,并执行常见的数据库管理任务。
SQLiteDatabase提供了如下静态方法来打开一个文件对应的数据库:
- SQLiteDatabase openDatabase(String path, SQLiteDatabase.CursorFactory factory, int flags):
打开path文件所代表的SQLite数据库。 - SQLiteDatabase openOrCreateDatabase(File file, SQLiteDatabase.CursorFactory factory):
打开或创建(如果不存在)file文件所代表的SQLite数据库。 - SQLiteDatabase openOrCreateDatabase(String path, SQLiteDatabase.CursorFactory factory):
打开或创建(如果不存在)path文件所代表的SQLite数据库。
当我们获取到SQLiteDatabase对象之后,就可以调用SQLiteDatabase如下的方法来对数据库进行操作了:
Android提供了上面的方法,来帮助开发者更“简便”的对数据库进行增删改查。但是其实这些方法完全可以通过SQL语句来完成。而用记上面复杂的参数的时间,就可以来掌握SQL语句了。
上面的方法,都是返回了一个Cursor接口,该接口提供对由数据库查询返回的结果集的随机读写访问,而Cursor同样提供了如下方法来移动查询结果的记录指针:
一旦通过以上方法移动到指定行后,就可以调用Cursor的getXXX()方法来获取指定列的数据了。
创建数据库和表
- 创建数据库:
// 判断数据库文件存放的文件夹是否存在,不存在则创建String mPath = Environment.getExternalStorageDirectory() + "/db/";File file = new File(mPath);if(!file.exists() && !file.isDirectory()){ // 创建目录 file.mkdirs();}// 使用静态方法打开数据库(不存在则创建),第二个参数用于返回Course工厂,null则表示使用默认工厂。SQLiteDatabase database = SQLiteDatabase.openOrCreateDatabase(mPath + "blog.db", null);
- 创建表:
// 执行创建表SQL语句,创建了一个名为blog_info的表String createSql = "create table blog_info(blog_id integer primary key, blog_name varchar(255), blog_link varchar(255))";database.execSQL(createSql);
注意:由于数据库创建在SD卡中,所以需要加上写入SD卡权限
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
操作数据库
在创建好数据库和表之后就可以对表中的数据进行管理和操作了。我们可以直接通过execSQL()方法执行SQL语句来操作,也可以使用Android给我们直接提供的增删改查方法。
insert
- insert(String table, String nullColumnHack, ContentValues values):
- table:想插入数据的表名。
- nullColumnHack:代表强行charunull值的数据列列名。当values参数为null或不想包含任何key-value对时该参数有效。
- values:代表一行记录的数据。
插入的数据参数为ContentValues,ContentValues有点类似与Map集合,它也有put(String key, XXX value)方法,其中key为数据列名,getXxx(String key)为取出对应列名的数据。
往刚刚上面创建的数据库blog_info表中插入一条数据:
ContentValues contentValues = new ContentValues();contentValues.put("blog_name", "Airsaid");contentValues.put("blog_link", "http://blog.csdn.net/airsaid");// line为新添加的行号,该行号是一个内部值,与主键id无关,当发生错误时,返回-1。long line = mDatabase.insert("blog_info", null, contentValues);
dalete
- delete(String table, String whereClause, String[] whereArgs):
- table:代表想删除数据的表名。
- whereClause:满足该whereClause子句的记录将会被删除。
- whereArgs:用于为whereClause子句传入参数。
删除和”Airsaid”相关的数据:
int num = mDatabase.delete("blog_info", "blog_name like ?", new String[]{"Airsaid"});Toast.makeText(this, "一共删除了:" + num + "条数据", Toast.LENGTH_SHORT).show();
update
- update(String table, ContentValues values, String whereClause, String[] whereArgs):
- table:代表需要更新的表名。
- values:代表想更新的数据。
- whereClause:满足该WhereClause子句的数据将会被更新。
- whereArgs: 用于为whereClause子句传入参数。
将所有主键大于5的blog_name改为周游:
ContentValues contentValues = new ContentValues();contentValues.put("blog_name", "周游");int num = mDatabase.update("blog_info", contentValues, "_id > ?", new String[]{"5"});
query
- query(boolean distinct, String table, String[] columns, String selection, String[] selectionArgs,String groupBy, String having, String orderBy, String limit):
- distinct:是否去除重复记录。
- table:需要执行查询的表名。
- columns:要查询出来的列名。
- selection:查询条件子句。
- selectionArgs:占位符传入参数。
- groupBy:用与控制分组。
- having:用于对分组进行排序。
- orderBy:用于对记录进行排序。
- limit:用于进行分页。
由于查询条件的不确定性,所以query()方法的参数真的是比较长。。感觉建议在写查询语句的时候,可以直接使用rawQuery()方法进行查询。
实例
下面写一个实例,用户分别输入博客名和博客链接,点插入后,将数据存储到数据库,并用列表展示出来:
* 布局:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:paddingBottom="@dimen/activity_vertical_margin" android:paddingLeft="@dimen/activity_horizontal_margin" android:paddingRight="@dimen/activity_horizontal_margin" android:paddingTop="@dimen/activity_vertical_margin" tools:context="com.airsaid.sqlitedemo.MainActivity"> <EditText android:id="@+id/edt_blog_name" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp"/> <EditText android:id="@+id/edt_blog_link" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp"/> <Button android:onClick="insert" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:text="插入数据"/> <ListView android:id="@+id/listView" android:layout_marginTop="10dp" android:layout_width="match_parent" android:layout_height="wrap_content"/></LinearLayout>
- 代码:
public class MainActivity extends AppCompatActivity { private String mPath = Environment.getExternalStorageDirectory() + "/db/"; private static final String DB_NAME = "blog.db"; private EditText mEdtName; private EditText mEdtLink; private ListView mListView; private SQLiteDatabase mDatabase; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mEdtName = (EditText) findViewById(R.id.edt_blog_name); mEdtLink = (EditText) findViewById(R.id.edt_blog_link); mListView = (ListView) findViewById(R.id.listView); // 判断数据库文件存放的文件夹是否存在,不存在则创建 File file = new File(mPath); if(!file.exists() && !file.isDirectory()){ // 创建目录 file.mkdirs(); } // 使用静态方法打开数据库(不存在则创建),第二个参数用于返回Course工厂,null则表示使用默认工厂。 mDatabase = SQLiteDatabase.openOrCreateDatabase(mPath + DB_NAME, null); // 执行创建表SQL语句,创建了一个名为blog_info的表 String createSql = "create table blog_info(_id integer primary key, blog_name varchar(255), blog_link varchar(255))"; mDatabase.execSQL(createSql); } /** * 插入数据 */ public void insert(View v){ // 获取用户输入信息 String name = mEdtName.getText().toString(); String link = mEdtLink.getText().toString(); // 执行SQL语句插入数据 mDatabase.execSQL("insert into blog_info values(null, ?, ?)", new String[]{name, link}); // 填充数据到ListView Cursor cursor = mDatabase.rawQuery("select * from blog_info", null); SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.item_listview_blog, cursor , new String[]{"blog_name", "blog_link"}, new int[]{R.id.txt_name, R.id.txt_link} , CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER); mListView.setAdapter(adapter); }}
- Item布局:
<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_gravity="center" android:orientation="horizontal"> <TextView android:id="@+id/txt_name" android:layout_width="0dp" android:layout_height="50dp" android:layout_weight="1"/> <TextView android:id="@+id/txt_link" android:layout_width="0dp" android:layout_height="50dp" android:layout_weight="1"/></LinearLayout>
运行结果:
事务
数据库操作,事务是少不了的,而SQLiteDatabase也提供了如下几个方法来操作事务:
* beginTransaction():开始事务。
* endTransaction():结束事务。
* inTransaction():判断当前上下文是否处于事务中。
当调用endTransaction()方法结束事务的时候,那么到底是提交事务还是进行回滚事务呢?这取决于SQLiteDatabase是否调用了:setTransactionSuccessful()方法来设置事务标志,如果在执行事务的时设置了,当事务成功则提交事务,否则程序将回滚事务。
SQLiteOpenHelper
其实在真实项目开发中,很少使用SQLiteDatabase的方法来打开数据库,而是通过继承Android给我们提供的SQLiteOpenHelper抽象类来创建。
SQLiteOpenHelper是一个辅助类,用于来帮助我们建立和管理数据库。我们只需要继承它,并实现两个抽象方法:
* onCreate(SQLiteDatabase db):在初次生成数据库的时候会被调用,用于生成表结构。
* onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion):在数据库版本发生更新时会被调用,oldVersion为旧数据库版本号,newVersion为新版本数据库版本号。
方法
SQLiteOpenHelper有如下方法:
实例
- 继承SQLiteOpenHelper,在onCreate方法中创建数据库表:
public class MyDatabaseHelper extends SQLiteOpenHelper { public MyDatabaseHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) { super(context, name, factory, version); } @Override public void onCreate(SQLiteDatabase db) { // 创建表结构 db.execSQL("create table dict(_id integer primary key autoincrement, word, detail)"); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { }}
- 布局很简单,分别为单词输入框和释义输入框,输入完成后点击按钮保存到数据库,保存数据后,用户可以输入要查询的生词进行查询,点击查询将结果作为dialog展示出来。添加生词的方法如下:
public void add(View v) { // 添加生词 String word = mEdtWord.getText().toString(); String detail = mEdtDetail.getText().toString(); if(TextUtils.isEmpty(word) || TextUtils.isEmpty(detail)){ Toast.makeText(this, "输入的数据不能为空", Toast.LENGTH_SHORT).show(); return; } SQLiteDatabase database = mDb.getReadableDatabase(); database.execSQL("insert into dict values(null, ? , ?)", new String[]{word, detail}); Toast.makeText(this, "添加成功", Toast.LENGTH_SHORT).show();}
主要是通过SQLiteOpenHelper的 getReadableDatabase()方法获取了SQLiteDatabase对象。这里需要注意的是:
getReadableDatabase()方法会先以读写方式打开数据库,如果数据库的磁盘空间已经满了,那么就会打开失败,然后再尝试以只读的方式打开数据库。
而通过getWritableDatabase()方法,如果磁盘空间已满,打开时就会出错。
- 查询:
public void seek(View v) { // 查看生词 String dict = mEdtInput.getText().toString(); SQLiteDatabase database = mDb.getReadableDatabase(); Cursor cursor = database.rawQuery("select * from dict where word like ? or detail like ?" , new String[]{"%" + dict + "%", "%" + dict + "%"}); List<String> dicts = new ArrayList<>(); while (cursor.moveToNext()){ String word = cursor.getString(1); String detail = cursor.getString(2); dicts.add("生词:" + word + " 解释:" + detail); } showData(dicts);}
- 将结果展示:
private void showData(List<String> dicts) { if(dicts.size() < 1) { Toast.makeText(this, "没有找到到该生词数据", Toast.LENGTH_SHORT).show(); return; } String[] strings = dicts.toArray(new String[dicts.size()]); for (String string : strings) { Log.e("test", string); } new AlertDialog.Builder(this) .setTitle("查询出来的单词结果") .setItems(dicts.toArray(new String[dicts.size()]), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }).create().show();}
运行结果:
参考文章:《疯狂Android讲义》
- Android数据存储之SQLite数据库存储
- Android数据存储之SQLite数据库存储
- Android数据存储之SQLite数据库存储
- Android数据存储之:SQLite数据库存储
- Android 数据存储之SQLite数据库存储
- Android数据存储之SQLite数据库存储
- Android 数据存储之 SQLite嵌入式数据库
- Android数据存储之Sqlite数据库
- Android 数据存储 之 SQLite数据库详解
- Android 数据存储 之 SQLite数据库详解
- Android 数据存储 之 SQLite数据库详解
- Android 数据存储 之 SQLite数据库详解
- Android 数据存储 之 SQLite数据库详解
- Android 数据存储 之 SQLite数据库详解
- Android 数据存储之SQLite数据库
- Android数据存储之SQLite数据库存储数据
- Android数据存储之使用SQLite数据库存储数据
- Android 存储数据之3 使用SQLite数据库存储
- caffe安装问题总结
- 定时器整理
- 初识JAVA
- 内网穿透
- spring3mvc与struts2比较
- Android 数据存储之SQLite数据库
- lesson 4 communication pattern
- Lua学习笔记(二)
- insert table 和create table as 区别及举例
- 迭代器
- kindeditor副文档编辑器
- SQL的主键和外键的作用
- POJ 3318 Matrix Multiplication 随机化算法
- 关于JDBC操作MySQL实例