android sqlite mysql_android操作sqlite数据库及心得

这篇博客主要介绍了如何在Android中使用SQLite数据库,包括数据库的创建、升级、插入、更新、删除和查询操作。作者强调了Cursor的重要性,以及在使用过程中需要注意的数据库关闭时机。此外,还分享了一个适合初学者的视频教程链接,并提供了具体的代码示例,帮助开发者避免常见的错误,如Cursor空指针问题。
摘要由CSDN通过智能技术生成

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

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

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

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

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

1、sudo  gedit/etc/profile2、将以下的两句加到上面打开的文件中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 find()

{

List all = new ArrayList();//此时仅仅是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 all = new ArrayList();//此时仅仅是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> 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 {

@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 _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 tmpMap = new HashMap();//用来储存日志名称的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>();

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();

}

};

}

一.创建一个DataBaseHelper DataBaseHelper是一个访问SQLite的助类,提供两个方面的功能 1.getReadableDatebase(),getWriteableDatabase()可以获取SQLiteDatabase对象,通过 2.提供了onCreate()和onUpdate()两个回调函数,允许我们常见和升级数据库是进行使用 A、 在SQLiteOpenHelper的子类当中,必须要有的构造函数 B、该函数是在第一次创建数据库的时候执行,实际上是在第一次得到SQLiteDataBase对象的时候onCreate 二、创建一个实体person类并且给字段和封装 三、创建一个业务类对SQL的CRUD操作 1.getWritableDatabase()和getReadableDatabase()的区别 ,两个方法都可以获取一个用于操作数据库SQLiteDatabase实例 2.execSQL(增,删,改都是这个方法)和close();android内部有缓存可关闭也不关闭也行,查询rawQuery是方法 3.在分页有到Cursor(游标)取游标下一个值cursor.moveToNext(),用游标对象接数据 "select * from person limit ?,?" person不能加上where 关键字 4.在删除注意:sb.deleteCharAt(sb.length() - 1); 四、AndroidCRUD业务对SQLite的CRUD操作 1.ContentValues对象的使用 2.android内部insert添加数据的方法,而且values这个不给值也必须要执行,而主键是不是null的其他字段的值是为null 3.insert update query delete 五、单元测试类要注意的 AndroidCRUDService curdService = new AndroidCRUDService(this.getContext()); /* * 注意:getContext必须在我们使用前已经注解进去的,在使用前要实力化,而且是使用后才有上下文 *一般设置为局部对象 */ 六、AndroidManifest.xml的配置 <!-- 配置用户类库android.test.runner测试 --> package jll.sqlitedb; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import android.database.sqlite.SQLiteDatabase.CursorFactory; /** * *@author Administrator DataBaseHelper是一个访问SQLite的助类,提供两个方面的功能 * 1.getReadableDatebase(),getWriteableDatabase()可以获取SQLiteDatabase对象,通过 * 2.提供了onCreate()和onUpdate()两个回调函数,允许我们常见和升级数据库是进行使用 */ public class DataBaseHelper extends SQLiteOpenHelper { // 给一个默认的SQLite数据库名 private static final String DataBaseName = "SQLite_DB"; private static final int VERSION = 2; // 在SQLiteOpenHelper的子类当中,必须要有的构造函数 public DataBaseHelper(Context context, String name, CursorFacto
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值