Android SqLite升级
android开发中,如果大家使用到了sqlite就会牵涉到它的升级问题,因为升级后的表结构可能完全不一样,会有字段的添加或者删除等。。
sqlite升级思路:
1:将表A重新命名:例如重新命名为:temp_A
2:创建新标A
3: 将temp_A中的数据【也就是更新前的数据】插入到新表A
我的案例分两种:1:一张表字段发生变化 2: 数据库中添加新的表
先看1:一张表字段发生变化
直接代码走起:
SQLiteOpenHelper类:
package com.example.sqldbupdatedemo;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
/****
*
* @author jone
*
* 2013-12-2
* com.example.sqldbupdatedemo
*
*/
public class MySqlHelper extends SQLiteOpenHelper
{
//DB name
public static final String DB_NAME = "TestUp.db";
//初始的版本号
public static final int DB_VERSION = 1;
//表名称
public static String tname = "myup";
//创建表的sql语句
public static final String CREATE_TASK_TB = "create table if not exists " + tname + "(name text,pwd text)";
public MySqlHelper(Context context, String name, int version)
{
super( context, name, null, version );
// TODO Auto-generated constructor stub
}
@Override
public void onCreate(SQLiteDatabase db)
{
// TODO Auto-generated method stub
db.execSQL( CREATE_TASK_TB );
Log.i( "tag", "oncreat db" );
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
Log.i( "tag", " onUpgrade db" );
//获取到旧表中的字段【也就是新表中保留的字段】
String columns = getColumnNames( db, tname );
//升级
updateTable( db, tname, columns );
}
private void updateTable(SQLiteDatabase db, String tableName, String columns)
{
try
{
db.beginTransaction();
String reColumn = columns.substring( 0, columns.length() - 1 );
// rename the table
String tempTable = tableName + "texp_temptable";
String sql = "alter table " + tableName + " rename to " + tempTable;
db.execSQL( sql );
// drop the oldtable
String dropString = "drop table if exists " + tableName;
db.execSQL( dropString );
// creat table
String ss = "create table if not exists " + tableName + "(name text,pwd text,rpwd text)";
db.execSQL( ss );
// load data
String newStr = "rpwd";
String newreColumn = reColumn + "," + newStr;
String ins = "insert into " + tableName + " (" + newreColumn + ") " + "select " + reColumn + "" + " " + " from "
+ tempTable;
db.equals( ins );
db.setTransactionSuccessful();
}
catch (Exception e)
{
// TODO: handle exception
Log.i( "tag", e.getMessage() );
}
finally
{
db.endTransaction();
}
}
// 获取升级前表中的字段
protected String getColumnNames(SQLiteDatabase db, String tableName)
{
StringBuffer sb = null;
Cursor c = null;
try
{
c = db.rawQuery( "PRAGMA table_info(" + tableName + ")", null );
if (null != c)
{
int columnIndex = c.getColumnIndex( "name" );
if (-1 == columnIndex)
{
return null;
}
int index = 0;
sb = new StringBuffer( c.getCount() );
for ( c.moveToFirst(); !c.isAfterLast(); c.moveToNext() )
{
sb.append( c.getString( columnIndex ) );
sb.append( "," );
index++;
}
}
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
if (c != null)
{
c.close();
}
}
return sb.toString();
}
}
具体的使用者Activity
package com.example.sqldbupdatedemo;
import java.util.ArrayList;
import android.app.Activity;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity implements OnClickListener
{
MySqlHelper dbHelper;
SQLiteDatabase db;
TextView tView1;
TextView tView2;
TextView tView3;
Button button;
Entity entity1;
Entity entity2;
ArrayList<Entity> list;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate( savedInstanceState );
setContentView( R.layout.activity_main );
dbHelper = new MySqlHelper( this, MySqlHelper.DB_NAME, 7 );
list = new ArrayList<MainActivity.Entity>();
initView();
initSql();
}
private void showInfo()
{
db = dbHelper.getReadableDatabase();
Cursor cursor = null;
try
{
cursor = db.rawQuery( "select * from myup", null );
while (cursor.moveToNext())
{
String name = cursor.getString( cursor.getColumnIndex( "name" ) );
String pwd = cursor.getString( cursor.getColumnIndex( "pwd" ) );
String rpwd = cursor.getString( cursor.getColumnIndex( "rpwd" ) );
// String myl = cursor.getString( cursor.getColumnIndex( "myl" ) );
Entity entity = new Entity( name, pwd, rpwd );
list.add( entity );
}
}
catch (Exception e)
{
// TODO: handle exception
e.printStackTrace();
Log.i( "tag", e.getMessage() );
}
if (cursor != null)
{
cursor.close();
db.close();
}
entity1 = list.get( 0 );
entity2 = list.get( 1 );
tView1.setText( entity1.getName() + "---" + entity1.getPwd() + "--" + entity1.getRpwd() );
tView2.setText( entity2.getName() + "---" + entity2.getPwd() + "--" + entity2.getRpwd() );
}
private void initView()
{
tView1 = (TextView) findViewById( R.id.en1 );
tView2 = (TextView) findViewById( R.id.en2 );
tView3 = (TextView) findViewById( R.id.en3 );
button = (Button) findViewById( R.id.btn );
button.setOnClickListener( this );
}
private void initSql()
{
db = dbHelper.getWritableDatabase();
String insert1 = "insert into myup(name,pwd) values(?,?)";
db.execSQL( insert1, new String[] { "zhangsan", "123456" } );
String insert2 = "insert into myup(name,pwd) values(?,?)";
db.execSQL( insert2, new String[] { "lisi", "789654" } );
db.close();
}
class Entity
{
String name;
String pwd;
String rpwd;
public Entity(String name, String pwd, String rwpd)
{
this.name = name;
this.pwd = pwd;
this.rpwd = rpwd;
}
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String getPwd()
{
return pwd;
}
public void setPwd(String pwd)
{
this.pwd = pwd;
}
public String getRpwd()
{
return rpwd;
}
public void setRpwd(String rpwd)
{
this.rpwd = rpwd;
}
}
@Override
public void onClick(View v)
{
switch (v.getId())
{
case R.id.btn:
showInfo();
break;
default:
break;
}
}
}
注释比较详细了
接下来是第二中情况:2 数据库中添加新的表
数据库升级的逻辑定义。。这点其实是数据库升级最重要的部分,我们在升级之前要定义好相应的升级逻辑,当我们在创建SQLiteOpenHelper类会传入不同的版本号,此刻我们更具这个version来做升级逻辑。。
例如我们的app已经有了两个版本V1.0,V1.2,现在我们在开发V1.3,那么我们对应的数据库版本号依次为18,19,20
对于这种情况,我们应该如何实现升级?
用户的选择有:
1) V1.0 -> V1.3 DB 18 -> 20
2) V1.1 -> V1.3 DB 19 -> 20
注意: 数据库每一个版本所代表的数据库必须是定义好的,比如说:V18数据库有两张表T1,T2,如果V19要添加一张表T3,V20要修改T3中的某些字段则逻辑是这样子的:
V18--> T1,T2
V19-->T1,T2,T3
V20-->T1,T2,T3(更新)
在onUpgrade()方法的实现如下:
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)
{
int upgradeVersion = oldVersion;
if (18 == upgradeVersion) {
// Create table T3
String sql = "CREATE TABLE ...";
db.execSQL(sql);
upgradeVersion = 1
}
if (20 == upgradeVersion) {
// Modify table T3
upgradeVersion = 20;
}
if (upgradeVersion != newVersion) {
// Drop tables
db.execSQL("DROP TABLE IF EXISTS " + tableName);
// Create tables
onCreate(db);
}
}
Android SqLite升级的更多相关文章
- android: SQLite升级数据库
如果你足够细心,一定会发现 MyDatabaseHelper 中还有一个空方法呢!没错,onUpgrade() 方法是用于对数据库进行升级的,它在整个数据库的管理工作当中起着非常重要的作用,可 千万不 ...
- Android——SQLite数据库(二)升级数据库、增、删、改、查、事务
xml <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android= ...
- Android Sqlite 数据库版本更新
Android Sqlite 数据库版本更新 http://87426628.blog.163.com/blog/static/6069361820131069485844/ 1.自己写一个类继承 ...
- 优雅的处理Android数据库升级的问题
原始完成于:2015-04-27 19:28:22 提供一种思路,优雅的处理Android数据库升级的问题,直接上代码: 1 package com.example.databaseissuetest ...
- Android SQLite 数据库详细介绍
Android SQLite 数据库详细介绍 我们在编写数据库应用软件时,需要考虑这样的问题:因为我们开发的软件可能会安装在很多用户的手机上,如果应用使用到了SQLite数据库,我们必须在用户初次使用 ...
- Android SQLite 数据库 增删改查操作
Android SQLite 数据库 增删改查操作 转载▼ 一.使用嵌入式关系型SQLite数据库存储数据 在Android平台上,集成了一个嵌入式关系型数据库--SQLite,SQLite3支持NU ...
- Android SQLite 简易指北
Android SQLite SQLite一款开源的, 轻量级的数据库. 以文本文件的形式存储数据. SQLite支持所有标准的关系型数据库特性. SQLite运行时占用内存非常少(约250 KByt ...
- 再读Android sqlite
再读Android sqlite Android原生支持sqlite数据库操作,sqlite时轻量级关系型数据库,支持标准sql语句.Android对sqlite进行良好的接口封装来避免sql注入等安 ...
- Android SQLite 通配符查询找不到参数问题
使用Android SQLite中SQLiteDatabase类的query方法查询时,如果where中包含通配符,则参数会无法设置,如类似下面的方法查询时 SQLiteDatabase db = d ...
随机推荐
- CSS的权重(转)
CSS写的渐渐多了,他的权重问题就不得不昂首面对,之前一直得过且过的将就用着,直到最近遇到了几个大坑,一直割刺着我对前端的热情,得了得了,蒙不过去了,就发点时间记下来吧,当然还是一片转载的文章,有时候 ...
- 异常处理:你不可能总是对的2 - 零基础入门学习Python033
异常处理:你不可能总是对的2 让编程改变世界 Change the world by program 我们已经了解足够多的可能碰到的异常,那我们这节课就来谈谈如何检测这些异常并处理它们. 异常检测我们 ...
- 手把手教你清除WIN7的C盘垃圾
WIN7系统用着用着C盘会变得越来越大,可用空间变得越来越小,磁盘清理,和安全卫士怎么清也清不出这些系统深度的垃圾.我们可以手动删除,释放C盘空间. 这样一清理下来,结果我的C盘就释放了近10个GB的 ...
- mysql/Java服务端对emoji的支持
更改好后的字符集: 乱码 推荐大家看 深入MySQL字符集设置 ,区分检查client端.server端的编码:最简单暴力的方式,是在所有的环节都显式明确的指定相同的编码. 比如使用python的My ...
- linux sed 使用
sed对文本的处理很强大,并且sed非常小,参数少,容易掌握,他的操作方式根awk有点像.sed按顺序逐行读取文件.然后,它执行为该行指定的所有操作,并在完成请求的修改之后的内容显示出来,也可以存放到 ...
- JS 实现 startWith endWith函数
String.prototype.startWith = function(s) { if (s == null || s == "" || this.length == 0 || ...
- Find Successor & Predecessor in BST
First, we use recursive way. Successor public class Solution { public TreeNode inorderSuccessor(Tree ...
- HDU4171--bfs+树
第一开始想成了DP.尼玛后来才发现只有N条边,那就简单了.. 从起点S遍历整棵树,从某点跳出来回到终点T,问最短路长度.然而从某点跳出时走过的路径是一个定值.... 长度为整棵树的边长和sum*2-d ...
- 基于Android的物理类游戏,源代码(JAVA)分享
游戏视频DEMO:http://v.youku.com/v_show/id_XNTM5MzM1Mzg0.html?from=s1.8-1-1.2 说明:一个自己做的Android上的物理类游戏,物理引 ...
- HDOJ-1016 Prime Ring Problem(DFS)
http://acm.hdu.edu.cn/showproblem.php?pid=1016 题意:输入n,代表有一个包含n个节点的环,在环中的节点中填入1,2...n-1,n,要求填入的数与左边的数 ...