• Android数据存储之SQLite


    SQLite,是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它的设计目标是嵌入式的,而且目前已经在很多嵌入式产品中使用了它,占用资源非常少,只有几百KB内存。支持Windows/Linux/Unix等等主流的操作系统,同时能够跟其他程序语言相结合,比如 Tcl、C#、PHP、Java等,还有ODBC接口,同样比起Mysql、PostgreSQL这两款开源的世界著名数据库管理系统来讲,它的处理速度比他们都快。SQLite是当前使用最广泛的数据库,基于以上优点,Android系统采用SQLite数据库。

    SQLiteOpenHelper介绍

     Android应用程序为了对数据库进行管理,提供了一个抽象类SQLiteOpenHelper,SQLiteOpenHelper类提供了两个重要的方法,分别是 onCreate()和 onUpgrade(),onCreate用于初次使用软件时生成数据库表,onUpgrade用于升级软件时更新数据库表结构。

      当调用SQLiteOpenHelper的getWritableDatabase()或者getReadableDatabase()方法获取用于操作数据库的SQLiteDatabase实例的时候,如果数据库不存在,Android系统会自动生成一个数据库,接着调用onCreate()方法。onCreate()方法在初次生成数据库时才会被调用,在onCreate()方法里可以生成数据库表结构及添加一些应用使用到的初始化数据。

    onUpgrade()方法在数据库的版本发生变化时会被调用,一般在软件升级时才需改变版本号,而数据库的版本是由程序员控制的。

      假设现在的版本是1,升级软件时希望更新用户手机里的数据库表结构,为了实现这一目的,可以把原来的数据库版本设置为2,并且在onUpgrade()方法里面实现表结构的更新。当软件的版本升级次数比较多,这时在onUpgrade()方法里面可以根据原版号和目标版本号进行判断,然后做出相应的表结构及数据更新。

    Demo的实现

    先来看一个页面:

    布局就不用写了,就是四个按钮,实现的目的就是在生成Person数据库,同时生成一个表,然后操作Person中的数据:

    首先需要重写一下抽象类SQLiteOpenHelper中的方法

    public class MySQLDBHelper extends SQLiteOpenHelper {
    
    	private static final String DBname="Person.db";
    	private static	final int version=1;
    	private String tag="MySQLDBHelper";
    
    	public MySQLDBHelper(Context context) {
    		super(context, DBname, null, version);
    		Log.i(tag, "测试");
    	}
    	
    	@Override
    	public void onCreate(SQLiteDatabase db) {
    		// TODO Auto-generated method stub
    		Log.i(tag, "Person数据库中Person创建前");
    		String sqlString="create table Person (id integer primary key autoincrement,Name nvarchar(200),Address nvarchar(200))";
    		db.execSQL(sqlString);
    		Log.i(tag, "Person数据库中Person创建成功");
    	}
    
    	@Override
    	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    		// TODO Auto-generated method stub
    		Log.i(tag, "更新数据库,暂时不需要使用");
    	}
    
    }

    构造函数中的数据库名称和版本号都是自己可以固定一下,测试就没有传那么多参数,,多说一下这个@Override:

    @Override是伪代码,表示重写(当然不写也可以),不过写上有两点好处: 
    1、可以当注释用,方便阅读;
    2、编译器可以给你验证@Override下面的方法名是否是你父类中所有的,如果没有则报错。例如,你如果没写@Override,而你下面的方法名写错了,这时你的编译器是可以编译通过的,因为编译器以为这个方法是你的子类中自己增加的方法。

    插入数据调用,这里获取SQLiteDatabase,让后把拼接好的sql直接传入执行就OK了:

    public void insert(View view) {
    		SQLiteDatabase database = dbhelper.getWritableDatabase();
    		String sql = "insert into Person values(NULL,?,?)";
    		database.execSQL(sql, new Object[] { "FlyElephant", "北京" });
    		Log.i(tag, "插入成功");
    	}

    更新数据,这里注意一下ContentValues的使用,键值对的顺序:

    	public void update(View view) {
    		SQLiteDatabase database = dbhelper.getWritableDatabase();
    		ContentValues contentValues = new ContentValues();
    		contentValues.put("Address", "深圳");
    		database.update("Person", contentValues, "Name=?",
    				new String[] { "FlyElephant" });
    		Log.i(tag, "更新成功");
    	}
    

    查询数据,这里用到了游标,类似于C#中SqlDataReader的使用,moveToNext可以满足基本需求:

    	public void query(View view) {
    		SQLiteDatabase database = dbhelper.getReadableDatabase();
    		Cursor cursor = database.rawQuery("select * from Person", null);
    		if (cursor.getCount()>0) {
    			while (cursor.moveToNext()) {
    				String nameString = cursor.getString(cursor.getColumnIndex("Name"));
    				String addreString = cursor.getString(cursor
    						.getColumnIndex("Address"));
    				Log.i(tag, "Name:" + nameString + "--Address:" + addreString);
    			}
    		}else {
    			Log.i(tag, "没有数据");
    		}
    		cursor.close();
    	}

    如果你觉得moveToNext()不能满足需求,我就从网上找了一下别人贴的代码,如下:

    c.move(int offset);	//以当前位置为参考,移动到指定行
    c.moveToFirst();	//移动到第一行
    c.moveToLast();		//移动到最后一行
    c.moveToPosition(int position);	//移动到指定行
    c.moveToPrevious();	//移动到前一行
    c.moveToNext();		//移动到下一行
    c.isFirst();		//是否指向第一条
    c.isLast();		//是否指向最后一条
    c.isBeforeFirst();	//是否指向第一条之前
    c.isAfterLast();	//是否指向最后一条之后
    c.isNull(int columnIndex);	//指定列是否为空(列基数为0)
    c.isClosed();		//游标是否已关闭
    c.getCount();		//总数据项数
    c.getPosition();	//返回当前游标所指向的行数
    c.getColumnIndex(String columnName);//返回某列名对应的列索引值
    c.getString(int columnIndex);	//返回当前行指定列的值

    删除数据:

    	public void delete(View v) {
    		SQLiteDatabase database = dbhelper.getReadableDatabase();
    		database.delete("Person", "Name=?", new String[] { "FlyElephant" });
    		Log.i(tag, "删除成功");
    	}
    

     可以看下结果:

    周末又过完了,希望大家明天上班都精精神神的,开开心心的,醉在周末~

  • 相关阅读:
    JVM调试常用命令——jmap、jstat(2)
    JVM调试常用命令——jps、(1)
    线程基础:多任务处理(18)——MESI协议以及带来的问题:volatile关键字
    线程基础:多任务处理(18)——MESI协议以及带来的问题:伪共享
    网络穿透与音视频技术(5)——NAT映射检测和常见网络穿越方法论(NAT检测实践2)
    网络穿透与音视频技术(4)——NAT映射检测和常见网络穿越方法论(NAT检测实践1)
    网络穿透与音视频技术(3)——NAT映射检测和常见网络穿越方法论(NAT检测)
    网络穿透与音视频技术(2)——NAT的概念及工作模式(下)
    成功解决JSP和Servlet的中文乱码问题
    bootstrap心得
  • 原文地址:https://www.cnblogs.com/xiaofeixiang/p/4052488.html
Copyright © 2020-2023  润新知