一、数据库的创建

1.文件的创建

     //引用,如果文件不存在是不会创建的

  File  file = new File("haha.txt");

    //输出流写数据,文件才会被创建

  FileOutputStream  fos = new FileOutputStream(file);

  fos.write("".getBytes());

  fos.close();

2.数据库的创建

//执行下面这一点代码,数据库是不会被创建出来的。相当于File file = new File("one.txt");(文件one.txt也没有创建出来)

        MyDBOpenHelper helper = new MyDBOpenHelper(this);

//如果要想创建数据库就必须执行下面的代码

       helper.getWritableDatabase();

创建文件我们需要一个File类,创建数据库我们也需要一个特殊的类SQLiteOpenHelper(抽象类)

(1)我创建一个新的Android工程如下:

(2)我们找到SQLiteOpenHelper,发现这是一个抽象类,所以我们必须自定义一个SQLiteOpenHelper的子类实现类:MyDBOpenHelper

代码如下:

 package com.himi.sqlite;

 import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper; public class MyDBOpenHelper extends SQLiteOpenHelper { public MyDBOpenHelper(Context context, String name, CursorFactory factory,
int version) {
super(context, name, factory, version);
// TODO 自动生成的构造函数存根
} @Override
public void onCreate(SQLiteDatabase db) {
// TODO 自动生成的方法存根 } @Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO 自动生成的方法存根 } }

这里我们发现这个构造方法参数很多,很晕,这个我们慢慢仔细看看这个构造函数,如下:

public MyDBOpenHelper(Context context, String name, CursorFactory factory,int version)

 context:上下文,用来打开或者创建数据库

  name:数据库文件的名称

  factory:用来创建游标对象,null就是使用默认的游标工厂

这个游标是什么概念?不懂啊?没事我们这里就说明一下这个概念,要知道这个概念必然是解决问题思路抽取出来的,为解决问题而服务,只是我们不知道这个内在解决问题的思路,才会这样迷糊,没事,很快就好了。

下面这个逻辑图就会让你明白:

version:从数字1开始的一个版本号,用来数据库更新使用

(3)上面已经知道构造函数的4个参数,一次性传入4个参数(context, name, factory, version)太过繁琐,这里修改只传入context。

package com.himi.sqlite;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper; /**
* 相当于File类
* @author Administrator
*
*/
public class MyDBOpenHelper extends SQLiteOpenHelper { public MyDBOpenHelper(Context context) {
super(context, "Juck.db", null, 1);
// TODO 自动生成的构造函数存根
} @Override
public void onCreate(SQLiteDatabase db) {
// TODO 自动生成的方法存根 } @Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO 自动生成的方法存根 } }

这时候我们已经创建出来了数据库工具类MyDBOpenHelper,接下来我们就可以在MainActivity中创建数据库,代码如下:

package com.himi.sqlite;

import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem; public class MainActivity extends Activity { @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main); //执行下面这一点代码,数据库是不会被创建出来的。相当于File file = new File("one.txt");(文件one.txt也没有创建出来)
MyDBOpenHelper helper = new MyDBOpenHelper(this);
//如果要想创建数据库就必须执行下面的代码
helper.getWritableDatabase();
} }

程序运行到手机上,我们在/data/data/com.himi.sqlite/databases目录下查找已经创建的数据库Juck.db,如下:

二、数据库的表创建

    1.之前的MyDBOpenHelper继承SQLiteOpenHelper实现的抽象方法onCreate(), 数据库第一次创建的时候调用,如果数据库已经创建,就不会执行这个onCreate()方法,在onCreate()方法中我们往往执行创建表的操作:create table

    public void onCreate(SQLiteDatabase db)

  2.当数据库的版本需要更新的时候调用的方法:

    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)  

  这里我们知道我们在刚刚利用构造函数创建数据库的时候:

public MyDBOpenHelper(Context context) {
super(context, "itheima.db", null, 1);
}

这里的默认数据库的版本号为version = 1,当我们修改版本号为version = 2,也就是说构造方法修改为如下:

public MyDBOpenHelper(Context context) {
super(context, "itheima.db", null, 2);
}

这就是说明数据库的版本由1升级到2,这样的话就会调用onUpgrade方法,顺便说一句数据库版本号只能升级,不能降级

比如:起初我们创建的数据库版本为version = 1,如下代码:

package com.himi.sqlite;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper; /**
* 相当于File类
* @author Administrator
*
*/
public class MyDBOpenHelper extends SQLiteOpenHelper { public MyDBOpenHelper(Context context) {
super(context, "Juck.db", null, 1);
// TODO 自动生成的构造函数存根
} /**
* 数据库第一次创建的时候调用,如果数据库已经创建,就不会执行这段代码
* @param db 代表的就是我们创建出来的数据库
*/
@Override
public void onCreate(SQLiteDatabase db) {
//创建表
db.execSQL("create table info (_id integer primary key autoincrement, name varchar(20), phone varchar(20))"); } @Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO 自动生成的方法存根 } }

当我们想添加数据库info一个字段为money varchar(10),代码如下:

package com.himi.sqlite;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper; /**
* 相当于File类
* @author Administrator
*
*/
public class MyDBOpenHelper extends SQLiteOpenHelper { public MyDBOpenHelper(Context context) {
super(context, "Juck.db", null, 2); // 为了满足升级的需求,这里已经修改了版本号,由1修改为2
// TODO 自动生成的构造函数存根
} /**
* 数据库第一次创建的时候调用,如果数据库已经创建,就不会执行这段代码
* @param db 代表的就是我们创建出来的数据库
*/
@Override
public void onCreate(SQLiteDatabase db) {
//创建表
db.execSQL("create table info (_id integer primary key autoincrement, name varchar(20), phone varchar(20))"); } @Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("alter table info add money varchar(10)"); //上面修改了版本号,这里就会调用onUpgrade()方法,从而实现添加money字段 } }

三、这样的话,完整的数据库创建和使用的代码我们也将完成了,如下:

MainActivity.java:

 package com.itheima.dbcreate;

 import android.os.Bundle;
import android.app.Activity;
import android.view.Menu; public class MainActivity extends Activity { @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//执行下面的一行代码,数据库是不会别创建的了。
MyDBOpenHelper helper = new MyDBOpenHelper(this);
//如果想创建数据库必须执行,下一行代码
helper.getWritableDatabase();
} }

而且MyDBOpenHelper.java:

 package com.itheima.dbcreate;

 import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteOpenHelper; /**
* 相当于File类
* @author Administrator
*
*/
public class MyDBOpenHelper extends SQLiteOpenHelper { /**
* @param context 上下文
* @param name 数据库文件的名称
* @param factory 用来创建游标对象, null就用默认的游标工厂
* @param version 数据库的版本号 从1开始
*/
public MyDBOpenHelper(Context context) {
super(context, "itheima.db", null, 1);
} /**
* 数据库第一次被创建的时候调用,如果数据库已经创建,就不会执行这一句代码
* @param db 代表的就是我们创建出来的数据库
*/
@Override
public void onCreate(SQLiteDatabase db) {
System.out.println("哈哈哈,数据库被创建了。适合初始化数据库的表结构");
//创建表
db.execSQL("create table info (_id integer primary key autoincrement, name varchar(20), phone varchar(20)) ");
}
/**
* 当数据库的版本需要更新的时候调用的方法
*/
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
System.out.println("onupgrade 数据库被升级啦 。哈哈哈,适合修改数据库的表结构");
//db.execSQL("alter table info add money varchar(10)"); }
}

四、特别说明:

首先我们通过一张图引出一个问题,如下:

有时候我们会经常处理数据库,这样的话就会出现很多版本的数据库。不同版本的数据库之间如果要升级,必须要做onUpgrade()方法中执行,比如

上面图中:数据库版本1------>数据库版本2,这里只需要在构造方法中修改版本号为2,同时在 onUpgrade()方法中添加字段money即可;同样的道理,数据库版本2------>数据库版本3,这里只需要在构造方法中修改版本号为3,同时在 onUpgrade()方法中添加字段age即可

相信你已经感觉到了,就是我们数据库升级的时候要考虑自己现在的版本(oldVersion)  以及我们要升级的版本(newVersion

所以这里我们要说一下这里:public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)

将来我们去上班的时候,你会发现有的项目做了很久,DBSQLiteHelper中的 onUpgrade()方法代码很复杂,可能都有好几百行,甚至要上千行,如下:

@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
System.out.println("onupgrade 数据库被升级啦 。哈哈哈,适合修改数据库的表结构");
for (int j = oldVersion; j <= newVersion; j++){
switch(j) {
case 1:
........
break;
case 2:
........
break;
case 3:
........
break;
case 4:
........
break;
case 5:
........
break; .
.
. }
}
}

为什么要在方法里写for循环,主要是考虑到夸数据库版本升级,比如有的用户一直不升级版本,数据库版本号一直是1,而客户端最新版本其实对应的数据库版本已经是4了,那么我中途可能对数据库做了很多修改,通过这个for循环,可以迭代升级,不会发生错误。

你会发现onUpgrade()方法中,有很多类似switch……case……  或者 if……else;这些都是因为我们升级项目的时候,更新数据库,这样就会出现很多版本的数据库,用户在升级数据库的时候,这里会根据用户现在的数据库版本oldVersion,执行相应的操作升级到现在数据库版本newVersion。

这样的话,用户升级软件的时候就不会清除你之前的数据,比如升级游戏的时候,之前的游戏登录账号和密码就还会记住,就不会要求用户重新输入,这样的用户体验是很好的

但是往往有些垄断行业,升级软件就不会有这一大堆switch这样的判断,就会出现升级软件账号和密码要重新输入,就是因为它清空我们之前的数据库内容,但是这样的用户体验是很不好的,这只有垄断行业才会采用的,比如QQ升级。

Android(java)学习笔记135:SQLite数据库(表)的创建 以及 SQLite数据库的升级的更多相关文章

  1. SQL学习笔记:库和表的创建

    目录 创建和删除数据库 创建和删除表 添加.修改和删除字段 创建和删除数据库 CREATE DATABASE justForLearn; DROP DATABASE justForLearn; 创建和 ...

  2. 【JAVAWEB学习笔记】09_MySQL多表&JDBC(包含MySQL数据库思维导图)

    今天晨读单词: order:订单constraint:(强制)约束foreign key:外键references:指向orderitem:订单项join:加入resourceBundle:资源捆绑c ...

  3. jquery-mobile 学习笔记之二(表单创建)

    绪上 一.注意事项 1. <form> 元素必须设置 method 和 action 属性 2. 每一个表单元素必须设置唯一的 "id" 属性. 该 id 在网站的页面 ...

  4. Android:日常学习笔记(10)———使用LitePal操作数据库

    Android:日常学习笔记(10)———使用LitePal操作数据库 引入LitePal 什么是LitePal LitePal是一款开源的Android数据库框架,采用了对象关系映射(ORM)的模式 ...

  5. 《Java学习笔记(第8版)》学习指导

    <Java学习笔记(第8版)>学习指导 目录 图书简况 学习指导 第一章 Java平台概论 第二章 从JDK到IDE 第三章 基础语法 第四章 认识对象 第五章 对象封装 第六章 继承与多 ...

  6. Android:日常学习笔记(9)———探究持久化技术

    Android:日常学习笔记(9)———探究持久化技术 引入持久化技术 什么是持久化技术 持久化技术就是指将那些内存中的瞬时数据保存到存储设备中,保证即使在手机或电脑关机的情况下,这些数据仍然不会丢失 ...

  7. 20145330第九周《Java学习笔记》

    20145330第九周<Java学习笔记> 第十六章 整合数据库 JDBC入门 数据库本身是个独立运行的应用程序 撰写应用程序是利用通信协议对数据库进行指令交换,以进行数据的增删查找 JD ...

  8. Java学习笔记4

    Java学习笔记4 1. JDK.JRE和JVM分别是什么,区别是什么? 答: ①.JDK 是整个Java的核心,包括了Java运行环境.Java工具和Java基础类库. ②.JRE(Java Run ...

  9. Java学习笔记31(IO:Properties类)

    Properties类,表示一个持久的j集,可以存在流中,或者从流中加载 是Hashtable的子类 map集合的方法都能用 用途之一:在开发项目中,我们最后交给客户的是一个编译过的class文件,客 ...

  10. 20155234 2610-2017-2第九周《Java学习笔记》学习总结

    20155234第九周<Java学习笔记>学习总结 教材学习内容总结 数据库本身是个独立运行的应用程序 撰写应用程序是利用通信协议对数据库进行指令交换,以进行数据的增删查找 JDBC(Ja ...

随机推荐

  1. Django 中得ORM介绍和字段及字段参数

    ORM 介绍 ORM概念 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术. 简单的说 ORM 是通过使用 ...

  2. EIP权限工作流升级说明-2019/5/23

    增加mysql版本在线预览地址:http://www.eipflow.com:3000/

  3. ASP.NET Core 3.0 自动挡换手动挡:在 Middleware 中执行 Controller Action

    最近由于发现奇怪的 System.Data.SqlClient 性能问题(详见之前的博文),被迫提前了向 .NET Core 3.0 的升级工作(3.0 Preview 5 中问题已被修复).郁闷的是 ...

  4. NLP入门(十)使用LSTM进行文本情感分析

    情感分析简介   文本情感分析(Sentiment Analysis)是自然语言处理(NLP)方法中常见的应用,也是一个有趣的基本任务,尤其是以提炼文本情绪内容为目的的分类.它是对带有情感色彩的主观性 ...

  5. 洛谷P1368 均分纸牌(加强版)

    P1368 均分纸牌(加强版) 题目描述 有 N 堆纸牌,编号分别为 1,2,…, N.每堆上有若干张,纸牌总数必为 N 的倍数.可以在任一堆上取1张纸牌,然后移动. 移牌规则为:在编号为 1 堆上取 ...

  6. 洛谷P2257 YY的GCD(莫比乌斯反演)

    传送门 原来……莫比乌斯反演是这么用的啊……(虽然仍然不是很明白) 首先,题目所求如下$$\sum_{i=1}^n\sum_{j=1}^m[gcd(i,j)=prim]$$ 我们设$f(d)$表示$g ...

  7. Node.js 内置模块crypto加密模块(2) AES

    AES:高级加密标准 ( Advanced Encryption Standard ) AES是一种对称加密算法:加密需要密钥,且加密密钥和解密密钥相同 下面是AES加密的Node实现: " ...

  8. go系列(6)- beego日志模块的使用

    1.安装日志模块 切换到工作目录,下载日志模块 cd /data/work/go/ go get github.com/astaxie/beego/logs 2.导入日志模块 使用的时候,需要导入模块 ...

  9. 2017swpu-ctf总结

    2017swpu-ctf总结 今年是我第一次出题感受很多,就分析几道我印象最深刻的题吧 你能进入后台吗? 这道题主要是考察php_screw还有md5加密开启true过后的注入 phpscrew加密在 ...

  10. CentOS,net core2 sdk nginx、supervisor、mysql

    CentOS下 .net core2 sdk nginx.supervisor.mysql环境搭建 作为.neter,看到.net core 2.0的正式发布,心里是有点小激动的,迫不及待的体验了一把 ...