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 语言,而且仅仅利用非常少的内存就有非常好的性能.此外它还是开 ...
随机推荐
- android——使用自带录屏工具进行屏幕录像
在做开源项目的时候,想传一个gif效果图上去.但是,要有连贯的动画效果.所以,就想到先录制视频,然后视频转gif.但是,用第三录屏软件总是不完美. 那么,怎么办呢? android4.4 提供了自带录 ...
- Android中获取apk基本信息
一 PackageManager可以获得的所有包节点信息: 1,所有节点的基类:PackageItemInfo: 2,PackageInfo:package的全面信息,与AndroidManifest ...
- wince下写入数据到csv/txt文件中
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- struts2中的国际化
[java] view plaincopy 实现struts2中国际化其实非常简单 首先,struts2中的国际化是通过资源文件来配置的. 资源文件分为:action类级,package类级,还有we ...
- shell中的数学运算
shell中要进行数学运算通常有3中方法: expr命令 比如 expr 1 + 6就会返回7,使用expr的缺点就是碰到乘法运算,或者加括号(因为它们在shell中有其他意义),需要使用转义,比如: ...
- shell中的退出状态码
shell中的退出状态码最大只有255,如果超过这个值,就会进行取余运算,即如果执行如下命令: exit exitCode 如果exitCode大于255,那么实际的状态码为exitCode % 25 ...
- git删除分支
git branch -d branchname删除一个分支需要具备的条件: 1 如果待删除的分支没有upstream branch,那么待删除的分支需要合并到HEAD上,否则需要使用-D强制删除 2 ...
- vs2010中socket链接错误LINK2019
解决方法参考下面链接: http://blog.163.com/strive_only/blog/static/893801682009225112354746/
- yii2 去掉index.php的方法
1.开启apache-rewrite 在Windows下,我们一般使用的是Administrator账号,所以启用这两项非常简单: 在[Apache安装目录]/conf/httpd.conf中找到 # ...
- android 开发环境搭建 (转)
最近由于工作中要负责开发一款Android的App,之前都是做JavaWeb的开发,Android开发虽然有所了解,但是一直没有搭建开发环 境去学习,Android的更新速度比较快了,Android1 ...