android operation sqlite database and experience

Writing this article is mainly because there are too many and too complicated operations on sqlite on the Internet, and in many cases they cannot be used well in their own projects. The structure is not clear. I wrote an operation that is suitable for people who have just contacted. method.


Recently, when using Android, I need to save some data. At first I used preferences. Later, there were more things to save. I found that using preferences obviously could not meet the requirements, and I found that the code became a bit messy if I used this. I started to learn to use a sqlite database. At first I thought it was a database. The usual mysql or sqlserver are the same. They are all simple, but later when I actually use it, I find that the difficulties are one by one, but it is still continuous After trying to solve the difficulties step by step, I found out that it is a good choice to watch some teaching videos on the Internet when learning Android when I really can't find ideas. It’s good to recommend a video here. I learned it from this video. http://www.tudou.com/programs/view/2qH5Am_3MsM/


Write some preparations in the android operating database.

First of all, configure the environment variables of adb, because it is too troublesome to go to the adb directory every time to start. The following are the specific steps. Of course, other files can also be used. I am used to changing this. After the change, you can source it. It takes effect.

1. sudo gedit   /etc/profile
2. Add the following two sentences to the file opened above  export ANDROID_HOME=/home/sdk file path export PATH=$PATH:$ANDROID_HOME/platform-tools


3. Restart the computer and you're done! !

After adb is configured, we'd better give access to the database in the mobile phone, usually in /data/data/package name/database. After entering with adb shell, su gets the root permission of the mobile phone, and then gives the permission chmod.

If you want to read the database file, use the command sqlite3 database file. The database in it can run sqlite3 directly in the adb shell, but I can’t open the sqlite3 database in the adb shell according to what I found online, saying that the command is not found, the file I should upload It's all passed, there is no way, only to put the database files everywhere in the file explorer of ddms in eclipse and then run the sqlite3 database in the linux terminal to see.


Also note that when writing sql statements, you must pay attention to the "select * from" +TABLE_NAME in the from and quotation marks to leave spaces, otherwise they will be linked together.

The following is a piece of knowledge to talk about, SQLite increase, delete and other operations are quite simple, the trouble is the query operation, generally use Cursor to save the query data, at first I did not pay much attention to this is a pointer type, pointing to the database When I first wrote the data in the database, I wrote the closing operation of the database before the Cursor operation. That is to say, the database was closed first and then the Cursor object was operated. In this way, the Cursor null pointer was also caused. It was destined to have a cup for a long time. . .



Here are some examples of SQLite database operations, which will help some people who are still in confusion, and at the same time help them review them later.


SQLiteHelper.java (database auxiliary class)

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 (database operation class)

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;
		}
	}
}

Any activity in a project (activity class, operation to open the database is already in it)

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



Guess you like

Origin blog.csdn.net/u012457196/article/details/38408747