android操作sqlite数据库及心得
来源:互联网 发布:xoi linux 编辑:程序博客网 时间:2024/05/22 06:37
写这篇文章主要是网上的对sqlite的操作太多且太杂,很多时候都不能很好的运用到自己的项目中,结构不清晰,我自己写了一篇适合刚刚接触的人看的操作方法。
近来用android时要将一些数据保存起来,一开始用的是preferences,后来要保存的东西多了,发现用preferences明显不能满足要求了,而且发现用这个的话代码就变得有点乱了,所以才开始学习使用sqlite数据库,一开始以为不就是个数据库么,和平时的mysql啊或者是sqlserver都一样,都很简单的,但后来真正在用的时候才发现困难一个接着一个,但还是在不断的摸索中一步一步的不断解决困难,后来发现学习安卓的话当自己实在找不到思路时看看网上的一些教学视频也是个不错的选择。这里推荐一个视频不错,我就是照这个视频学的。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
;
}
}
}</string></string></string></string></string>
随便的一个项目中的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();
}
};
}</map<string,object></string,></string,></problem></
void
,></map<string,>
- android操作sqlite数据库及心得
- android操作sqlite数据库及心得
- Android Sqlite数据库创建及操作
- Android数据库sqlite封装心得
- android sqlite数据库操作
- Android数据库操作--------SQLite
- android数据库SQLite操作
- android 数据库 sqlite 操作
- android SQLite数据库操作
- Android SQLite数据库操作
- Android SQLite数据库操作
- Android sqlite 数据库操作
- Android操作Sqlite数据库
- Android sqlite 数据库操作
- android操作sqlite数据库
- android sqlite 数据库操作
- Android-操作SQLite数据库
- android操作SQLite数据库
- JS中cookie的基本使用
- 对于httpclient上传文件的封装
- CoVH之柯南开锁
- leetcode.355. Design Twitter
- 引用
- android操作sqlite数据库及心得
- Method Size Limit in Java
- 虚函数
- opengl中天空盒缝隙消除的解决办法!
- 120. Triangle
- win8 vs2010 openGL 配置
- 指向指针的指针
- qt 设置应用图标
- 台湾大学机器学习笔记——Neural Network 神经网络