andrid中的Sqlite 数据库连接(本地版)
sqlite简介
SQLite,是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它包含在一个相对小的C库中。它是D.RichardHipp建立的公有领域项目。它的设计目标是嵌入式的,而且目前已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了。它能够支持Windows/Linux/Unix等等主流的操作系统,同时能够跟很多程序语言相结合,比如 Tcl、C#、PHP、Java等,还有ODBC接口,同样比起Mysql、PostgreSQL这两款开源的世界著名数据库管理系统来讲,它的处理速度比他们都快。SQLite第一个Alpha版本诞生于2000年5月。 至2015年已经有15个年头,SQLite也迎来了一个版本 SQLite 3已经发布。
效果图:
以下为工程结构:
以下Layout:
'''
<EditText
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/txtInput"
/>
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/btnAdd"
android:text="add"
/>
<Button
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/btnViewAll"
android:text="select"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:id="@+id/viewALl"
/>
</LinearLayout>
'''
以下为DBHelper:
''' java
package com.loweir.sqlitedemo;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
/**
数据库操作工具类
@author daguangspecial@gmail.com
*/
public class DBHelper {
private static final String TAG = "DBDemo_DBHelper";
// 调试标签
private static final String DATABASE_NAME = "dbdemo.db";
// 数据库名
SQLiteDatabase db;
Context context;// 应用环境上下文 Activity 是其子类DBHelper(Context _context) {
context = _context;
// 开启数据库
db = context.openOrCreateDatabase(DATABASE_NAME, Context.MODE_APPEND,
null);
CreateTable();
Log.v(TAG, "db path=" + db.getPath());
}/**
- 建表 * 列名 区分大小写? * 都有什么数据类型? * SQLite 3 * TEXT 文本 NUMERIC 数值 INTEGER 整型
- REAL 小数 NONE 无类型 * 查询可否发送select ?
*/
public void CreateTable() {
try {
db.execSQL("CREATE TABLE t_user ("
+ "_ID INTEGER PRIMARY KEY autoincrement," + "NAME TEXT"
+ ");");
Log.v(TAG, "Create Table t_user ok");
} catch (Exception e) {
Log.v(TAG, "Create Table t_user err,table exists.");
}
}
/** * 增加数据 * @param id * @param uname * @return */
public boolean save(String uname) {
String sql = "";
try {
sql = "insert into t_user values(null,'" + uname + "')";
db.execSQL(sql);
Log.v(TAG, "insert Table t_user ok");
return true;
} catch (Exception e) {
Log.v(TAG, "insert Table t_user err ,sql: " + sql);
return false;
}
}/** * 查询所有记录 * * @return Cursor 指向结果记录的指针,类似于JDBC 的 ResultSet */
public Cursor loadAll() {
if (db == null) {
Log.e(TAG, " loadall db is null");
return null;
}
Cursor cur = null;
try {
cur = db.query("t_user", new String[] { "_ID", "NAME" }, null,
null, null, null, null);
} catch (Exception e) {
e.printStackTrace();
Log.e(TAG, "61");
}
if (cur == null) {
Log.e(TAG, " loadall cur is null");
return null;
}
System.out.println("loadall is ok");
return cur;
}public void close() {
db.close();
}
}
'''
以下为 MainActivity.java
''' java
package com.loweir.sqlitedemo;
import android.app.Activity;
import android.database.Cursor;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
/**
*
*/
public class MainActivity extends Activity {
EditText inputTxt;
Button btnAdd;
Button btnViewAll;
TextView viewAll;
DBHelper db;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
this.setContentView(R.layout.activity_main);
// 初始化UI
btnAdd = (Button) findViewById(R.id.btnAdd);
btnViewAll = (Button) findViewById(R.id.btnViewAll);
viewAll = (TextView) findViewById(R.id.viewALl);
inputTxt = (EditText) findViewById(R.id.txtInput);
// 初始化DB
db = new DBHelper(this);
// 初始化监听
OnClickListener listener = new OnClickListener() {
public void onClick(View v) {
if (v.getId() == R.id.btnAdd) {
// 增加
db.save(inputTxt.getText().toString());
viewAll.setText("input success");
//这里的db.close() 必须注释掉以下有解释
//db.close();
} else if (v.getId() == R.id.btnViewAll) {
// 浏览所有数据
if( db == null)
{
viewAll.setText("db is null");
return ;
}
Cursor cur = null;
try {
cur = db.loadAll();
} catch(Exception e) {
Log.i("Main", "58");
return ;
}
Log.i("Main", "61");
StringBuffer sf = new StringBuffer();
cur.moveToFirst();
Log.i("Main", "64");
while (!cur.isAfterLast()) {
Log.i("Main", "60");
sf.append(cur.getInt(0)).append(" : ")
.append(cur.getString(1)).append("\n");
cur.moveToNext();
}
db.close();
viewAll.setText(sf.toString());
}
}
};
btnAdd.setOnClickListener(listener);
btnViewAll.setOnClickListener(listener);
}
}
'''
*因为在MainActivity中有句db.close() 没有注释掉 导致在查询数据库的时候出现错误。为此我在代码中加了很多Log语句用来查看程序运行状况 比如说上面的Log.i("Main","58");其中58为行数。
每次运行的时候都是只能插入而无法查询。
首先我想到的是Cursor 是否为空,经过断点调试确实为空
这样,我想到是不是数据库是空。查了一下adb的命令
adb shell 可以进入shell
然后 通过ls cd rm 命令
找到 并删除创建的数据库 重新测试一下
结果仍然报错
于是在ddms视图 用File explorer 将数据库导出 并用sqlite expert 查看 结果有值
这时我看到一个异常 因为一开始 我只try了异常 并没有e.print
这时看到 e 的值为
java.lang.IllegalStateException: attempt to re-open an already-closed object
百度结果为:
http://blog.csdn.net/zhufuing/article/details/14455823
这个错误出现的原因是因为我在一个数据库查询方法中调用了另一个数据库查询方法,我的数据库查询方法都是在开始的时候获取SQLiteDatabase对 象,在结束的时候关闭SQLiteDabse对象,结果内部的数据库查询方法在结束的时候直接关闭了SQLiteDatabase对象,导致外面的数据库 查询操作报错,在这里大家不要以为多获取了几个SQLiteDatabase对象就可以了,每个线程只能使用一个SQLiteOpenHelper,也就 使得每个线程使用一个SQLiteDatabase对象(多线程操作数据库会报错);
解决办法就是我不再关闭内部数据库查询方法的SQLiteDatbase对象或者将那个方法直接集成到外面的查询方法中,当然,要确保这个查询方法只会出 现其他数据库查询方法中,要是单独用这个方法,反而会因为SQLiteDatabase对象没有关闭而报错;
然后 我就将上面的那个db.close() 注释掉
结果ok
andrid中的Sqlite 数据库连接(本地版)的更多相关文章
- UWP开发-在UWP中使用sqlite
原文:UWP开发-在UWP中使用sqlite sqlite是一种轻量级的数据库,对于一些资源紧张又需要数据库的开发非常好用. SQLite 是一个开源的无服务器嵌入式数据库. 这些年来,它已作为面向存 ...
- Visual Studio 2010(.NET 4.0)中使用SQLite.NET
Visual Studio 2010(.NET 4.0)中使用SQLite.NET 2011年4月1日 | 分类: DataBase, DOTNET | 标签: .net 4.0, SQLite. ...
- 在项目中使用SQLite数据库小结
------------------------------------------------------------------------推荐: - VS2012 使用 1.0.84 版的库 - ...
- Android 开发中使用 SQLite 数据库
SQLite 介绍 SQLite 一个非常流行的嵌入式数据库,它支持 SQL 语言,并且只利用很少的内存就有很好的性能. 此外它还是开源的,任何人都可以使用它.许多开源项目((Mozilla, PHP ...
- 使用SQLite做本地数据缓存的思考
前言 在一个分布式缓存遍地都是的环境下,还讲本地缓存,感觉有点out了啊!可能大家看到标题,就没有想继续看下去的欲望了吧.但是,本地缓存的重要性也是有的! 本地缓存相比分布式缓存确实是比较out和比较 ...
- Xamarin android使用Sqlite做本地存储数据库
android使用Sqlite做本地存储非常常见(打个比方就像是浏览器要做本地存储使用LocalStorage,貌似不是很恰当,大概就是这个意思). SQLite 是一个软件库,实现了自给自足的.无服 ...
- 在Windows Phone 8.1中使用Sqlite数据库
前言 我的工作目前不涉及到Windows phone的开发,但是业余时间也开发过几款app.以前由于各种条件的限制,只接触到WP8.0设备的app开发. 最近几个月开始将WP8的应用迁移到WP8.1, ...
- 在Android 开发中使用 SQLite 数据库笔记
SQLite 介绍 SQLite 一个非常流行的嵌入式数据库,它支持 SQL 语言,并且只利用很少的内存就有很好的性能.此外它还是开源的,任何人都可以使用它.许多开源项目((Mozilla, PH ...
- 在 Android 应用程序中使用 SQLite 数据库以及怎么用
part one : android SQLite 简单介绍 SQLite 介绍 SQLite 一个非常流行的嵌入式数据库.它支持 SQL 语言,而且仅仅利用非常少的内存就有非常好的性能.此外它还是开 ...
随机推荐
- SOLR使用手册之操作collection
一.Collections API 参考:https://cwiki.apache.org/confluence/display/solr/Collections+API 因为API比较多,我就不一 ...
- 【转载】ADO.NET与ROM的比较(1):ADO.NET实现CRUD
[转载]ADO.NET与ROM的比较(1):ADO.NET实现CRUD 转自周公 说明:个人感觉在Java领域大型开发都离不了ORM的身影,所谓的SSH就是Spring+Struts+Hiberna ...
- PHP学习笔记二十八【抽象类】
<?php //定义一个抽象类.主要用来被继承 //如果一个类继承了抽象类,则它必须实现该抽象类的所有抽象方法(除非它自己也是抽象类) // abstract class Animal{ pub ...
- lucene评分推导公式
在进行Lucene的搜索过程解析之前,有必要单独的一张把Lucene score公式的推导,各部分的意义阐述一下.因为Lucene的搜索过程,很重要的一个步骤就是逐步的计算各部分的分数. Lucene ...
- /调整button的title的位置
[bottomButton setTitleEdgeInsets:UIEdgeInsetsMake(10, -190, 10, 44)]; //上左下右 ||button.co ...
- Webfrom 上传 单个上传 多个上传
文件上传控件:FileUpload - 控件,界面+方法+属性Button/LinkButton/ImageButton FileUpload控件:1.SaveAs("要上传到服务器的绝对路 ...
- Java IO5:管道流、对象流
前言 前面的文章主要讲了文件字符输入流FileWriter.文件字符输出流FileReader.文件字节输出流FileOutputStream.文件字节输入流FileInputStream,这些都是常 ...
- 利用glibc中锁结构的信息解决死锁问题
首先非常感谢老丁和老李同学的帮助,没有他们这个问题估计又得搞很久.遇见这个问题,真是头疼.不熟悉代码.不熟悉流程,但是领导还是把活给排下来了(实在不解),只能硬着头皮找了. 问题是这样的,cac ...
- JQuery easyui (1) Draggable(拖动)组件
很不习惯这种强迫式的学习,但谁叫我不是老师了,所以还是决定坚持练习,顺带为博客加点东西.虽然我还是很反感短时间内惯性的去熟悉一个工具. easyui做为一个封装了JQusey的UI插件,其实还是蛮好用 ...
- 让PHP程序永远在后台运行
PHP里有个函数很有用.这是在最近的开发中才逐渐用到的. int ignore_user_abort ( [bool setting] ) 这个函数的作用是指示服务器端在远程客户端关闭连接后是否继续执 ...