Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> android操作sqlite數據庫及心得

android操作sqlite數據庫及心得

編輯:關於Android編程

寫這篇文章主要是網上的對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 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();
		}
	};
}



  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved