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项目,会经常发生数据变化,所以我们就需要对数据库进行更新。
更新的思路:
当前版本 v1.0
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
升级数据库的话,就在那个onUpgrade()方法中进行,我们把之前定义version(版本号)改为2,再在 onUpgrade()方法中修改数据库
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 }
结果:
因为我的数据主键用的是自增长,没有对数据降级的表的数据插入数据进行考虑,所以直接把之前那个表个删了在建一个新的。