写这篇文章主要是网上的对sqlite的操作太多且太杂,非常多时候都不能非常好的运用到自己的项目中,结构不清晰,我自己写了一篇适合刚刚接触的人看的操作方法。



近来用android时要将一些数据保存起来,一開始用的是preferences,后来要保存的东西多了。发现用preferences明显不能满足要求了,并且发现用这个的话代码就变得有点乱了。所以才開始学习使用sqlite数据库,一開始以为不就是个数据库么,和平时的mysql啊或者是sqlserver都一样。都非常easy的,但后来真正在用的时候才发现困难一个接着一个。但还是在不断的摸索中一步一步的不断解决困难。后来发现学习安卓的话当自己实在找不到思路时看看网上的一些教学视频也是个不错的选择。这里推荐一个视频不错,我就是照这个视频学的。

http://www.tudou.com/programs/view/2qH5Am_3MsM/

写一下android操作数据库中的一些准备。

首先,配一下adb的环境变量,由于每次都要到adb的文件夹下去启动实在太麻烦了,以下是详细步骤。当然也能够该其它文件,我习惯改这个。能够改完后能够source一下使它生效。

1、sudo  gedit  /etc/profile

2、将以下的两句加到上面打开的文件中 

export ANDROID_HOME=/home/sdk文件路径

export PATH=$PATH:$ANDROID_HOME/platform-tools

3、重新启动电脑,大功告成!!

adb配好以后,我们最好还要给手机里的数据库訪问的权限。一般在/data/data/包名/database 里面,用adb shell进入后su获得手机root权限,然后给权限chmod。

要读数据库文件的话就用命令 sqlite3 数据库文件  ,当中的数据库能够直接在adb shell中执行sqlite3,但我依照网上弄的就是不能在adb shell中打开sqlite3数据库。说命令没有找到,我该传的文件都传了。没办法。仅仅有在eclipse里的ddms的file explore里把数据库文件到处然后在linux终端里执行sqlite3数据库来看了。

还有要注意的是写sql语句时一定要注意"select * from " +TABLE_NAME 中的from和引號要留有空格。不然的话就连在一起了。


以下的有一个知识要讲一下,sqlite的添加,删除等操作都挺简单的,麻烦的就是查询操作,一般都借用Cursor来保存查询数据,一開始我没怎么注意这是一个指针类型,指向数据库里的数据。而我一開始写的时候把数据库的关闭操作写在了Cursor操作的前面。也就是说先把数据库关闭了再对Cursor对象进行操作。这种话就造成了Cursor的空指针,也就注定杯具了好久。。。

以下就贴一些关于sqlite数据库操作的事例,这样对一些还在困惑中的人有一些帮助。同一时候有助于以后自己回想。

SQLiteHelper.java(数据库辅助类)

public class SQLiteHelper extends SQLiteOpenHelper{

	private static final String DATABASE_NAME="fpp.db";
private static final int DATABASE_VERSION=17;//更改版本号后数据库将又一次创建
private static final String TABLE_NAME="test"; /**
* 在SQLiteOpenHelper的子类其中。必须有这个构造函数
* @param context 当前的Activity
* @param name 表的名字(而不是数据库的名字,这个类是用来操作数据库的)
* @param factory 用来在查询数据库的时候返回Cursor的子类,传空值
* @param version 当前的数据库的版本号,整数且为递增的数
*/
public SQLitedata(Context context)
{
super(context, DATABASE_NAME, null, DATABASE_VERSION);//继承父类
// TODO Auto-generated constructor stub
}
/**
* 该函数是在第一次创建数据库时运行。仅仅有当其调用getreadabledatebase()
* 或者getwrittleabledatebase()并且是第一创建数据库是才会运行该函数
*/ public void onCreate(SQLiteDatabase db)
{ // TODO Auto-generated method stub
String sql = "CREATE TABLE " + TABLE_NAME + "("
+ "id INTEGER,"
+ "nid VARCHAR(11),"
+ "sid CHAR(1),"
+ "type INTEGER,"
+ "stime DATETIME,"
+ "locate_main VARCHAR(45),"
+ "locate_detail VARCHAR(45),"
+ "state INTEGER"
+ ")";
db.execSQL(sql);
Log.e("create","数据库创建成功");
}
/**
*数据库更新函数。当数据库更新时会运行此函数
*/ public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
String sql = "DROP TABLE IF EXISTS " + TABLE_NAME;
db.execSQL(sql);
this.onCreate(db);
// TODO Auto-generated method stub
System.out.println("数据库已经更新");
/**
* 在此加入更新数据库是要运行的操作
*/
} }

MyOperator.java (数据库操作类)

public class MyOperator {

	private static final String TABLE_NAME = "test";//要操作的数据表的名称
private SQLiteDatabase db=null; //数据库操作 //构造函数
public MyOperator(SQLiteDatabase db)
{
this.db=db;
} // //插入操作
// public void insert(int id,String nid,String sid,int type,
// String stime,String etime,String desc,String locate_main,String locate_detail,int state)
// {
// String sql = "INSERT INTO " + TABLE_NAME + " (id,nid,sid,type,stime,etime,desc,locate_main,locate_detail,state)"
// + " VALUES(?,?,?,? ,? ,? ,? ,?,?,? )";
// Object args[]=new Object[]{id,nid,sid,type,stime,etime,desc,locate_main,locate_detail,state};
// this.db.execSQL(sql, args);
// this.db.close();
// }
//插入重载操作
public void insert(int id,int state)
{
String sql = "INSERT INTO " + TABLE_NAME + " (id,state)" +" VALUES(?,? )";
Object args[]=new Object[]{id,state};
this.db.execSQL(sql, args);
this.db.close();
} //更新操作
public void update(int id,int state)
{
String sql = "UPDATE " + TABLE_NAME + " SET state=? WHERE id=?";
Object args[]=new Object[]{state,id};
this.db.execSQL(sql, args);
this.db.close();
} //删除操作,删除
public void delete(int id)
{
String sql = "DELETE FROM " + TABLE_NAME +" WHERE id=?";
Object args[]=new Object[]{id};
this.db.execSQL(sql, args);
this.db.close();
} //查询操作,查询表中全部的记录返回列表
public List<String> find()
{
List<String> all = new ArrayList<String>(); //此时仅仅是String
String sql = "SELECT * FROM " + TABLE_NAME;
Cursor result = this.db.rawQuery(sql, null); //运行查询语句
for(result.moveToFirst();!result.isAfterLast();result.moveToNext() ) //採用循环的方式查询数据
{
all.add(result.getInt(0)+","+result.getString(1)+","+result.getString(2)+","+result.getInt(3)+","
+result.getString(4)+","+result.getString(5)+","+result.getString(6)+","+result.getString(7)+","
+result.getString(8));
}
this.db.close();
return all;
} //查询操作虫重载函数,返回指定ID的列表
public int getstatebyID(int id)
{
int num=-1;//错误状态-1
List<String> all = new ArrayList<String>(); //此时仅仅是String
String sql = "SELECT state FROM " + TABLE_NAME + " where id=?" ;
String args[] = new String[]{String.valueOf(id)};
Cursor result = this.db.rawQuery(sql, args);
for(result.moveToFirst();!result.isAfterLast();result.moveToNext() )
{
num=result.getInt(0);
} Log.e("database", "图片状态state"+ String.valueOf(num));
this.db.close();
return num;
} //推断插入数据的ID是否已经存在数据库中。 public boolean check_same(int id)
{
String sql="SELECT id from " + TABLE_NAME + " where id = ?";
String args[] =new String[]{String.valueOf(id)};
Cursor result=this.db.rawQuery(sql,args);
Log.e("database", "the sql has been excuate"); Log.e("database","the hang count" + String.valueOf(result.getCount())); if(result.getCount()==0)//推断得到的返回数据是否为空
{
Log.e("database", "return false and not exist the same result" + String.valueOf(result.getCount()));
this.db.close();
return false;
}
else
{
Log.e("database", "return true and exist the same result"+ String.valueOf(result.getCount()));
this.db.close();
return true;
}
}
}

随便的一个项目中的activity(activity 类。操作打开数据库已经在里面)

public class MainActivity extends Activity {
private static LinkedList<Map<String, Object>> mListItems;
private PullToRefreshListView pullToRefreshListView;
private ProblemController problemController = ProblemController.getInstance(); private SQLiteOpenHelper helper =null;
private MyOperator mytab=null; /** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.helper=new SQLitedata(this);//数据库操作辅助类
setPullToRefreshView();
} @Override
public boolean onCreateOptionsMenu(Menu _menu){
super.onCreateOptionsMenu(_menu);
_menu.add(0, 0, 0, "设置");
return true;
} @Override
public boolean onOptionsItemSelected(MenuItem _item){
switch (_item.getItemId()) {
case 0:{
Intent intent = new Intent(getApplicationContext(), SettingsActivity.class);
startActivity(intent);
break;
}
}
return true;
} private class GetDataTask extends AsyncTask<Void, Void, String[]> { @Override
protected String[] doInBackground(Void... params) {
if(listToShowData(problemController.getNewProblems())){ }else {
Message message = new Message();
handler.sendMessage(message);
}
return mStrings;
} @Override
protected void onPostExecute(String[] result) {
pullToRefreshListView.onRefreshComplete();
super.onPostExecute(result);
}
} private String[] mStrings = {}; /**
* @param _newslist 须要显示的消息列表
*/
private boolean listToShowData(LinkedList<Problem> _problems) {
if(_problems != null){
mListItems.clear();
for (Problem news : _problems) {
//将数据插入数据库进行初始化
//这里须要一个推断反复的操作。假设数据的id已经在数据库中就不须要进行插入数据 mytab = new MyOperator(helper.getWritableDatabase());
Log.e("database", "start check if id exists and insert the id,the id is "+String.valueOf(news.getID()));
if(!mytab.check_same(news.getID()))
{
Log.e("database", "the id is not exist,insert the new id now.....");
mytab = new MyOperator(helper.getWritableDatabase());
mytab.insert(news.getID(), 1);
Log.e("database", "insert finished");
} Map<String, Object> tmpMap = new HashMap<String, Object>(); //用来储存日志名称的Map
tmpMap.put("id", news.getID());
tmpMap.put("describe", "模块:" + news.getSid() + "出现故障!");
tmpMap.put("time", news.getsTime());
tmpMap.put("img", R.drawable.icon_important); Log.e("database", "start read database"); //读取数据库推断这个事件的状态显示相应的图标,1表示默认状态问号,2表示已察看。3表示事件已经完毕勾
mytab = new MyOperator(helper.getWritableDatabase());
int state = mytab.getstatebyID(news.getID());
switch(state)
{
case 1:tmpMap.put("state_img", R.drawable.icon_question);break;
case 2:tmpMap.put("state_img", R.drawable.icon_process);break;
case 3:tmpMap.put("state_img", R.drawable.icon_correct);break;
default:tmpMap.put("state_img", R.drawable.icon_correct);
}
mListItems.add(tmpMap);
Log.e(news.toString(), news.toString());
}
return true;
}else {
return false;
}
} /**
* @param 对下拉刷新控件进行设置
*/
private void setPullToRefreshView(){
mListItems = new LinkedList<Map<String,Object>>();
pullToRefreshListView = (PullToRefreshListView)findViewById(R.id.pullToRefreshListView1);
pullToRefreshListView.setOnRefreshListener(new OnRefreshListener() {
public void onRefresh() {
new GetDataTask().execute(); //拉数据的线程开启
}
});
pullToRefreshListView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> arg0, View arg1, final int arg2,
long arg3) {
Log.e("Pull", String.valueOf(arg2));
ShareData.showProblem = problemController.getOldProblems().get(arg2 - 1);
Intent intent = new Intent(getApplicationContext(), DetailsActivity.class); //设置新的图片,如今用数据库的方法,所以这个操作就不须要了,到时候统一读取图片
// ImageView tempImage=(ImageView)arg1.findViewById(R.id.imageView2);
// tempImage.setImageResource(R.drawable.icon_correct);
//把状态存入数据库,推断图片状态,假设为1则说明没有被訪问过。改变为2
mytab = new MyOperator(helper.getWritableDatabase());
if(mytab.getstatebyID(ShareData.showProblem.getID())==1)
{
mytab = new MyOperator(helper.getWritableDatabase());
mytab.update(ShareData.showProblem.getID(), 2);
} //将故障ID传入到选项界面。以便与推断哪个页面选了哪些选项。 int id=ShareData.showProblem.getID();
Bundle bd=new Bundle();
bd.putInt("id", id);
intent.putExtra("ID", bd); startActivity(intent);
//传入到了还有一个界面
}
});
pullToRefreshListView.setOnItemLongClickListener(new OnItemLongClickListener() {
public boolean onItemLongClick(AdapterView<? > arg0, View arg1,
int arg2, long arg3) {
Log.e("PullLong", String.valueOf(arg2));
return true;
}
});
SimpleAdapter adapter = new SimpleAdapter(getApplicationContext(), mListItems, R.layout.layout_listitem,
new String[]{"id", "img", "describe", "time" ,"state_img"},
new int[]{R.id.title_TV, R.id.imageView1, R.id.content_TV, R.id.date_TV, R.id.imageView2});
pullToRefreshListView.setAdapter(adapter); } private Handler handler = new Handler(){
@Override
public void handleMessage(Message message) {
Toast.makeText(getApplicationContext(), "网络状况出现故障!", Toast.LENGTH_LONG).show();
}
};
}

android操作sqlite数据库及心得的更多相关文章

  1. 无废话Android之android下junit测试框架配置、保存文件到手机内存、android下文件访问的权限、保存文件到SD卡、获取SD卡大小、使用SharedPreferences进行数据存储、使用Pull解析器操作XML文件、android下操作sqlite数据库和事务(2)

    1.android下junit测试框架配置 单元测试需要在手机中进行安装测试 (1).在清单文件中manifest节点下配置如下节点 <instrumentation android:name= ...

  2. Android中操作SQLite数据库

    我又回到了安卓的学习当中,忙来忙去终于忙的差不多有时间做自己的事情了,这感觉实在是太棒了!!本来想写android的控件以及他们的监视器的,但是我查了查android的手册,基本上都能查到,但是查有些 ...

  3. Android中SQLite数据库操作(1)——使用SQL语句操作SQLite数据库

    下面是最原始的方法,用SQL语句操作数据库.后面的"Android中SQLite数据库操作(2)--SQLiteOpenHelper类"将介绍一种常用的android封装操作SQL ...

  4. Java操作Sqlite数据库-jdbc连接

    Java操作Sqlite数据库步骤: 1. 导入Sqlite jdbc 本文使用sqlite-jdbc-3.7.2.jar,下载地址 http://pan.baidu.com/s/1kVHAGdD 2 ...

  5. android 一个SQLite数据库多个数据表的基本使用框架 (带demo)

    android 一个SQLite数据库多个数据表(带demo) 前言        demo演示        一.搭建        二.建立实体类        三.建立数据库操作类        ...

  6. Qt for Android 打包 SQLite 数据库

    Qt for Android 调用 SQLite 数据库时, 怎样将已经存在的数据库附加到 APK 中? 直接在你项目里面的Android源码的根目录下新建一个文件夹assets, 数据库就可以放里面 ...

  7. Android实现SQLite数据库联系人列表

    Android实现SQLite数据库联系人列表 开发工具:Andorid Studio 1.3 运行环境:Android 4.4 KitKat 工程内容 实现一个通讯录查看程序: 要求使用SQLite ...

  8. EF6操作Sqlite数据库的项目兼容性问题

    vs2010无法正确打开2015创建的项目里面操作Sqlite数据库时使用EF6创建的edmx文件(会显示空白)   但是可以正常查询 vs2015无法正确打开2010创建的项目里面操作Sqlite数 ...

  9. EF操作sqlite数据库时的项目兼容性问题

    问题:vs2015打不开vs2010建的操作sqlite的实体数据模型edmx文件 原因: 当前电脑必须先安装:驱动库及sqlite的vs拓展 正常情况下安装驱动和拓展后,vs2015就应该可以正常打 ...

随机推荐

  1. python模块分析之hashlib加密(二)

    前言 hashlib模块是py3.+用来对字符串进行hash加密的模块,核心算法是md5,明文与密文是一一对应不变的关系:用于注册.登录时用户名.密码等加密使用. 模块分析 hashlib模块有多种加 ...

  2. Linux TTY驱动--Uart_driver底层【转】

    转自:http://blog.csdn.net/sharecode/article/details/9196591 版权声明:本文为博主原创文章,未经博主允许不得转载. Linux 中将串口驱动进行了 ...

  3. centos7 部署 docker swarm

    =============================================== 2019/4/9_第3次修改                       ccb_warlock 更新说 ...

  4. Ubuntu 12.04 下 Sublime Text 3 Build 3047 破解

    1. $sudo vim /opt/sublime_text/sublime_text 2. 将文件转成十六进制形式.在 vim 中输入: :%!xxd 3. 查找数字串 “4333 3342 303 ...

  5. 【军哥谈CI框架】之CI中集成百度UEditor

    Hello,各位亲,新的一周来临啦,很高兴这么快又跟大家伙见面!话说上一回,军哥带大家用JQuery写了一个城市级联菜单的例子 ,不知道亲们学会了多少,是否自己可以独立写出来了呢. 军哥很是期待大家学 ...

  6. mysql过滤数据

    1.大纲 WHERE - 学习如何使用WHERE子句根据指定的条件过滤行记录. AND运算符 - 介绍如何使用AND运算符以组合布尔表达式以形成用于过滤数据的复杂条件. OR运算符 - 介绍OR运算符 ...

  7. IEnumerable<T>

    IEnumerable 饮水思源 <C#本质论> Overview 根据定义,.Net 的中集合,本质上是一个类,它最起码实现了IEnumeraable 或者非泛型的IEnumerable ...

  8. python 实现结构体

    # python 使用类创建结构体 class Myclass(object): class Struct(object): def __init__(self, name, age, job): s ...

  9. python的异常处理及异常类定义

    python的异常处理语法和大多数语言相似: try: try块的语句... except exceptiontype1 as var:#使用as语句获得本次捕获到的异常的实例var except块语 ...

  10. python语法(五)—函数

    前面几天学习了python的基础语法,判断,循环,以及文件操作等等内容,对python也是有了一个认识.今天开始学习python的函数和模块. 函数 函数是什么?我的理解就是,他和java中的方法是一 ...