安卓开发的SQLite操作

Android——SQLite数据库使用详解 登录后的页面activity_index.xml,这个页面就显示了一个用户的姓名(开始还有几个测试按钮,之后感觉不好看删除了O(∩_∩)O哈哈~,你们可以自己加几个按钮测试)relativePackage 阅读详情

1、存储方式简介

      之前已经讲解过APP对接服务器的demo,众所周知,一个APP,必不可少地会涉及到服务器以及数据库的操作。连接服务器,可以让我们合理地利用服务器以及客户端进行任务分配,如果所有功能都在客户端或者服务端完成,必然会造成一头大一头小的情况。合理地安排任务,能够大大地提高APP的稳定性以及可操作性。而对于一个多用户使用的APP,用户使用过程更是会产生许多的数据,其中一些有用的数据需要我们保存下来,因为下次使用用户可能还需要继续使用。

      在安卓开发之中,提供给我们使用的存储方法有较多。

  • 如果这些数据只是在当前activity生命周期之中有用到的(一次性数据),我们可以直接通过定义变量的形式来临时储存(activity结束或者系统内存紧张时,这些变量随时都有可能被回收)。这种方法优缺点比较明显,存储快速,定义简单,但是数据没有持久性。
  • 将数据存储在手机文件里。将数据存储在手机文件里,可以解决上面临时变量的缺点,利用JAVA流将数据存储在手机文件之中,对于一些数据类型较为简单的存储十分实用。但是以文件的形式来存储数据,缺点也很明显,首先,手机文件存储数据,能实现的存储数据类型十分有限,对于一些具有复杂联系的数据难以储存,就算存放进去了,后期的维护也是十分艰难。
  • 第三个存储方法就是利用JAVA提供的一个SharedPreferences类来存储数据。其实这一种方法跟手机文件存储有点相似,但是该方法下存储的数据是以键值对的形式进行存储的,之后在读取时可以通过键来读取对应键的内容,这样的存储方式对于一些常见的键值数据的存储十分方便。虽然SharedPreferences方法比之手机文件存储方式多了一个键值对的功能,但是仍然无法很好地处理一些复杂数据类型。
  • 数据库。数据库相信大部分人都有听说过,数据库分为多种类型,而最常见的就是关系型数据库了。关系型数据库通过数据之间的关系来建表,并且通过表的形式来管理数据,实现数据的增删查改。虽然数据库能够很好地维护一些复杂数据类型,但是对于一些简单的数据存储,就没有必要使用数据库来管理了,这样反而显得冗余。

2、SQLite简介  

    本次程序使用的数据库是SQLite数据库,实现的是一个APP连接到数据库的增查改操作。先看一下APP实现的功能:


     SQLite是一款轻量级的关系型数据库,它运算速度快,占用资源少,通常只需要几百k的内存就够了,支持标准的sql语法和数据库的ACID事务。在Android中为了能够更加方便的管理数据库,专门提供了一个SQLiteOpenHelper帮助类,借助这个类就可以非常简单的对数据库进行创建和升级。


     SQLiteOpenHelper是一个抽象类,如果我们要使用的话,就需要创建一个自己的类去继承它。SQLiteOpenHelper中有2个抽象方法,分别是onCreate和onUpgrade方法,我们必须在自己的帮助类里面重写这两个方法,然后分别在这两个方法中实现创建,升级数据库的逻辑。


     SQLiteOpenHelper中还有2个非常重要的实例方法,getReadableDatabase()和getWritableDatabase()方法。这两个方法都可以创建或打开一个现有的数据库(如果数据库已经存在则直接打开,否则创建一个新的数据库),并返回一个可对数据库进行读写操作的对象。不同的是当数据库不可写入的时候(如磁盘空间已满)getReadableDatabase()方法返回的对象将以只读的方式去打开数据库,而getWritableDatabase()方法方法将出现异常。


     SQLiteOpenHelper中有2个构造方法可供重写,一般使用参数少点的那个构造方法即可。这个构造方法中接收4个参数,第一个参数是Context,必须要有Context才能对数据库进行操作。第二参数是数据库名,创建数据库时使用的就是这里使用的名称。第三个参数允许我们在查询数据的时候返回一个自定义的Cursor,一般都是传如null。第四个参数表示当前数据库的版本号,可用于对数据库进行升级操作。构建出SQLiteOpenHelper的实例后,在调用它的getReadableDatabase()或getWritableDatabase()方法就能够创建数据库了,数据库文件会存放在/data/data/<package name>/databases/目录下。此时,重写的onCreate方法也会得到执行,所以通常在这里去处理一些创建表的逻辑。

3、SQLite数据库的创建

      SQLite数据库的创建主要是通过继承SQLiteOpenHelper并重写其onCreate(用来创建数据库),onUpgrade(用来更新数据库),onDowngrade(用来数据库的版本向下兼容,若是不重写该方法,那么就必须保证数据库的版本version每次操作都是大于或者等于上一次的操作的版本)。具体看一下代码:

public class MySQLite extends SQLiteOpenHelper{

	//从ShareData中取得想要新建的表名
	ShareData sData=new ShareData();
	//建表语句
	private Context context;
	public  MySQLite(Context context,String name,
			SQLiteDatabase.CursorFactory factory,int version) {
		super(context,name,factory,version);
		this.context=context;
	}
	/*
	 * 建表,该表有四列,分别为主键id、username、password以及验证码verification
	 * @see android.database.sqlite.SQLiteOpenHelper#onCreate(android.database.sqlite.SQLiteDatabase)
	 */
	@Override
	public void onCreate(SQLiteDatabase db) {
		if(!sData.get().isEmpty()) {
		String CREATE_BOOK="create table "+sData.get()+"("+"id integer primary key autoincrement,"
			        +"username text,"+"password text,"+"verification integer)";
		db.execSQL(CREATE_BOOK);
		Log.i("建表界面","表名是"+sData.get());
		Toast.makeText(context, "建表成功", Toast.LENGTH_SHORT).show();
		}
		else
		Toast.makeText(context, "获取表名失败", Toast.LENGTH_SHORT).show();	
	}
	@Override
	public void onUpgrade(SQLiteDatabase db,int oldVersion,int newVersion) {
		if(oldVersion!=newVersion) {
		db.execSQL("drop table if exists "+sData.get());
		Log.i("更新界面","表名是"+sData.get());
		onCreate(db);
		}
	}
	@Override
	public void onDowngrade (SQLiteDatabase db, int oldVersion, int newVersion) {

		
	}
	/*
	 * 判断某张表是否存在的方法
	 */
	/**
     * 判断某张表是否存在
     * @param tabName 表名
     * @return
     */
    public boolean tabIsExist(String tabName){
            boolean result = false;
            if(tabName == null){
                    return false;
            }
            SQLiteDatabase db = null;
            Cursor cursor = null;
            try {
                    db = this.getReadableDatabase();//此this是继承SQLiteOpenHelper类得到的
                    String sql = "select count(*) as c from sqlite_master where type ='table' and name ='" + tabName.trim() + "' "; 
                    cursor = db.rawQuery(sql, null);
                    if(cursor.moveToNext()){
                            int count = cursor.getInt(0);
                            if(count>0){
                                    result = true;
                            }
                    }
                     
            } catch (Exception e) {
                    // TODO: handle exception
            }                
            return result;
    }
}

      其实上面代码写了那么多,真正用于创建数据库的就是这两句

String CREATE_BOOK="create table "+sData.get()+"("+"id integer primary key autoincrement,"
			        +"username text,"+"password text,"+"verification integer)";
		db.execSQL(CREATE_BOOK);
      第一句是创建数据库的SQL语言,这个SQL命令通过db.execSQL发送执行,这样当数据库接收到建表指令之后就会执行建立数据库的操作。当然还需要在mainActivity里面实例化该类,然后进行一次getWritableDatabase方法,该方法下,若是数据库存在将会打开数据库,若是数据库不存在则会执行上面的onCreate方法建立新的数据库。
mSqLite=new MySQLite(this, "QiuRuibo_SQLite", null
					,version);
			Log.i("MainVersion",""+version);
			sData.set(creatTableText.getText().toString());
			mSqLite.getWritableDatabase();

       MainActivity的代码:

public class MainActivity extends BaseActivity implements OnClickListener{

	private Button creatTableButton,next;
	private EditText creatTableText;
	private MySQLite mSqLite;
	private SharedPreferences sPreferences;
	private SharedPreferences.Editor editor;
	ShareData sData;
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		//初始化控件
		creatTableButton=(Button)findViewById(R.id.newTableButton);
		next=(Button)findViewById(R.id.nextButton);
		creatTableText=(EditText)findViewById(R.id.newTableText);
		creatTableButton.setOnClickListener(this);
		next.setOnClickListener(this);
		//从ShareData中设置想要新建的表名
		sData=new ShareData();
		//实例化一个shared来保存数据
		sPreferences=(SharedPreferences)getSharedPreferences("MySQLiteVersion", MODE_PRIVATE);
		//使用Editor类来存放数据到SharedPreferences中
		editor=sPreferences.edit();
		
		creatTableText.setFilters(new InputFilter[]{filter});
		
	}
	/*
	 * 禁止editText输入空格或者回车,因为数据库建表时不允许空格或者回车等特殊字符
	 */
	private InputFilter filter=new InputFilter() {
		   @Override
		   public CharSequence filter(CharSequence source, 
				   int start, int end, Spanned dest, int dstart, int dend) {
		      if(source.equals(" ")) {
		    	  Toast.makeText(MainActivity.this, "表名不允许出现空格", Toast.LENGTH_SHORT).show();
		    	  return "";
		      }
		      else if(source.toString().contentEquals("\n"))
		      {
		    	  Toast.makeText(MainActivity.this, "表名不允许出现回车", Toast.LENGTH_SHORT).show();
		    	  return "";
		      }
		      else return null;
		   }
		};
	
	/*
	 * 重写监听事件,为建表等按钮添加监听事件
	 */
	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.newTableButton:
			if(!creatTableText.getText().toString().isEmpty()) {   //如果表名非空,则建表,否则提示
			//获取sharedPreferences中当前数据库版本号,并加1赋值给MySQLite,这样才能保证MySQLite会执行onUpgrade
			int version=sPreferences.getInt("MySQLiteVersion",0);
			version++;
			mSqLite=new MySQLite(this, "QiuRuibo_SQLite", null
					,version);
			Log.i("MainVersion",""+version);
			sData.set(creatTableText.getText().toString());
			mSqLite.getWritableDatabase();
			//将数据库当前版本号存放到sharedPreferences中
			editor.putInt("MySQLiteVersion",version);
			editor.apply();
			}
			else {
				Toast.makeText(this, "表名不能为空", Toast.LENGTH_SHORT).show();
			}
			break;
		case R.id.nextButton:
			Intent intent=new Intent(MainActivity.this,InsertDataActivity.class);
			startActivity(intent);
			onPause();
			break;
		default:
			break;
		}
	}
}

      我们可以注意到,上面的MainActivity并不是直接继承于Activity,而是继承于自建的BaseActivity,为什么要建立这个activity呢?其实作用很简单,建立BaseActivity,可以减少很多activity的重复性操作,本文中,在baseactivity中定义了一个activityCollector管理器,实现每个activity创建后都在List<Activity>里面注册,销毁时都在List<Activity>中注销。这么做有什么用呢?当我们想要一键关闭所有的activity时就显得十分地方便,在想要关闭所有的activity时我们可以在收集activity的管理器中通过一个循环关闭所有的activity。当然建立这么一个父activity还可以实现很多其他的功能,能够避免我们代码中出现大量的重复代码。下面是BaseActivity的代码:

package com.example.sqlite;

import android.app.Activity;
import android.os.Bundle;

public class BaseActivity extends Activity{

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		ActivityCollector.addAvtivity(this);
	}
	@Override
	public void onDestroy() {
		super.onDestroy();
		ActivityCollector.removeActivity(this);
	}
}

     ActivityCollector的代码 

public class ActivityCollector {

	//创建一个activity的list来收集每一个activity
	public static List<Activity> activities=new ArrayList<Activity>();
	/**
	 * @param 新增传递进来的activity
	 */
	public static void  addAvtivity(Activity activity) {
		activities.add(activity);
	}
	/**
	 * @param 删除传递进来的activity
	 */
	public static void removeActivity(Activity activity) {
		activities.remove(activity);
	}
	/**
	 * @param 删除所有的activity
	 */
	public static void finishAll() {
		for(Activity a:activities)
			if(!a.isFinishing())
				a.finish();
		activities.clear();
	}
}

4、SQLite数据库的增删查改

      在前面建立数据库时我们贴了一大段的代码,里面用于建立数据库的其实只有onCreat方法,那么里面的更新方法是用来干嘛的呢?现在我们就要用到它了,因为一个数据库一旦建立了,那么就不会再执行onCreate方法了,那么如果我们想要新增或者修改一个表的结构怎么办呢,这时就要用到上面的onUpgrade方法了。而onUpgrade方法也是有一定的执行时机的,只有当数据库版本比之前高时才会执行onUpgrade方法,因此如果我们想要修改数据库中表的结构,我们必须在修改时给数据库一个更高的版本,这样才会执行onUpgrade方法。

    我们在编写数据库应用软件时,需要考虑这样的问题:因为我们开发的软件可能会安装在很多用户的手机上,如果应用使用到了SQLite数据库,我们必须在用户初次使用软件时创建出应用使用到的数据库表结构及添加一些初始化记录,另外在软件升级的时候,也需要对数据表结构进行更新。那么,我们如何才能实现在用户初次使用或升级软件时自动在用户的手机上创建出应用需要的数据库表呢?总不能让我们在每个需要安装此软件的手机上通过手工方式创建数据库表吧?因为这种需求是每个数据库应用都要面临的,所以在Android系统,为我们提供了一个名为SQLiteOpenHelper的抽象类,必须继承它才能使用,它是通过对数据库版本进行管理来实现前面提出的需求。 
为了实现对数据库版本进行管理,SQLiteOpenHelper类提供了两个重要的方法,分别是onCreate(SQLiteDatabase db)和onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion),前者用于初次使用软件时生成数据库表,后者用于升级软件时更新数据库表结构。当调用SQLiteOpenHelper的getWritableDatabase()或者getReadableDatabase()方法获取用于操作数据库的SQLiteDatabase实例的时候,如果数据库不存在,Android系统会自动生成一个数据库,接着调用onCreate()方法,onCreate()方法在初次生成数据库时才会被调用,在onCreate()方法里可以生成数据库表结构及添加一些应用使用到的初始化数据。onUpgrade()方法在数据库的版本发生变化时会被调用,一般在软件升级时才需改变版本号,而数据库的版本是由程序员控制的,假设数据库现在的版本是1,由于业务的变更,修改了数据库表结构,这时候就需要升级软件,升级软件时希望更新用户手机里的数据库表结构,为了实现这一目的,可以把原来的数据库版本设置为2(有同学问设置为3行不行?当然可以,如果你愿意,设置为100也行),并且在onUpgrade()方法里面实现表结构的更新。当软件的版本升级次数比较多,这时在onUpgrade()方法里面可以根据原版号和目标版本号进行判断,然后作出相应的表结构及数据更新。

getWritableDatabase()和getReadableDatabase()方法都可以获取一个用于操作数据库的SQLiteDatabase实例。但getWritableDatabase() 方法以读写方式打开数据库,一旦数据库的磁盘空间满了,数据库就只能读而不能写,倘若使用getWritableDatabase()打开数据库就会出错。getReadableDatabase()方法先以读写方式打开数据库,如果数据库的磁盘空间满了,就会打开失败,当打开失败后会继续尝试以只读方式打开数据库。

     而SQLite数据库的添加数据其实可以有多种方法添加,如果你十分熟悉SQL语言,那么完全可以通过SQL语言来写,最后通过自定义的类MYSQL执行exec。当然安卓也提供了这么一个方法,那就是insert方法,该方法要求需要新增的数据封装到ContentValue里面,然后再进行添加。表的创建以及数据的新增如下:

public class InsertDataActivity extends BaseActivity implements OnClickListener{
	private Button addDataButton,backButton,updateButton;
	private EditText userName,userPassword,verification,chooseTable;
	private SharedPreferences sPreferences;
	private MySQLite mSQLite;
	private AlertDialog alertDialog;
	private ShareData sData;
	private SharedPreferences.Editor editor;
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.insert_data);
		//初始化控件
		addDataButton=(Button)findViewById(R.id.addDataButton);
		backButton=(Button)findViewById(R.id.back);
		updateButton=(Button)findViewById(R.id.updateButton1);
		userName=(EditText)findViewById(R.id.userNameText);
		userPassword=(EditText)findViewById(R.id.userPasswordText);
		verification=(EditText)findViewById(R.id.verificationCodeText);
		chooseTable=(EditText)findViewById(R.id.chooseTableText);
		//设置按钮监听
		addDataButton.setOnClickListener(this);
		updateButton.setOnClickListener(this);
		backButton.setOnClickListener(this);
		sPreferences=getSharedPreferences("MySQLiteVersion", MODE_PRIVATE);
		editor=sPreferences.edit();
		sData=new ShareData();
	}
	@Override
	protected void onResume() {
		// TODO Auto-generated method stub
		super.onResume();
		//从SharedPrefernces获取数据库版本号
				int version=sPreferences.getInt("MySQLiteVersion", 0);
				//创建数据库实例
				if(version==0) {
					alertDialog=new AlertDialog.Builder(InsertDataActivity.this).create();
					alertDialog.setTitle("警告:");
					alertDialog.setMessage("系统检测到数据库中还没有任何表,是否返回创建一张新表");
					alertDialog.setButton(DialogInterface.BUTTON_POSITIVE,"返回", 
							new DialogInterface.OnClickListener() {			
						@Override
						public void onClick(DialogInterface dialog, int which) {	
							finish();
								}
							});
					alertDialog.setButton(DialogInterface.BUTTON_NEGATIVE,"退出", 
							new DialogInterface.OnClickListener() {
								@Override
								public void onClick(DialogInterface dialog, int which) {
									// TODO Auto-generated method stub
									ActivityCollector.finishAll();
								}
							});
					//开启新线程,来进行延时操作
					new Thread(new Runnable() {
						
						@Override
						public void run() {
							try {
								Thread.sleep(900);
								Looper.prepare();
								alertDialog.show();	
								Looper.loop();
							} catch (InterruptedException e) {
								// TODO Auto-generated catch block
								e.printStackTrace();
							}	
						}
					}).start();		
				}
				else {
					Log.i("Version",""+version);
				mSQLite=new MySQLite(this, "QiuRuibo_SQLite", null,version);
				}
	}
	/*
	 * 重写监听方法,实现按钮监听
	 */
	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.addDataButton:
			if(chooseTable.getText().toString().isEmpty())
				Toast.makeText(this, "选择保存的表名不能为空", Toast.LENGTH_SHORT).show();
		    else if(userName.getText().toString().isEmpty())
				Toast.makeText(this, "用户名不能为空", Toast.LENGTH_SHORT).show();
			else if(userPassword.getText().toString().isEmpty())
				Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show();
			else if(verification.getText().toString().isEmpty())
				Toast.makeText(this, "验证码不能为空", Toast.LENGTH_SHORT).show();
			else {
			add();
			
			}
			break;
		case R.id.back:
			Intent intent=new Intent(InsertDataActivity.this,MainActivity.class);
			startActivity(intent);
			finish();
			break;
		case R.id.updateButton1:
			Intent intent1=new Intent(InsertDataActivity.this,UpdateActivity.class);
			startActivity(intent1);
			finish();
			break;
		default:
			break;
		}
	}
	private void add() {
		// TODO Auto-generated method stub
		SQLiteDatabase sqLiteDatabase=mSQLite.getWritableDatabase();
		ContentValues cValues=new ContentValues();
		cValues.put("username", userName.getText().toString());
		cValues.put("password", userPassword.getText().toString());
		cValues.put("verification", verification.getText().toString());
		 /*创建表,并判断是否已经存在此表,没创建,则创建并初始化*/
        if (!mSQLite.tabIsExist(chooseTable.getText().toString())) {
        	createAlertDialog();
            }
        else {
        	
        	// 开启事务
        	sqLiteDatabase.beginTransaction();
            try{
                    // 数据库操作
            	// 插入数据
            sqLiteDatabase.insert(chooseTable.getText().toString(), null, cValues);
            // 设置事务标志为成功,当结束事务时就会提交事务
            //(一定要记得添加这句,否则就会出现insert成功,但数据库没数据)
            sqLiteDatabase.setTransactionSuccessful();
            Toast.makeText(InsertDataActivity.this, "添加成功", Toast.LENGTH_SHORT).show();
            //将此时的表名传递给更新的activity
            ShareData.setTable(chooseTable.getText().toString());
            }
            catch(Exception e){
            	Toast.makeText(InsertDataActivity.this,
            			e.toString(), Toast.LENGTH_SHORT).show();
             
            } finally {
                    // 结束事务方法时会检查事务的标志是否为成功,
                    // 如果程序执行此方法之前调用了setTransactionSuccessful()方法设置事务的标志为成功则提交事务
              // 如果没有调用setTransactionSuccessful() 方法则回滚事务。
            	sqLiteDatabase.endTransaction();
            }
        }
		cValues.clear();
	}
	/*
	 * 创建一个对话框,用来询问是否自动建表
	 */
	public void createAlertDialog() {
		AlertDialog aDialog=new AlertDialog.Builder(InsertDataActivity.this).create();
		aDialog.setTitle("温馨提示");
		aDialog.setMessage("您想要保存的表名不存在,是否在数据库中自动创建该表?");
		aDialog.setButton(AlertDialog.BUTTON_POSITIVE,"是", 
				new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				//获取sharedPreferences中当前数据库版本号,并加1赋值给MySQLite,这样才能保证MySQLite会执行onUpgrade
				int version=sPreferences.getInt("MySQLiteVersion",0);
				mSQLite=new MySQLite(InsertDataActivity.this, "QiuRuibo_SQLite", null
						,++version);
				Log.i("MainVersion",""+version);
				sData.set(chooseTable.getText().toString());
				mSQLite.getWritableDatabase();
				//将数据库当前版本号存放到sharedPreferences中
				editor.putInt("MySQLiteVersion",version);
				editor.apply();
				
			}
		});
		aDialog.setButton(AlertDialog.BUTTON_NEGATIVE,"否", 
				new DialogInterface.OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
			}
		});
		aDialog.show();
	}
}

        上面的数据的添加是通过安卓提供的API来实现的,下面我们就用SQL语言来实现一个数据的更新的操作。

public class UpdateActivity extends BaseActivity implements OnClickListener{

	private SQLiteDatabase db;
	private MySQLite mySQLite;
	private Button updateButton,backButton,nextButton;
	private SharedPreferences sPreferences;
	private EditText updatePasswordText,updateAgainText,usernameToUpdate;
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.update);
		//初始化控件
		updateButton=(Button)findViewById(R.id.updateButton);
		backButton=(Button)findViewById(R.id.back1);
		nextButton=(Button)findViewById(R.id.nextButton1);
		updatePasswordText=(EditText)findViewById(R.id.updatePasswordText);
		updateAgainText=(EditText)findViewById(R.id.updateAgainText);
		usernameToUpdate=(EditText)findViewById(R.id.usernameToUpdatePassword);
		//设置按钮监听
		updateButton.setOnClickListener(this);
		backButton.setOnClickListener(this);
		nextButton.setOnClickListener(this);
		sPreferences=getSharedPreferences("MySQLiteVersion", MODE_PRIVATE);
		int version=sPreferences.getInt("MySQLiteVersion", 0);
		mySQLite=new MySQLite(this, "QiuRuibo_SQLite", null,version);
		
		
	}
	/*
	 * 重写方法,实现按钮监听
	 */
	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.back1:
			Intent intent=new Intent(UpdateActivity.this,InsertDataActivity.class);
			startActivity(intent);
			finish();
			break;
		case R.id.updateButton:
			if(updatePasswordText.getText().toString().equals
					(updateAgainText.getText().toString()))
			update();
			else {
				Toast.makeText(this, "两次输入的密码不一致", Toast.LENGTH_SHORT).show();
			}
			break;
		case R.id.nextButton1:
			
			break;
		default:
			break;
		}
	}
	private void update() {
		Cursor cursor=null;
		boolean isExist=false;
		db=mySQLite.getReadableDatabase();
		cursor=db.rawQuery("select count(username)  from "+ShareData.getTable()
		                +" where username='"+usernameToUpdate.getText().toString()
		                +"' ", null);
		 if(cursor.moveToNext()){
             int count = cursor.getInt(0);
             if(count>0){
                     isExist=true;
             }
     }
		 if(isExist) {
		db.execSQL("update "+ShareData.getTable()+" set password='"
	                    +updatePasswordText.getText().toString().trim()+"' where username='"
				        +usernameToUpdate.getText().toString().trim()+"'");
		Toast.makeText(UpdateActivity.this, "修改成功", Toast.LENGTH_SHORT).show();
		 }
		 else 
			 Toast.makeText(UpdateActivity.this, "用户名不存在", Toast.LENGTH_SHORT).show();
		
	}
}

        两种方法各有优缺点,看自己的知识掌握选择,当然我们还可以使用一些开源项目来进行数据库的操作,像LitePal等,LitePal是一种对象关系映射(ORM)的模式,可以帮助我们以面向对象的语言来实现数据库的操作,对于不熟悉SQL语言的人无疑是一个很大的福利。LitePal的操作这里就不介绍了,感兴趣的可以自己上Github下载使用,当然使用Android studio的就不用那么麻烦,可以直接新建一个xml文件就能够成功配置。

        补充一点:上面我们一直使用一个自定义类ShareData来实现不同类或者activity之间的数据共享,该类定义如下:

public class ShareData {

	private static String table="defaultTable",tableFromInsert;
	//private Context context;
	public ShareData(){
		//this.context=context;
	}
	public static void setTable(String table) {
		tableFromInsert=table;
	}
	public static String getTable() {
		return tableFromInsert;
	}
	public void set(String tableName) {
		table=tableName;
	}
	public String get() {
		return table;
	}
}



Android开发中的SQLite数据库操作 通过上述步骤,我们学习了如何在Android应用中使用SQLite数据库进行CRUD操作,并解决了常见的配置问题。掌握这些基本操作和问题解决方法,将有助于您更高效地开发Android应用。 阅读详情

相关推荐

17、Android SQLite数据库开发全解析:从创建到CRUD操作

本文详细解析了在Android应用开发中如何使用ContentProvider与SQLite数据库进行交互,涵盖从创建数据库、定义表结构、实现ContentProvider到完成CRUD操作的完整流程。同时介绍了数据库升级处理、ContentProvider的URIs使用方法以及MIME类型定义。最后通过实际案例展示了如何在应用中实现任务管理功能,并提出了优化建议,帮助开发者构建高效、稳定的数据存储功能。

hill8的博客 73

Android 操作SQLite基本用法

在Android开发中SQLite起着很重要的作用,网上SQLite的教程有很多很多,不过那些教程大多数都讲得不是很全面。本人总结了一些SQLite的常用的方法,借着论坛的大赛,跟大家分享分享的。 一.SQLite的介绍 1.SQLite简介 SQLite是一款轻型的数据库,是遵守ACID的关联式数据库管理系统,它的设计目标是嵌入  式的,而且目前已经在很多嵌入式产品中使用了它,

xyjikl 395

Android开发中SQLite多表联动操作详解

SQLite 是一种轻量级、无服务器架构的嵌入式关系型数据库,因其无需独立的数据库服务器进程、零配置、文件级存储等特性,被广泛应用于移动设备(如 Android、iOS)及小型本地应用中。它以库的形式嵌入到应用程序中,数据存储在单一文件中,便于移植与维护。本章将从 SQLite 的基本特点入手,分析其在资源受限环境下的优势,并探讨其在 Android 系统中的典型应用场景,如本地数据存储、缓存管理等,为后续章节中多表联动操作的学习奠定基础。

weixin_28729843的博客 1239

Hello Android - SQLite数据库操作

Android中内置的是SQLite小型数据库,类似access一样是以文件方式存在的,操作起来十分方便。android操作SQLite需要继承自SQLiteOpenHelper 来得到连接。实现了2个方法:onCreate和onUpgrade。第一次获得对数据库的读或写操作的时

luoxiangyu001的专栏 732

Android开发必备:SQLite数据库操作详解

SQLite 是 Android 平台内置的一款轻量级、嵌入式关系型数据库,无需依赖独立的数据库服务器即可运行。其核心特点包括:零配置、事务支持、跨平台兼容、数据库文件存储于本地,非常适合移动设备上的本地数据持久化需求。在 Android 开发中,SQLite 被广泛用于存储用户信息、应用配置、离线缓存等结构化数据。通过类和辅助类,开发者可以方便地进行数据库的创建、升级与操作。

weixin_42502040的博客 909

Android应用开发之SQLite数据库实战操作指南

在Android应用开发中,数据持久化是核心功能之一,而直接操作数据库则是实现高效本地数据存储的关键技能。本章将引导读者理解为何在现代Android开发中仍需掌握底层数据库操作能力,即使已有如Room等高级封装库的普及。Android平台内置了对SQLite数据库的支持,允许开发者在应用中创建、管理和查询本地数据库。所谓直接操作数据库,是指通过类直接执行SQL语句或调用其API进行数据的增删改查(CRUD)操作。

weixin_29867767的博客 1008

Android SQLite高级操作之泛型对象操作

SQLite是一款广泛用于嵌入式设备上的轻量级关系型数据库,而在安卓设备的数据存储上更是有举足轻重的位置,所以SQLite的基本操作是每个安卓开发者必须掌握的技能。而它操作与用法在网上已经有大量的资料,博客可以参考。所以这里我也不老生常谈,直接进入主题介绍今天要谈的SQLite泛型对象操作。

u012874222的博客 1598

最全软考高项工具技术总结(上)

第四版教材把工具和技术分为:数据收集技术、数据分析技术、数据表现技术、决策技术、沟通技巧、人际关系和团队技能、其他。我会按照上面的分类总结说明并标识他们用在哪些过程。小伙伴们可以通读理解做到有印象能选对应付上午选择,选几个深化用在下午论文的举例中。没必要背!

PM喵的窝 2045

Android 通过纯SQL语句操作SQLite完整示例(CRUD)

示例代码如下:这里用纯SQL实现了数据库的创建、建表、插入、修改、查询、删除等全部操作。并提供了两种不通过SQLiteOpenHelper类进行数据库创建或打开的操作方法和说明。

wh445306 1029

MySQL8.2.0下载安装

4、点击No thanks,just start my download,就是只是开始下载的意思,点击下载,等待下载完成。5、新建空白行,或直接双击紧挨的空白行,把复制的mysql的安装路径bin路径复制粘贴过来,确定,确定,确定。1、上面点击finish后,自动勾选了run mysql配置,自动会打开配置页面,点击Next。1、双击安装包,进入安装流程,勾选我同意 I accept,next。2、根据自己需要选择,我选的第二个,可以自己改安装路径。2、默认,点击Next,记住默认端口3306。

m0_59681797的博客 1万+

STM32与AD7606的SPI通信优化:提升高精度数据采集效率

本文深入探讨了STM32与AD7606的SPI通信优化策略,旨在提升高精度数据采集系统的效率与稳定性。文章从硬件连接、电源去耦、PCB布局等基础环节入手,详细解析了软件驱动中SPI模式配置、DMA应用及精准时序控制等关键优化技术,并提出了系统级的性能提升方案,帮助开发者解决高速采样下的数据跳动、效率瓶颈等实际问题。

weixin_29192211的博客 392

android 内嵌 数据库,安卓开发之嵌入式数据库sqlite的操作方法

安卓App开发经常会需要嵌入式数据库sqlite的辅助,它可以存放我们必要的应用数据,下面介绍下如何使用java连接读取sqlite中的数据。本文中的代码经本人测试可用,可以参考。代码如下:DBHelper.javapackage com.web.redrain;import android.content.Context;import android.database.sqlite.SQLite...

weixin_28733803的博客 640

[软考]系统架构设计师 备考经验分享(一) - 备考计划篇

前言 上周末刚刚结束了软考架构师的考试,自我感觉考的还可以,大概率是过了。 两次参加软考,一次中级嵌入式,一次高级架构师,都是备考不到两个月时间,尤其是架构师这次考试内容和本职工作有不小的差别,并且需要同时备考三个科目,在高强度地备考中感觉是摸索出到了一点软考的技巧与经验。 打算趁还记得,赶紧写几篇文章做下梳理总结,算是给将来自己考系分、高项或者其他考试做个记录,也希望能够帮到正在备考的大家。 先把第一步,个人的备考计划分享给大家。 自身情况分析 首先,请大家一定先明确三个问题,这三个问题会直接影响到你的

_ 6404

安卓开发工程师-SQLite 数据库操作

在 SQLite 中,表结构通过 SQL 的语句定义。例如,假设我们有一个用户表User_id:主键,自增name:用户姓名age:用户年龄。

qq_62784677的博客 1186

避坑指南:DeepSeek Function calling流式输出中的常见问题与解决方案

本文深入探讨了在DeepSeek Function Calling中实现流式输出时常见的参数拼接、函数依赖管理和错误处理等核心挑战。针对流式响应中参数碎片化的问题,提供了健壮的参数拼接方案与状态管理策略。同时,文章详细阐述了如何管理函数调用顺序、处理条件性执行,并构建了分阶段的错误处理与重试机制,旨在帮助开发者构建稳定、高效的流式AI应用。

weixin_29062671的博客 203

手把手教你复现IEEE 2025高光谱图像盲超分算法DBSR(附开源代码与避坑指南)

本文详细介绍了如何从零复现IEEE 2025高光谱图像盲超分算法DBSR,包括环境配置、数据预处理、核心模块解析、训练策略及常见问题解决方案。特别针对开源代码中的关键步骤和潜在问题提供了实用指南,帮助研究者和开发者高效实现Deep blind super-resolution技术,适用于遥感、医疗等领域的图像增强应用。

weixin_42524708的博客 413

安卓开发能用mysql吗_在安卓开发中使用SQLite数据库操作实例

前段时间写了个安卓平台下SQLite数据库操作的实例 ,一直没得时间总结 ,今天把它弄出来了。在Android 运行时环境包含了完整的 SQLite。首先介绍一下SQLite这个数据库:SQLite,是一款轻型的数据库,是遵守ACID的关联式数据库管理系统,它的设计目标是嵌入式的,而且目前已经在很多嵌入式产品中使用了它,它占用资源非常的低,在嵌入式设备中,可能只需要几百K的内存就够了。它能够支持W...

weixin_31869917的博客 1270

彻底解析 DDIC_TYPE_INCONSISTENCY:从 ABAP ST22 连环 Dump 到 SE14 一键修复

听上去像内核级的致命故障,实则更多源于日常运维的细枝末节。只要掌握的排查三板斧,结合严格的变更流程与周期性的字典体检,再严重的 Dump 也能化险为夷。希望本文的案例与步骤能帮助读者在下一次遇到类似问题时,既能快速止血,也能追根溯源,避免重蹈覆辙。

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 629

Android开发--使用adb访问操作sqlite数据库

adb命令访问Sqlite数据库。

程序袁的优快云 2296

lammps 案例in文件汇总

进阶案例: 聚乙烯和石墨烯界面pull out模拟代码 反应力场reax/c设置方法及案例解析 石墨烯热导率模拟代码(NEMD方法) 圆锥形SiC纳米磨削单晶硅源代码 高熵合金FeNiCrCoCu纳米压痕模拟代码 fix indent命令实现纳米摩擦及摩擦力计算 Fe原子辐照轰击多层石墨烯模拟代码 铝基石墨烯复合物压缩变形in文件源代码 石墨烯自动卷曲到Fe纳米线模拟源代码 铝/石墨烯复合物结晶过程lammps模

lammps_jiayou的博客 9445

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Android开发笔记(三十)SQLite数据库基础操作

SQLite语法 SQLite是一个小巧的嵌入式数据库,使用方便、开发简单,手机上最早由ios运用,后来android兴起同样也采用了sqlite。sqlite的多数sql语法与oracle是一样的,下面只列出不同的地方: 1、建表时为避免重复操作,应加上“IF NOT EXISTS”关键词,例如:CREATE TABLE IF NOT EXISTS table_name 2、同样的,删表时

aqi00的博客 3670

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

安卓开发之SQlite数据库

首先送各位有缘看到这篇文章的朋友们一句话:努力,总会有收获! 下面开始正题: SQlite数据库是一个轻量级的数据库,被用在嵌入式设备上,2019年6月还在流行的两大移动终端操作系统,Android和ios都支持这款数据库。 下面说一下怎么在安卓开发中操作sqlite数据库。 1.数据库的创建和更新 谷歌提供的api中有一个类叫做SQLiteOpenHelper,我们只需继承此类写出一个...

Ahacker_L的博客 1159

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Android开发中SQLite Expert的操作技巧

最近学习SQLite Expert,了解过后,才觉得和MySql同工异曲,深度学习android开发,就必须了解Sqlite Expert,才能更上一层楼。在之前的一篇文章中我已经粗浅的介绍了SQLite的基本使用方法,这一骗我重点介绍一下SQlite的事务操作,适配器操作,分页操作等技巧.当然,先简单的温习一下Sqlite基本方法,http://blog.youkuaiyun.com/google_huchu

移动开发者 3688

android开发第五天sqlite数据库操作

android开发第五天sqlite数据库操作   public class DBHelper extends SQLiteOpenHelper { /** * 数据库名称 */ private static final String DB_NAME="mydb.db"; /** * 数据库版本 */

anlun的专栏 432

Android开发之SQLite数据库的DAO标准CRUD操作

Android开发之SQLite数据库的DAO标准CRUD操作一、功能说明二、设计分析三、运行界面展示四、源码代码仓库地址 一、功能说明 实现SQLITE数据库基础CRUD操作。 需实现的具体功能为: 创建包括姓名和年龄的数据库,实现数据 -增:输入姓名和年龄信息,点击添加按钮,数据添加进数据库中在数据显示栏显示 -删:在数据显示栏点击要删除的数据,数据显示在输入信息栏,数据点击删除按钮,数据在数据显示栏删除 -查:呈现数据库中的所有信息到数据显示栏上 -改:在数据显示栏点击要修改的数据,数据显示在输入信息

qq_44677790的博客 456

Android开发之SQLite数据操作

这一节讲述一下Android中有关轻量级数据库SQLite的操作,主要正对该数据库的增删查改进行一些举例说明。 首先,得建一个数据库帮助类,用于建立数据库以及进行数据库方面的一些操作,该类必须继承自android.database.sqlite.SQLiteOpenHelper,重载两个方法,一个是onCreate()用于在数据库第一次创建的时候的操作,onUpgrade()用于在数据库版本更新

路漫漫其修远兮,吾将上下而求索 733
上一篇: String,StringBuffer与StringBuilder的区别??
下一篇: Android 从任何地方得到Application context
RuiBo_Qiu
博客等级 码龄11年 158粉丝 56原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值