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 语言,而且仅仅利用非常少的内存就有非常好的性能.此外它还是开 ...
随机推荐
- Socket介绍
一 socket协议 Socket协议的形象描述 socket的英文原义是“孔”或“插座”.在这里作为4BDS UNIX的进程通信机制,取后一种意思.socket非常类似于电话插座.以一个国家级电话网 ...
- 两个iframe联动刷新 JS代码
1.iframe代码: <iframe id="famUpload" src="report.asp?syear=<%=Year(now())%>&qu ...
- C#设置程序自启动
public static void SetAutoRun(string fileName, bool isAutoRun) { RegistryKey reg = ...
- hdu1215七夕节
Problem Description 七夕节那天,月老来到数字王国,他在城门上贴了一张告示,并且和数字王国的人们说:"你们想知道你们的另一半是谁吗?那就按照告示上的方法去找吧!" ...
- [hdu5136]Yue Fei's Battle 2014 亚洲区域赛广州赛区J题(dp)
转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud 现场赛的时候由于有个地方有点小问题,没有成功AC,导致与金牌失之交臂. 由于今天下 ...
- GDI 开发的准备工作
1 需要的链接库和头文件 大部分函数在 Gdi.dll 和 Gdi32.dll 提供.相关的函数接口和结构都在 Wingdi.h 文件中(如果工程中已包含 Windows.h 就不需要再包含了,因为 ...
- 数值的N次方
问题描述: 实现函数double Power(double base,int exponent),求base的exponent次方.不得使用库函数, 同时不需考虑大数问题. 思路分析: 要是你秒秒钟想 ...
- ASPCMS 多条件查询
1. 表单样例: <form name="topFrm" id="topFrm" action="/search.asp"> & ...
- phpexcel导入excel文件报the filename xxx is not recognised as an OLE file错误。
工作中频繁会用phpexcel类导入excel文件的数据到数据库,目前常用的excel文件格式有:xls.csv.xlsx. 刚开始,针对xls文件,使用如下程序,能正常运行: $objReader ...
- php-app开发接口加密
自己平时工作中用到的一套接口加密规则,记录下来以后用: /** 2 inc 3 解析接口 客户端接口传输规则: 1.用cmd参数(base64)来动态调用不同的接口,接口地址统一为 http://a. ...