写这篇文章主要是网上的对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. linux内核环形缓冲区【转】

    转自:https://blog.csdn.net/eydwyz/article/details/56671023 循环缓冲区在一些竞争问题上提供了一种免锁的机制,免锁的前提是,生产者和消费 都只有一个 ...

  2. lombok使用说明

    简介lombok 的官方网址:http://projectlombok.org/lombok 提供了简单的注解的形式来帮助我们简化消除一些必须有但显得很臃肿的 java 代码.特别是相对于 POJO, ...

  3. 014_mac下的端口查看

    一. 使用netstat去过滤listen效果不怎么理想. $ netstat -an|grep -i --color "listen" tcp6 0 0 ::1.5601 *.* ...

  4. poj2148

    题意:给出若干个没有公共面积的多边形,几个多边形可能属于同一个国家,要求给这个地图染色,同一个国家用相同的颜色,相邻国家不能用相同颜色.问最少需要多少种颜色. 分析:计算几何+搜索.先判断哪些多边形是 ...

  5. Java实现继承过程概述

    super(); 在调用子类的构造器的时候,如果没有显示的写出 super(); ,那么,编译器会在佛那个加上 super(); 无参构造器 如果想调用父类的有参构造器,那么,必须显示的调用,编译器不 ...

  6. HTTPS那-攻击实例与防御

    在<HTTPS-SSL证书>我描述了使用SSL证书时一些需要注意的安全问题,在这一篇文章里面我再演示一下针对HTTPS攻击的一些实例,通过这些实例能更安全的使用HTTPS.知己知彼百战不殆 ...

  7. 删除oracle 表中重复数据sql语句、保留rowid最小的一条记录

    delete from tablename a where rowid > ( select min(rowid) from table_name b where b.id = a.id and ...

  8. 《Look Mom, I don’t use Shellcode》议题解析

    0x0 前言 <Look Mom, I don’t use Shellcode>是2016年Syscan360上讲过的一个议题,这个议题的副标题是"Browser Exploit ...

  9. Simple Web API Server in Golang (2)

    In this challenge, I tried to implement a simple OAuth2 server basing on Simple Web API Server in [1 ...

  10. .NetCore 实现分页控件(URL分页)实战

    上一篇文章介绍了分页控件的具体实现方式,接下来我们就来做一个分页控件 后台数据处理就过度的介绍,下面针对URL分页中的下面几点做说明: 1.搜索条件的状态保持 2.点击分页需要带上搜索条件 3.页码的 ...