Android—SQLITE数据库的设计和升降级
Google为Andriod的较大的数据处理提供了SQLite,他在数据存储、管理、维护等各方面都相当出色,功能也非常的强大。SQLite具备下列特点:
1.轻量级
使用 SQLite 只需要带一个动态库,就可以享受它的全部功能,而且那个动态库的尺寸想当小。
2.独立性
SQLite 数据库的核心引擎不需要依赖第三方软件,也不需要所谓的“安装”。
3.隔离性
SQLite 数据库中所有的信息(比如表、视图、触发器等)都包含在一个文件夹内,方便管理和维护。
4.跨平台
SQLite 目前支持大部分操作系统,不至电脑操作系统更在众多的手机系统也是能够运行,比如:Android。
5.多语言接口
SQLite 数据库支持多语言编程接口。
6.安全性
SQLite 数据库通过数据库级上的独占性和共享锁来实现独立事务处理。这意味着多个进程可以在同一时间从同一数据库读取数据,但只能有一个可以写入数据。
创建数据库的方法,在android开发中,要想为项目创建数据库,必须继承SQLiteOpenHelper类
首先,我们创建一个类来继承SQLiteOpenHelper类
1 package com.example.sqlltetest;
2
3 import android.content.Context;
4 import android.database.DatabaseErrorHandler;
5 import android.database.sqlite.SQLiteDatabase;
6 import android.database.sqlite.SQLiteDatabase.CursorFactory;
7 import android.database.sqlite.SQLiteOpenHelper;
8 import android.util.Log;
9
10 public class MyDataBaseOpenOrCreate extends SQLiteOpenHelper{
11
12 private static final String DB_NAME = "mydata.db"; // 数据库名称
13 private static final int version = 1; // 数据库版本
14
15
16
17 public MyDataBaseOpenOrCreate(Context context) {
18 super(context, DB_NAME, null, version);
19 }
20
21 @Override
22 public void onCreate(SQLiteDatabase db) {
23 Log.i("tag", "欢迎你的加入");
24 String sql_table = "create table t_student(stuid integer primary key autoincrement,stuName varchar(50))";
25 db.execSQL(sql_table);
26 String sql_1 = "insert into t_student(stuName) values ('小波')";
27 String sql_2 = "insert into t_student(stuName) values ('小小波')";
28 String sql_3 = "insert into t_student(stuName) values ('小小小波')";
29 db.execSQL(sql_1);
30 db.execSQL(sql_2);
31 db.execSQL(sql_3);
32 }
33
34 @Override
35 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newversion) {
36
37 }
38
39 }
如过你的项目没有数据库的化,他会走onCreate()的方法,如果有的话,他是不会走onCreate()方法的,至于onUpgrade()方法,是当你数据库发生更新时触发的,上面我们通过日志打印来测试
那么我们创建一个实体类来关联数据库
1 package com.example.entity;
2
3 public class student {
4
5 private String stuid;
6 private String stuName;
7 private int age;//为了升级做准备的
8 public String getStuid() {
9 return stuid;
10 }
11 public void setStuid(String stuid) {
12 this.stuid = stuid;
13 }
14 public String getStuName() {
15 return stuName;
16 }
17 public void setStuName(String stuName) {
18 this.stuName = stuName;
19 }
20 public int getAge() {
21 return age;
22 }
23 public void setAge(int age) {
24 this.age = age;
25 }
26
27 }
后面我们直接通过程序来显示数据
1 package com.example.sqlltetest;
2
3 import java.util.*;
4
5 import com.example.entity.student;
6
7 import android.app.Activity;
8 import android.database.Cursor;
9 import android.database.sqlite.SQLiteDatabase;
10 import android.os.Bundle;
11 import android.util.Log;
12 import android.view.LayoutInflater;
13 import android.view.View;
14 import android.view.ViewGroup;
15 import android.widget.BaseAdapter;
16 import android.widget.ListView;
17 import android.widget.TextView;
18
19 public class MainActivity extends Activity {
20
21 private ListView lv;
22 private List<student> list = new ArrayList<student>();
23
24 @Override
25 protected void onCreate(Bundle savedInstanceState) {
26 super.onCreate(savedInstanceState);
27 setContentView(R.layout.activity_main);
28
29 MyDataBaseOpenOrCreate myDataBase = new MyDataBaseOpenOrCreate(
30 MainActivity.this);
31 SQLiteDatabase db = myDataBase.getWritableDatabase();
32 Log.i("tag", "创建数据库完成");
33 Cursor cursor = db.query("t_student", null, null, null, null, null,
34 null);
35 while (cursor.moveToNext()) {
36 student s = new student();
37 s.setStuName(cursor.getString(cursor.getColumnIndex("stuName")));
38
39 list.add(s);
40 }
41 db.close();
42 lv = (ListView) findViewById(R.id.listView1);
43 lv.setAdapter(new BaseAdapter() {
44
45 // 返回多少条记录
46 @Override
47 public int getCount() {
48 // TODO Auto-generated method stub
49 return list.size();
50 }
51
52 // 每一个item项,返回一次界面
53 @Override
54 public View getView(int position, View convertView, ViewGroup parent) {
55 View view = null;
56
57
58 LayoutInflater inflater = MainActivity.this.getLayoutInflater();
59 // 因为getView()返回的对象,adapter会自动赋给ListView
60 view = inflater.inflate(R.layout.list_item, null);
61
62 student m = list.get(position);
63
64 TextView tv_stuName = (TextView) view
65 .findViewById(R.id.tv_stuName);
66 tv_stuName.setText(m.getStuName());
67
68
69 return view;
70 }
71
72 @Override
73 public Object getItem(int position) {
74 // TODO Auto-generated method stub
75 return null;
76 }
77
78 @Override
79 public long getItemId(int position) {
80 // TODO Auto-generated method stub
81 return 0;
82 }
83
84 });
85 }
86
87 }
显示的结果:
当我们第一次运行的时候,在日志中可以看到之前oncreate()方法中日志
但是当我们在重新运行一次的时候,日志是这样的
由此可见,只有我们数据库没有这个数据库的时候他才会走oncreate()方法。
因为我们创建的是app项目,会经常发生数据变化,所以我们就需要对数据库进行更新。
更新的思路:
1. 没有安装过 会直接 走 onCreate()
--------------------------------------
当前版本 v2.0 [onUpgrade 情况:n-1,onCreate 情况:1] 升级就会直接走 onUpgrade() 方法
1. v1.0 --> v2.0 onUpgrade
2. 没有安装过 onCreate()
-----------------------------------------
当前版本 v3.0 [onUpgrade 情况:n-1,onCreate 情况:1]
1. v1.0 -->v3.0 onUpgrade
alter table t_message add column isdel bit default 0;
插入数据
2. v2.0 -->v3.0 onUpgrade
alter table t_message add column isdel bit default 0;
3. 没有安装过 onCreate()
1、考虑云端要保存用户【自定义数据、行为习惯】。专业术语profile-->>提高用户黏度
2、考虑[当前]的最低版本要求-->>降低维护成本
3、尽可能本地的数据转移(所有新版本,都不删除字段)-->尽可能把未知变已知
try catch
1 package com.example.sqlltetest;
2
3 import android.content.Context;
4 import android.database.DatabaseErrorHandler;
5 import android.database.sqlite.SQLiteDatabase;
6 import android.database.sqlite.SQLiteDatabase.CursorFactory;
7 import android.database.sqlite.SQLiteOpenHelper;
8 import android.util.Log;
9
10 public class MyDataBaseOpenOrCreate extends SQLiteOpenHelper{
11
12 private static final String DB_NAME = "mydata.db"; // 数据库名称
13 private static final int version = 2; // 数据库版本
14
15
16
17 public MyDataBaseOpenOrCreate(Context context) {
18 super(context, DB_NAME, null, version);
19 }
20
21 @Override
22 public void onCreate(SQLiteDatabase db) {
23 Log.i("tag", "欢迎你的加入");
24 String sql_table = "create table t_student(stuid integer primary key autoincrement,stuName varchar(50))";
25 db.execSQL(sql_table);
26 String sql_1 = "insert into t_student(stuName) values ('小波')";
27 String sql_2 = "insert into t_student(stuName) values ('小小波')";
28 String sql_3 = "insert into t_student(stuName) values ('小小小波')";
29 db.execSQL(sql_1);
30 db.execSQL(sql_2);
31 db.execSQL(sql_3);
32 }
33
34 @Override
35 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newversion) {
36 if (oldVersion == 1){
37 String sql_upgrade_1 = "alter table t_student add column age int default 18";
38 db.execSQL(sql_upgrade_1);
39 Log.i("db", "从1到2,升级成功!");
40 }
41
42 }
43
44
45 }
当然数据的改变,我们的显示也要跟着改变,我们对之前的MainActivity进行修改
1 package com.example.sqlltetest;
2
3 import java.util.*;
4
5 import com.example.entity.student;
6
7 import android.app.Activity;
8 import android.database.Cursor;
9 import android.database.sqlite.SQLiteDatabase;
10 import android.os.Bundle;
11 import android.util.Log;
12 import android.view.LayoutInflater;
13 import android.view.View;
14 import android.view.ViewGroup;
15 import android.widget.BaseAdapter;
16 import android.widget.ListView;
17 import android.widget.TextView;
18
19 public class MainActivity extends Activity {
20
21 private ListView lv;
22 private List<student> list = new ArrayList<student>();
23
24 @Override
25 protected void onCreate(Bundle savedInstanceState) {
26 super.onCreate(savedInstanceState);
27 setContentView(R.layout.activity_main);
28
29 MyDataBaseOpenOrCreate myDataBase = new MyDataBaseOpenOrCreate(
30 MainActivity.this);
31 SQLiteDatabase db = myDataBase.getWritableDatabase();
32 Log.i("tag", "创建数据库完成");
33 Cursor cursor = db.query("t_student", null, null, null, null, null,
34 null);
35 while (cursor.moveToNext()) {
36 student s = new student();
37 s.setStuName(cursor.getString(cursor.getColumnIndex("stuName")));
38 s.setAge(cursor.getInt(cursor.getColumnIndex("age")));
39 list.add(s);
40 }
41 db.close();
42 lv = (ListView) findViewById(R.id.listView1);
43 lv.setAdapter(new BaseAdapter() {
44
45 // 返回多少条记录
46 @Override
47 public int getCount() {
48 // TODO Auto-generated method stub
49 return list.size();
50 }
51
52 // 每一个item项,返回一次界面
53 @Override
54 public View getView(int position, View convertView, ViewGroup parent) {
55 View view = null;
56
57 // 布局不变,数据变
58
59 // 如果缓存为空,我们生成新的布局作为1个item
60 LayoutInflater inflater = MainActivity.this.getLayoutInflater();
61 // 因为getView()返回的对象,adapter会自动赋给ListView
62 view = inflater.inflate(R.layout.list_item, null);
63
64 student m = list.get(position);
65
66 TextView tv_stuName = (TextView) view
67 .findViewById(R.id.tv_stuName);
68 tv_stuName.setText(m.getStuName());
69
70 TextView tv_Age = (TextView) view.findViewById(R.id.tv_age);
71 tv_Age.setText(m.getAge() + "");
72
73 return view;
74 }
75
76 @Override
77 public Object getItem(int position) {
78 // TODO Auto-generated method stub
79 return null;
80 }
81
82 @Override
83 public long getItemId(int position) {
84 // TODO Auto-generated method stub
85 return 0;
86 }
87
88 });
89 }
90
91 }
下面我们看一下日志和结果:
好了,我们的数据库升级成功了,接着我们来尝试一下降级吧,
我们先把version(版本好)换成1
package com.example.sqlltetest; import android.content.Context;
import android.database.DatabaseErrorHandler;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log; public class MyDataBaseOpenOrCreate extends SQLiteOpenHelper{ private static final String DB_NAME = "mydata.db"; // 数据库名称
private static final int version = 1; // 数据库版本 public MyDataBaseOpenOrCreate(Context context) {
super(context, DB_NAME, null, version);
} @Override
public void onCreate(SQLiteDatabase db) {
Log.i("tag", "欢迎你的加入");
String sql_table = "create table t_student(stuid integer primary key autoincrement,stuName varchar(50))";
db.execSQL(sql_table);
String sql_1 = "insert into t_student(stuName) values ('小波')";
String sql_2 = "insert into t_student(stuName) values ('小小波')";
String sql_3 = "insert into t_student(stuName) values ('小小小波')";
db.execSQL(sql_1);
db.execSQL(sql_2);
db.execSQL(sql_3);
} @Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newversion) {
if (oldVersion == 1){
String sql_upgrade_1 = "alter table t_student add column age int default 18";
db.execSQL(sql_upgrade_1);
Log.i("db", "从1到2,升级成功!");
} } @Override
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
try {
//第一、先把t_message 未来的表,改名
String rename_sql = "alter table t_student rename to t_student_bak";
db.execSQL(rename_sql);
Log.i("down", "1.改名成功");
//第二、建立降级的表名的表结构
String sql_message = "create table t_student(stuid integer primary key autoincrement,stuName varchar(50))";
db.execSQL(sql_message);
Log.i("down", "2.建立2.0表结构成功");
//第三、把备份的数据,copy到 新建的2.0的表(即将之前表名的数据插入到降级的版本中)
String sql_copy = "insert into t_student select stuName from t_student_bak";
db.execSQL(sql_copy);
Log.i("down", "3.copy到用户数据到 2.0的表");
//第四、把备份表drop掉
String drop_sql = "drop table if exists t_student_bak";
db.execSQL(drop_sql);
Log.i("down", "4.把备份表drop掉"); } catch (Exception e) {
//如果上面的方法不行,采取最暴力的行为,把表删了,重新建立一张之前版本的表
Log.i("hi", "降级失败,重新建立");
String sql_drop_old_table = "drop table if exists t_student";
String sql_message = "create table t_student(stuid integer primary key autoincrement,stuName varchar(50))";
String sql_init_1 = "insert into t_student(stuName) values ('小波')";
String sql_init_2 = "insert into t_student(stuName) values ('小明')";
String sql_init_3 = "insert into t_student(stuName) values ('小红')";
db.execSQL(sql_drop_old_table);
db.execSQL(sql_message);
db.execSQL(sql_init_1);
db.execSQL(sql_init_2);
db.execSQL(sql_init_3);
}
} }
1 package com.example.sqlltetest;
2
3 import java.util.*;
4
5 import com.example.entity.student;
6
7 import android.app.Activity;
8 import android.database.Cursor;
9 import android.database.sqlite.SQLiteDatabase;
10 import android.os.Bundle;
11 import android.util.Log;
12 import android.view.LayoutInflater;
13 import android.view.View;
14 import android.view.ViewGroup;
15 import android.widget.BaseAdapter;
16 import android.widget.ListView;
17 import android.widget.TextView;
18
19 public class MainActivity extends Activity {
20
21 private ListView lv;
22 private List<student> list = new ArrayList<student>();
23
24 @Override
25 protected void onCreate(Bundle savedInstanceState) {
26 super.onCreate(savedInstanceState);
27 setContentView(R.layout.activity_main);
28
29 MyDataBaseOpenOrCreate myDataBase = new MyDataBaseOpenOrCreate(
30 MainActivity.this);
31 SQLiteDatabase db = myDataBase.getWritableDatabase();
32 Log.i("tag", "创建数据库完成");
33 Cursor cursor = db.query("t_student", null, null, null, null, null,
34 null);
35 while (cursor.moveToNext()) {
36 student s = new student();
37 s.setStuName(cursor.getString(cursor.getColumnIndex("stuName")));
38 //s.setAge(cursor.getInt(cursor.getColumnIndex("age")));
39 list.add(s);
40 }
41 db.close();
42 lv = (ListView) findViewById(R.id.listView1);
43 lv.setAdapter(new BaseAdapter() {
44
45 // 返回多少条记录
46 @Override
47 public int getCount() {
48 // TODO Auto-generated method stub
49 return list.size();
50 }
51
52 // 每一个item项,返回一次界面
53 @Override
54 public View getView(int position, View convertView, ViewGroup parent) {
55 View view = null;
56
57 // 布局不变,数据变
58
59 // 如果缓存为空,我们生成新的布局作为1个item
60 LayoutInflater inflater = MainActivity.this.getLayoutInflater();
61 // 因为getView()返回的对象,adapter会自动赋给ListView
62 view = inflater.inflate(R.layout.list_item, null);
63
64 student m = list.get(position);
65
66 TextView tv_stuName = (TextView) view
67 .findViewById(R.id.tv_stuName);
68 tv_stuName.setText(m.getStuName());
69
70 /*TextView tv_Age = (TextView) view.findViewById(R.id.tv_age);
71 tv_Age.setText(m.getAge() + "");*/
72
73 return view;
74 }
75
76 @Override
77 public Object getItem(int position) {
78 // TODO Auto-generated method stub
79 return null;
80 }
81
82 @Override
83 public long getItemId(int position) {
84 // TODO Auto-generated method stub
85 return 0;
86 }
87
88 });
89 }
90
91 }
结果:
因为我的数据主键用的是自增长,没有对数据降级的表的数据插入数据进行考虑,所以直接把之前那个表个删了在建一个新的。
Android—SQLITE数据库的设计和升降级的更多相关文章
- Android菜鸟成长记11 -- sqlite数据库的设计和升降级
Google为Andriod的较大的数据处理提供了SQLite,他在数据存储.管理.维护等各方面都相当出色,功能也非常的强大.SQLite具备下列特点: 1.轻量级 使用 SQLite 只需要带一个动 ...
- Android Sqlite 数据库版本更新
Android Sqlite 数据库版本更新 http://87426628.blog.163.com/blog/static/6069361820131069485844/ 1.自己写一个类继承 ...
- Android SQLite 数据库详细介绍
Android SQLite 数据库详细介绍 我们在编写数据库应用软件时,需要考虑这样的问题:因为我们开发的软件可能会安装在很多用户的手机上,如果应用使用到了SQLite数据库,我们必须在用户初次使用 ...
- Android sqlite数据库存取图片信息
Android sqlite数据库存取图片信息 存储图片:bitmap private byte[] getIconData(Bitmap bitmap){ int size = bitmap.get ...
- Android SQLite 数据库 增删改查操作
Android SQLite 数据库 增删改查操作 转载▼ 一.使用嵌入式关系型SQLite数据库存储数据 在Android平台上,集成了一个嵌入式关系型数据库--SQLite,SQLite3支持NU ...
- 图解IntelliJ IDEA 13版本对Android SQLite数据库的支持
IntelliJ IDEA 13版本的重要构建之一是支持Android程序开发.当然对Android SQLite数据库的支持也就成为了Android开发者对IntelliJ IDEA 13版本的绝对 ...
- Android——SQLite/数据库 相关知识总结贴
android SQLite简介 http://www.apkbus.com/android-1780-1-1.html Android SQLite基础 http://www.apkbus.com/ ...
- Android Sqlite数据库加密
Android使用的是开源的SQLite数据库,数据库本身没有加密,加密思路通常有两个: 1. 对几个关键的字段使用加密算法,再存入数据库 2. 对整个数据库进行加密 SQLite数据库加密工具: 收 ...
- Android SQLite数据库使用
在Android开发中SQLite起着很重要的作用,网上SQLite的教程有很多很多,不过那些教程大多数都讲得不是很全面.本人总结了一些SQLite的常用的方法,借着论坛的大赛,跟大家分享分享的.一. ...
随机推荐
- andriod手机签到应用服务器设计
最近导师要求我和另一个同学开发一个手机上课签到应用,我负责客户端和服务器之间的通信架构编写和数据的存储 本人大学四年只用过汇编和C/C++,因此对andriod开发还是一窍不通,花了一个星期写出来了基 ...
- Android自定义之TextView跑马灯的监听
TextView都有跑马灯的效果,如果说让你去监听跑马灯效果的执行,我觉得这个需求有点二了,但是也要实现. 思路: 1.自定义View 继承TextView 这种方法过于麻烦,只是监听一个跑马灯 ...
- Configuring Service Broker for Asynchronous Processing
Configuring Service Broker for Asynchronous Processing --create a database and enable the database f ...
- Linux下修改PATH路径
1.#PATH=$PATH:/opt/lamp/mysql/bin 使用这种方法,只对当前会话有效,也就是说每当登出或注销系统以后,PATH 设置就会失效 2.#vi /etc/profi ...
- Use the PDFs below or the HTML contents to the left to install and configure P6 EPPM and its additional components.
Welcome to Your Documentation Use the PDFs below or the HTML contents to the left to install and c ...
- SQLServer获取临时表所有列名或是否存在指定列名的方法
获取临时表中所有列名 select name from tempdb.dbo.syscolumns where id=object_id( '#TempTB') 判断临时表中是否存在指定列名 if c ...
- [持续更新] 文章列表 last updated SEP 18, 2016
1.前端 HTML5快速学习二 Canvas@20141125 HTML5快速学习一@20141122 2.ASP.NET(MVC) MVC5+EF6 入门完整教程14--动态生成面包屑@201608 ...
- 【C#进阶系列】04 类型基础
关于System.Object 所有类型都从System.Object派生而来. System.Object的公共方法中ToString()一般是返回对象的类型的全名,只有Int32这些类型将其重写后 ...
- CMS如何提供XML格式的接口
在做APP的过程中,需要服务端的接口数据. 是用Json格式还是Xml格式呢,很多人会说还是xml习惯. 然而PHP更适合返回的还是json,php核心库中就包含了json编码的函数,可以直接将数组转 ...
- Java内存泄露的原因
Java内存泄露的原因 1.静态集合类像HashMap.Vector等的使用最容易出现内存泄露,这些静态变量的生命周期和应用程序一致,所有的对象Object也不能被释放,因为他们也将一直被Vector ...