10分钟理解Android数据库的创建与使用(附具体解释和演示样例代码)

1.Android数据库简单介绍.

Android系统的framework层集成了Sqlite3数据库。我们知道Sqlite3是一种轻量级的高效存储的数据库。

Sqlite数据库具有以下长处:

(1)零配置,无需安装和配置;

(2)储存在单一磁盘文件里的一个完整的数据库。

(3)数据库文件能够在不同字节顺序的机器间自由共享;

(4)支持数据大小至2TB;

(5)足够小。全部源码大致3万行C代码。250KB;

(6)比眼下流行的大多数数据库的操作要快。

(7)开源。

2.Sqlite 基本操作语句和重要概念

(1)创建数据库

创建数据库实际上并不是通过SQL语句来创建。创建数据库能够通过sqlite3 新数据库名 来创建,比方创建一个名为school.db的数据库,在命令行下输入“sqlite3 school.db;”就可以。

(2)创建表

创建表的SQL语法为:

create table 表名(字段1 数据约束类型,…,字段n 数据约束类型)。

注意:每一条SQL语句都以分号结尾

Sqlite数据库支持的数据库类型大致分为5种。各自是:

NUll 数据值为空

INTEGER 整型

REAL 浮点型数据

TEXT 字符类型,使用数据库编码(UTF-8等)存放

BLOB 仅仅是一个数据块,全然依照输入存放

注意:SQLite3数据库中不论什么列,除了整形主键列,能够用于存储不论什么一个存储列的值,SQLite没有单独的布尔存储类型,你能够使用INTEGER的0和1表示true和false,另外。SQLite也没有代表时间和日期的数据类型。能够转化为TEXT或者INTEGER来存储

经常使用的数据库约束包括以下几种:

PRIMARY KEY 主键 它是非空且唯一的

NOT NULL 非空

UNIQUE 唯一

FOREIGN KEY 外键

CHECK 条件检查

DEFAULT 字段的默认值

以下举例说明创建一个班级表,表中有3个字段,各自是自增的主键id、专业、年份。

创建表的SQL语句例如以下图所看到的

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGl1eHU4NDE5MTE1NDg=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="创建表" title="">

(3)插入数据

SQL语句插入数据的关键字为insert。完整的格式例如以下图所看到的

比如在classes表中插入一条数据,这里我仅仅插入了一条数据中的2个字段,写法例如以下图

注意:插入的这些数据在表中一定要有相应的字段。不然就会报错!

insert语句支持批量插入数据,比方我要把students表中的数据都导入表stu中。SQL语句为

insert into stu select * from students;

(4)查询语句

Select语句的通用格式例如以下:

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbGl1eHU4NDE5MTE1NDg=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="查询语句标准格式" title="">

这段语句简单解释一下,columns是要查询的字段,tables表示从哪张表里面查询,where是查询过滤的条件,group by是指依照某个字段分组查询。order by是排序,limit是限制数量语句,以下我会一一解释每一个语句须要注意的地方。

1.字段与表的别名

多表查询时查询条件相对复杂,表之间可能会产生同样的字段,这个时候字段前面能够加上表名以区分。别名就是我们能够将classes的表名设置为cls。将classes表中的major字段显示为cmj字段以简化SQL语句。

2.where条件过滤

where语句中经常使用的逻辑操作符有and、or、not,分别代表与、或、非。

注意where中有一个较为重要的关系操作符叫做like。它是模糊匹配。比如要找到students表中以t开头的全部学生,那么相应的SQL为:

select * from students where name like “t%”;

3.Group by 分组

    聚合中有一个重要的功能就是分组。分组就是将得到的结果集依照一定的规则划分为多个组。

因为该功能不常使用,想要了解的朋友自行查阅资料。

4.排序

select结果集的排序使用的是order by字句。排序有升序和降序两种。分别相应asc和desc,order by后面紧跟一个或者多个字段。多个字段间用逗号隔开。

5.数量限定

数量限定须要使用limit语句。数量限定的标准格式例如以下:

    limit 返回的数量 offset 偏移量

比如我们希望从students中索引为3的记录開始索引而且仅仅返回一条语句,SQL例如以下:

select * from students limit 1 offset 2;

6.distinct去重

    distinct用于去除select语句中反复的行。它紧跟在select之后。

(5)update 语句

update 语句用于更新表中的数据,它的格式为:

update table set update_list where predicate;
    update_list是要改动的字段以及值。事实上就是一个字段赋值语句,形式为:字段名 = 字段值,每一个字段赋值语句通过逗号分隔开。兴许我会在具体的演示样例代码中举例,在这就只是多阐述。

(6)delete语句

delete语句的格式例如以下:

//当满足where的条件时。删除表table中的数据。table是表名
delete from table where predicate;

(7)改动表

    我们知道。随着项目的演化,最初建立的表可能会面临改动的情况。

改动表的SQL语句命令为alter。SQLite中的alter命令并没有实现标准SQL中的全部功能,**它仅仅有改动表名和加入字段两个功能**,**删除字段等功能仅仅能通过又一次创建表来实现**。

alter的语法格式为:

alter table tableName {rename to newName | add column 新的字段};
    上述的语法表示alter table之后要操作先跟表名,然后rename to newName 和add column 新的字段两者2选1。rename to 是重命名。add column是加入新的字段。

(8)drop 命令

    drop命令用于删除物理存储介质。

比如删除表、视图、索引、触发器等。

drop的语法格式为:
drop {table | view |index |trigger} name;

(9)数据库事务的介绍

    事务是一个数据库操作的运行单元。它定义了一条或多条SQL语句,这些语句要么被全部运行。要么全部不运行。它保证了SQL语句的原子性。

事务有begin、commit、rollback3个命令。begin表示開始一个事务,commit表示整个事务操作成功,rollback表示回滚到begin之前。

格式为:
begin。
//SQL语句
[commit | rollback];

注意:事务提供了一种保证多条SQL语句能够被运行或者不运行。非常大程度上保证了数据库操作的安全性。而在Android中使用事务。也会提升SQL的运行效率。

    事务的运用简单举个样例,张三给李四转账400元。银行的数据库中张三的存款金额要减400,李四的存款金额要加400,我们要保证张三扣钱的通过李四收到钱。这个时候就须要用到数据库事务,要么两条SQL语句同一时候成功,要么同一时候失败。

(10)Android中封装的数据库帮助接口

    我们知道Android的SQLite数据库是由C和C++实现,因此Android在FrameWork层封装了一层Java接口,使得开发者能够更方便的操作数据库。

基本的类型为SQLiteOpenHelper、SQLiteDatabase以及Cusor。无论怎样封装。本质上都是通过构建SQL语句而且提交到SQLite中运行。以下具体介绍。Android中创建数据库创建表的全部方法。

3.使用Android的接口创建和操作数据库

一般来说,在Android中创建数据库仅仅须要以下几步:

(1)创建一个Java类继承SQLiteOpenHelper

(2)实现SQLiteOpenHelper的onCreate和onUpdate方法以及构造方法。

(3)通过构造方法创建数据库,须要传入数据库的名称。Context和数据库的版本。

(4)在onCreate中完毕创建表和字段的操作,onUpdate中完毕升级操作

(5)通过帮助类的openOrCreateDatabase()方法或者getReadableDatabase()或者getWriteableDatabase()获取到数据库完毕数据的操作。

以下附上我的写的一个演示样例代码,当中封装了推断数据库是否存在某个表,是否存在某个字段的方法

数据库的帮助类,完毕了创建数据库,创建表

package com.geocompass.gisdatacollection.database;

import android.content.Context;
import android.database.Cursor;
import android.database.DatabaseErrorHandler;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Environment;

import com.geocompass.gisdatacollection.CollectionApplication;

import java.io.File;

/**
 * Created by liuxu on 2017/4/7.
 * 数据库的操作的帮助类
 */

public class ComplexDatabaseSqlHelper extends SQLiteOpenHelper {
    private static final String TAG = "ComplexDatabaseSqlHelper";
    //数据库的版本
    private static final int DB_VERSION = 1;

    public SQLiteDatabase getDb() {
        return db;
    }

    private SQLiteDatabase db;
    //数据库db文件的路径,由调用者传入
    private static String mDBPath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "giscoll.db";

    private static ComplexDatabaseSqlHelper mDBSqlHelper;

    public ComplexDatabaseSqlHelper(Context context, String DBpath) {
        super(context, DBpath, null, DB_VERSION);
        mDBPath = DBpath;
        if (db == null) {
            db = SQLiteDatabase.openOrCreateDatabase(DBpath, null);
        }
        onCreate(db);
    }

    public ComplexDatabaseSqlHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
        super(context, name, factory, version);
    }

    public ComplexDatabaseSqlHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version, DatabaseErrorHandler errorHandler) {
        super(context, name, factory, version, errorHandler);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        String CREATE_POINT = "create table tab_point ("
                + "id integer primary key autoincrement,"
                + "lon double, "
                + "lat double, "
                + "type integer) ";
        String CREATE_INTERSECTION = "create table tab_intersection ("
                + "inter_id integer primary key autoincrement,"
                + "interLon double, "
                + "interLat double, "
                + "interRouteID text) ";
        String CREATE_ROUTE = "create table tab_route ("
                + "route_name text,"
                + "startPointID integer, "
                + "endPointID integer, "
                + "geometryID text, "
                + "Geometry text) ";
        ;
        //假设不存在该表。则创建该表
        if (!tableIsExist("tab_point")) {
            db.execSQL(CREATE_POINT);
        }
        if (!tableIsExist("tab_intersection")) {
            db.execSQL(CREATE_INTERSECTION);
        }
        if (!tableIsExist("tab_route")) {
            db.execSQL(CREATE_ROUTE);
        }

    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }

    /**
     * 获取数据库的帮助类
     *
     * @return
     */
    public static ComplexDatabaseSqlHelper getDBSqlHelper() {
        if (mDBSqlHelper == null) {
            synchronized (ComplexDatabaseSqlHelper.class) {
                if (mDBSqlHelper == null) {
                    mDBSqlHelper = new ComplexDatabaseSqlHelper(CollectionApplication.getmContext(), mDBPath);
                }
            }
        }
        return mDBSqlHelper;
    }

    /**
     * 依据sql查询数据库的方法
     *
     * @param sql
     * @return
     */
    public Cursor query(String sql) {
        return db.rawQuery(sql, null);
    }

    /**
     * 运行Sql语句
     *
     * @param sql
     */
    public void execSQL(String sql) {
        db.execSQL(sql);
    }

    /**
     * 推断表格是否存在
     *
     * @param tableName
     * @return
     */
    public boolean tableIsExist(String tableName) {
        boolean result = false;
        if (tableName == null) {
            return false;
        }
        Cursor cursor = null;
        try {
            //db = SQLiteDatabase.openDatabase(this.mDBPath,null,SQLiteDatabase.OPEN_READONLY);
            String sql = "select count(*) as c from Sqlite_master where type =‘table‘ and name =‘" + tableName.trim() + "‘ ";
            cursor = db.rawQuery(sql, null);
            if (cursor.moveToNext()) {
                int count = cursor.getInt(0);
                if (count > 0) {
                    result = true;
                }
            }
            cursor.close();
        } catch (Exception e) {
            // TODO: handle exception
            result = false;
        }
        return result;
    }

    /**
     * 推断表中是否包括某个字段
     *
     * @param tableName
     * @param columnName
     * @return
     */
    public boolean columnIsExistsInTable(String tableName, String columnName) {
        boolean result = false;
        Cursor cursor = null;
        try {
            //  db = SQLiteDatabase.openDatabase(this.mDBPath, null, SQLiteDatabase.OPEN_READONLY);
            cursor = db.rawQuery("select * from sqlite_master where name = ? and sql like ?

"
                    , new String[]{tableName, "%" + columnName + "%"});
            result = null != cursor && cursor.moveToFirst();
        } catch (Exception ignored) {

        } finally {
            if (null != cursor && !cursor.isClosed()) {
                cursor.close();
            }
        }
        return result;
    }

    private void open() {
        if (db != null && !db.isOpen())
            db = SQLiteDatabase.openOrCreateDatabase(mDBPath, null);
    }
}

数据库的操作类,完毕了对数据库表中数据的插入和查询

package com.geocompass.gisdatacollection.database.manage;

import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;

import com.geocompass.gisdatacollection.model.Intersection;
import com.geocompass.gisdatacollection.model.Point;
import com.geocompass.gisdatacollection.model.Route;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by liuxu on 2017/4/10.
 * 封装了对数据库表的增删改查方法
 */

public class ComplexDBDao {
    private SQLiteDatabase db;
    public ComplexDBDao(SQLiteDatabase db) {
        this.db = db;
    }

    /**
     * 插入一个点到tab_point表
     * @param point
     * @return
     */
    public boolean insert(Point point){
        String INSERT_POINT = "INSERT INTO tab_point(lon,lat,type) VALUES (" + point.lon + "," + point.lat + "," + point.point_type + ")";
        try{
            db.execSQL(INSERT_POINT);
        }catch(SQLException e){
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 插入一个节点到tab_intersection表中
     * @param intersection
     * @return
     */
    public boolean insert(Intersection intersection){
        String INSERT_INTERSECTION = "insert into tab_intersection(interLon,interLat,interRouteID) values ("+intersection.interLon+","+intersection.interLat+",‘"+
                intersection.inter_route_id+"‘)";
        try{
            db.execSQL(INSERT_INTERSECTION);
        }catch(SQLException e){
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 插入一条Route到tab_route表中
     * @param route
     * @return
     */
    public boolean insert(Route route){
        String  INSERT_ROUTE = "insert into tab_route (route_name,startPointID,endPointID,geometryID,Geometry) values(‘"+route.route_name+
                "‘,"+route.startPointID+","+route.endPointID+",‘"+route.geometryID+"‘,‘"+route.Geometry+"‘)";
        try{
            db.execSQL(INSERT_ROUTE);
        }catch(SQLException e){
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 查询出数据库中全部的Points
     * @return
     */
    public List<Point> findAllTabPoint(){
        String sql_select = "select * from tab_point order by id";
        //请补充sql运行语句
        Cursor cursor = db.rawQuery(sql_select,null);
        int IDIndex = cursor.getColumnIndex("id");
        int lonIndex = cursor.getColumnIndex("lon");
        int latIndex = cursor.getColumnIndex("lat");
        int typeIndex = cursor.getColumnIndex("type");
        List<Point> list = new ArrayList<>();
        while (cursor.moveToNext()) {
            Point point = new Point();
            point.id = cursor.getInt(IDIndex);
            point.lon = cursor.getDouble(lonIndex);
            point.lat = cursor.getDouble(latIndex);
            point.point_type = cursor.getInt(typeIndex);
            list.add(point);
        }
        return list;
    }

    /**
     * 查询出数据库中全部的Intersection
     * @return
     */
    public List<Intersection> findAllTabIntersection(){
        String sql_select = "select * from tab_intersection order by inter_id";
        //请补充sql运行语句
        Cursor cursor = db.rawQuery(sql_select,null);
        int interIdIndex = cursor.getColumnIndex("inter_id");
        int interLonIndex = cursor.getColumnIndex("interLon");
        int interLatIndex = cursor.getColumnIndex("interLat");
        int interRouteIDIndex = cursor.getColumnIndex("interRouteID");
        List<Intersection> list = new ArrayList<>();
        while (cursor.moveToNext()) {
            Intersection intersection = new Intersection();
            intersection.inter_id = cursor.getInt(interIdIndex);
            intersection.interLon = cursor.getDouble(interLonIndex);
            intersection.interLat = cursor.getDouble(interLatIndex);
            intersection.inter_route_id = cursor.getString(interRouteIDIndex);
            list.add(intersection);
        }
        return list;
    }

    /**
     * 查询出数据库中全部的Route
     * @return
     */
    public List<Route> findAllTabRoute(){
        String sql_select = "select * from tab_route ";
        //请补充sql运行语句
        Cursor cursor = db.rawQuery(sql_select,null);
        int routeNameIndex = cursor.getColumnIndex("route_name");
        int startPointIDIndex = cursor.getColumnIndex("startPointID");
        int endPointIDIndex = cursor.getColumnIndex("endPointID");
        int geometryIDIndex = cursor.getColumnIndex("geometryID");
        int geometryIndex = cursor.getColumnIndex("Geometry");
        List<Route> list = new ArrayList<>();
        while (cursor.moveToNext()) {
            Route route = new Route();
            route.route_name = cursor.getString(routeNameIndex);
            route.startPointID = cursor.getInt(startPointIDIndex);
            route.endPointID = cursor.getInt(endPointIDIndex);
            route.geometryID = cursor.getString(geometryIDIndex);
            route.Geometry = cursor.getString(geometryIndex);
            list.add(route);
        }
        return list;
    }
}

这些知识都是数据库的基础知识。当然复杂的知识也是在基础知识的基础上拼接起来的,先学好了基础才干谈复杂项目中多个表多个字段数据库的运用!

我非常喜欢的一句话,不积跬步无以至千里,一直陪伴着我的学习和工作!

不足之处请指正。谢谢!

时间: 2024-10-27 18:24:06

10分钟理解Android数据库的创建与使用(附具体解释和演示样例代码)的相关文章

10分钟理解Android数据库的创建与使用(附详解和示例代码)

1.Android数据库简介. Android系统的framework层集成了Sqlite3数据库,我们知道Sqlite3是一种轻量级的高效存储的数据库. Sqlite数据库具有以下优点: (1)零配置,无需安装和配置: (2)储存在单一磁盘文件中的一个完整的数据库: (3)数据库文件可以在不同字节顺序的机器间自由共享: (4)支持数据大小至2TB: (5)足够小,全部源代码大致3万行C代码,250KB: (6)比目前流行的大多数数据库的操作要快: (7)开源. 2.Sqlite 基本操作语句和

PHPCMS中GET标签概述、 get 标签语法、get 标签创建工具、get 调用本系统演示样例、get 调用其它系统演示样例

一.get 标签概述 通俗来讲,get 标签是Phpcms定义的能直接调用数据库里面内容的简单化.友好化代码,她可调用本系统和外部数据,仅仅有你对SQL有一定的了解,她就是你的绝世好剑!也就是适合熟悉SQL语句的人使用.有了她,我们打造个性化的站点,能很方便的调用出数据库里面指定的内容.通过条件限制,我们能够调用出不同条件下的不同数据. 二.get标签样式 {get dbsource=" " sql=" "} {/get} 三.get 标签语法 1.get标签属性值

Android线程池(二)——ThreadPoolExecutor及其拒绝策略RejectedExecutionHandler使用演示样例

MainActivity例如以下: package cc.vv; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import android.os.Bundle; import android.app.Activity; /** * Demo描写叙述: * 线程池(Threa

将 Android* x86 NDK 用于 Eclipse* 并移植 NDK 演示样例应用

目标 面向 Eclipse (ADT) 的 Android 插件如今支持基于 NDK 的应用开发. 其可自己主动生成项目和构件文件以及代码存根,并可集成到整个 Android 应用开发中(构建原生库.将库拷贝到项目内的对应 JNI 目录.将应用打包以及生成带有 NDK 代码的终于 APK). 本文将讨论怎样配置 Eclipse 以利用该功能.并示范移植 NDK 应用的演示样例. 配置 Eclipse ADT 插件以配合 NDK 使用 必须先配置 Eclipse ADT 插件指向 NDK 安装路径

JDBC连接MySQL数据库及演示样例

JDBC是Sun公司制定的一个能够用Java语言连接数据库的技术. 一.JDBC基础知识         JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,能够为多种关系数据库提供统一訪问,它由一组用Java语言编写的类和接口组成.JDBC为数据库开发者提供了一个标准的API,据此能够构建更高级的工具和接口,使数据库开发者能够用纯 Java API 编写数据库应用程序,而且可跨平台执行,而且不受数据库供应商的限制.

Android数据库之创建和升级数据库(中)

上一篇文章中,简单介绍了一下android数据库的一些基本概念,那么从本节开始,就实战一下Android数据库的创建和升级. 上文中,也介绍了,SQLiteOpenHelper是一个抽象类,是我们用来创建和升级数据库的最佳实践.下面直接以代码方式,演示一下数据库的创建操作. <span style="font-size:18px;">package com.happy.db.db; import android.content.Context; import android

10分钟理解BFC原理

10 分钟理解 BFC 原理 一.常见定位方案 在讲 BFC 之前,我们先来了解一下常见的定位方案,定位方案是控制元素的布局,有三种常见方案: 普通流 (normal flow) 在普通流中,元素按照其在 HTML 中的先后位置至上而下布局,在这个过程中,行内元素水平排列,直到当行被占满然后换行,块级元素则会被渲染为完整的一个新行,除非另外指定,否则所有元素默认都是普通流定位,也可以说,普通流中元素的位置由该元素在 HTML 文档中的位置决定. 浮动 (float) 在浮动布局中,元素首先按照普

10分钟理解JS引擎的执行机制

10分钟理解JS引擎的执行机制 javascript 阅读约 7 分钟 深入理解JS引擎的执行机制 1.灵魂三问 : JS为什么是单线程的? 为什么需要异步? 单线程又是如何实现异步的呢? 2.JS中的event loop(1) 3.JS中的event loop(2) 4.说说setTimeout 首先,请牢记2点: (1) JS是单线程语言 (2) JS的Event Loop是JS的执行机制.深入了解JS的执行,就等于深入了解JS里的event loop 1.灵魂三问 : JS为什么是单线程的

android listview综合使用演示样例_结合数据库操作和listitem单击长按等事件处理

本演示样例说明: 1.自己定义listview条目样式,自己定义listview显示列数的多少,灵活与数据库中字段绑定. 2.实现对DB的增删改查,而且操作后listview自己主动刷新. 3.响应用户操作点击事件,演示样例中展示单击时取出主键Id和其它内容. 4.响应用户操作长按事件,演示样例中展示长按时依据主键Id来编辑和删除数据. 5.表现层与数据处理层分开,不依赖于cursor(使用cursor不易表现和业务分离),支持接口编程. 6.使用数据库处理框架AHibernate灵活操作sql