接下来我们通过项目案例来介绍:这个利用谷歌API对数据库增删改查

1. 首先项目图:

2. 这里的布局文件activity_main.xml:

 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" > <Button
android:onClick="add"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="增" /> <Button
android:onClick="delete"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="删" /> <Button
android:onClick="update"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="改" /> <Button
android:onClick="query"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="查" /> </LinearLayout>

3. 其次是MyDBOpenHelper.java  和  MainActivity.java

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)"); }
}

MainActivity.java:

package com.itheima.dbcreate;

import java.util.Random;

import android.app.Activity;
import android.content.ContentValues;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.view.View;
import android.widget.Toast; public class MainActivity extends Activity { @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
} /**
* 添加一条数据
*/
public void add(View view) {
// 执行下面的一行代码,数据库是不会别创建的了。
MyDBOpenHelper helper = new MyDBOpenHelper(this);
// 如果想创建数据库必须执行,下一行代码
SQLiteDatabase db = helper.getWritableDatabase();
Random random = new Random();
// db.execSQL("insert into info (name,phone) values (?,?)", new Object[]
// {
// "王五" + random.nextInt(100), "110-" + random.nextInt(100) });
ContentValues values = new ContentValues();
values.put("name", "王五" + random.nextInt(100));
values.put("phone", "110-" + random.nextInt(100));
long id = db.insert("info", null, values);// google封装API,内部本质还是通过组拼SQL语句
db.close();
if (id != -1) {
Toast.makeText(this, "添加成功,在第" + id + "行", 0).show();
} else {
Toast.makeText(this, "添加失败", 0).show();
}
} /**
* 删除一条数据
*/
public void delete(View view) {
// 执行下面的一行代码,数据库是不会别创建的了。
MyDBOpenHelper helper = new MyDBOpenHelper(this);
// 如果想创建数据库必须执行,下一行代码
SQLiteDatabase db = helper.getWritableDatabase();
// db.execSQL("delete from info ");
int result = db.delete("info", null, null);
db.close();
if (result == 0) {
Toast.makeText(this, "删除失败", 0).show();
} else {
Toast.makeText(this, "删除了"+result+"条记录", 0).show();
// 再去查询一次。
}
} /**
* 修改一条数据
*/
public void update(View view) {
// 执行下面的一行代码,数据库是不会别创建的了。
MyDBOpenHelper helper = new MyDBOpenHelper(this);
// 如果想创建数据库必须执行,下一行代码
SQLiteDatabase db = helper.getWritableDatabase();
//db.execSQL("update info set phone=?", new Object[] { "8888" });
ContentValues values = new ContentValues();
values.put("phone", "99999");
int result = db.update("info", values, null, null);
db.close();
if (result == 0) {
Toast.makeText(this, "修改了0条记录", 0).show();
} else {
Toast.makeText(this, "修改了"+result+"条记录", 0).show();
}
} /**
* 查询全部数据
*/
public void query(View view) {
// 执行下面的一行代码,数据库是不会别创建的了。
MyDBOpenHelper helper = new MyDBOpenHelper(this);
// 如果想创建数据库必须执行,下一行代码
SQLiteDatabase db = helper.getReadableDatabase();
//Cursor cursor = db.rawQuery("select * from info", null);
Cursor cursor = db.query("info", new String[]{"name","phone","_id"}, null, null, null, null, null);
while (cursor.moveToNext()) {
String name = cursor.getString(0);
String phone = cursor.getString(1);
String id = cursor.getString(2);
System.out.println("id:" + id + "--name:" + name + "--phone"
+ phone);
System.out.println("----");
}
// 记得用完数据库 关闭cursor
cursor.close();
db.close();
} }

4. 注意事项:

(1)首先是getWritableDatabase()和getReadableDatabase()使用:

getWritableDatabase():

public SQLiteDatabase getWritableDatabase() {
synchronized (this) {
return getDatabaseLocked(true);
}
}

getReadableDatabase():

 public SQLiteDatabase getReadableDatabase() {
synchronized (this) {
return getDatabaseLocked(false);
}
}

这里getWritableDatabase()从源码可以看出,它是给数据库数据加锁,这是因为当我们写入数据到数据库的时候,我们考虑的线程安全,在多线程中,在写入数据到数据库中,不同线程写入数据顺序不一样。

这里getReadableDatabase()从源码可以看出,它是给数据库数据没有加锁,这是因为当我们读取数据库数据的时候,可以多个线程同时读取

(2)google封装API

public long insert(String table, String nullColumnHack, ContentValues values)

参数table:要插入数据的数据库表名

参数nullColumnHack:比如如果我们定义nullColumnHack为"phone",表示如果数据库中"phone"这一列出现某一行为空,就会系统自动补一个null

通常我们这个nullColumnHack我们设置为"null",就是不希望自动补null。

当values参数为空或者里面没有内容的时候,我们insert是会失败的(底层数据库不允许插入一个空行),为了防止这种情况,我们要在这里指定一个 列名,到时候如果发现将要插入的行为空行时,就会将你指定的这个列名的值设为null,然后再向数据库中插入。

参数values:一个ContentValues对象,类似一个map.通过键值对的形式存储值。可以使用ContentValues的put()方法,put()原型如下:

public void put(String key, String value) {
mValues.put(key, value);
}

返回值long类型:返回插入的数据在表中第几行(long),插入失败返回 -1

比如:values.put( "name",  "王五" + random.nextInt(100) );

public int delete(String table, String whereClause, String[] whereArgs)

参数table:要删除数据的数据库表名

参数whereClause:更新的条件,为一个字符串。如果为null,则所有行都将更新

参数whereArgs:字符串数组,和whereClause配合使用。有两种用法,如果whereClause的条件已经直接给出,如"class = " + num,num是传入的参数,则whereArgs可设为null。如果是”class = ?“,则?会被whereArgs这个数组中对应的值替换,whereArgs给出?代表的值,有多个?的,字符串数组里的值依次填入。

返回值int类型:返回删除了多少条(int)记录数据删除失败返回0

这里whereClause和whereArgs通常我们设置都是null,表示没有过滤条件,表示全部删除

例:db.delete("info", null, null);

     db.delete("info","phone=?",new String[] {"999"});----删除所有phone=999的数据,等价于SQL的:delete from info where phone=999

     db.delete("info","phone=999",null);----------------------删除所有phone=999的数据,等价于SQL的:delete from info where phone=999

public int update(String table, ContentValues values, String whereClause, String[] whereArgs)

参数table:要更新数据的数据库表名

参数values:你需要更新个数据组成的一个map,由列的名字和列的新值构成,null是合法的值,会被转化为NULL;
参数whereClause:更新的条件,为一个字符串。如果为null,则所有行都将更新;
参数whereArgs:字符串数组,和whereClause配合使用。有两种用法,如果whereClause的条件已经直接给出,如“class = “ + num,num是传入的参数,则whereArgs可设为null。如果是”class = ?“,则?会被whereArgs这个数组中对应的值替换,whereArgs给出?代表的值,有多个?的,字符串数组里的值依次填入。
返回值int类型:返回更新多少行数据(int)
比如:db.update("info", values, null, null);
 

public Cursor query(String table, String[] columns,  String selection, String[] selectionArgs, String groupBy, String having, String orderBy)

参数table:要查询数据的数据库表名
参数culumns:需要返回的列的列表,如果为null,则返回全部的列;
参数selection:查询的条件,符合什么条件的行将返回。如果为null,则这个表里的所有行都将返回。其两种用法和update里的一样;
参数selectionArgs:用法和update里的一样。

返回值Cursor类型:返回了一个游标指针的Cursor,接下来可以使用Cursor中方法可以查询数据

比如:

db.query("info", new String[]{"name","phone","_id"}, null, null, null, null, null);

while (cursor.moveToNext()) {
        String name = cursor.getString(0);
        String phone = cursor.getString(1);
        String id = cursor.getString(2);
        System.out.println("id:" + id + "--name:" + name + "--phone"+ phone);
        System.out.println("----");
}
// 记得用完数据库 关闭cursor
cursor.close();

由于往往我们不知道数据库表中字段的排列顺序,但是我们可以在查询的时候:

db.query("info", new String[]{"name","phone","_id"}, null, null, null, null, null);

这样的话下面使用游标Cursor时候:index=0就是 name; index=1就是phone; index=2就是 _id

也就是: String name = cursor.getString(0);
             String phone = cursor.getString(1);
             String id = cursor.getString(2);

这里特别注意使用Cursor查询完了之后,一定要关闭使用cursor.close();

5. 使用完了数据库一定要关闭

db.close();

Android(java)学习笔记193:利用谷歌API对数据库增删改查(推荐使用)的更多相关文章

  1. Android(java)学习笔记136:利用谷歌API对数据库增删改查(推荐使用)

    接下来我们通过项目案例来介绍:这个利用谷歌API对数据库增删改查 1. 首先项目图: 2. 这里的布局文件activity_main.xml: <LinearLayout xmlns:andro ...

  2. C#学习笔记(3)——操作sqlserver数据库增删改查

    说明(2017-5-25 16:29:35): 1. VS2010,视图->服务器资源管理器->数据连接->右键添加连接->服务器名(本机可以用点)->选择数据库-> ...

  3. C#学习笔记(2)——操作sqlite数据库增删改查

    说明(2017-5-25 10:49:50): 1. app.config文件 Alt+Shift+C创建类,选择“应用程序配置文件”,添加<connectionStrings>,要先打个 ...

  4. Mysql学习笔记(三)对表数据的增删改查。

    正文内容. 这一部分是最简单的,也是最麻烦的.简单是因为其实只包括增删该插四个部分.大体上看,增加数据.删除数据.修改数据.查询数据都不麻烦啊,我们日常都是常用的.这个谁不会呢?以前在培训机构学mys ...

  5. 【EF6学习笔记】(二)操练 CRUD 增删改查

    本篇原文链接: Implementing Basic CRUD Functionality 说明:学习笔记参考原文中的流程,为了增加实际操作性,并能够深入理解,部分地方根据实际情况做了一些调整:并且根 ...

  6. EF6 学习笔记(二):操练 CRUD 增删改查

    EF6学习笔记总目录 ASP.NET MVC5 及 EF6 学习笔记 - (目录整理) 接上篇: EF6 学习笔记(一):Code First 方式生成数据库及初始化数据库实际操作 本篇原文链接: I ...

  7. Mysql学习笔记(二)对表结构的增删改查

    有将近一个星期都没有更新mysql了.相反linux的东西倒是学习不少.可能我个人情感上对linux更感兴趣一点.但mysql我也不烦,只是一旦将精力投入到了一样事情上去,就很难将精力分散去搞其他的东 ...

  8. oracle学习笔记系列------oracle 基本操作之表的增删改查

    --创建一个表 CREATE TABLE employee_souvc( id ), name ), gender ), birth DATE, salary ,), job ), deptno ) ...

  9. mongodb的学习笔记一(集合和文档的增删改查)

    1数据库的增删改查 一.增加一个数据库: use blog-----切换到指定的数据库,如果数据库不存在,则自动创建该数据库(新建的数据库,如果没有存储对应的集合,是不会显示出来的) 二.删除一个数据 ...

随机推荐

  1. UESTC 1425 Another LCIS

    也是一个求最长连续单调区间的问题,不同于HDU 3308LCIS的是,单点更新变成了区间成段增加,没关系同样的方法可破之.由于是成段更新,所以比更新区间小的区间是最大连续区间长度是不变的,所以更新su ...

  2. Button with Hover Effect (Learned from 百度脑图)

    今天想学学PM的技能, 打开了百度脑图的网站, 看到中间那个按键的hover效果蛮好看, 遂学习一下. 效果如下: Demo 其实就是利用:before绘制了半透明白色的遮罩, 平时用transfor ...

  3. 以面到点的学习MFC

    市面上讲解学习MFC的书籍不胜其多,但是阅读的同学呢,看了一些内容以后,就无法阅读下去了,觉得MFC好难,有的呢,就会直接去看别人写的程序,不管是大或小,有时候也能明白一点点,但是总是走不出自己开发设 ...

  4. 【HDOJ】3496 Watch The Movie

    二维费用背包. #include <stdio.h> #include <string.h> #define mymax(a, b) (a>b) ? a:b ][]; ] ...

  5. bzoj1899

    显然如果只有一个窗口,是一道贪心的题目,直接让吃饭慢的排在前面即可 两个窗口的话,我们还是根据这个原则 先对吃饭时间降序排序,然后这是一个dp 假如设当前处理到第i个人,当在窗口1的打饭时间确定了,窗 ...

  6. 通过 WIN32 API 实现嵌入程序窗体

    写了一个不使用 COM, 而是通过 WIN32 API 实现的示例, 它把写字板程序嵌在了自己的一个面板中. 这么做可能没有实际意义, 因为两个程序之前没有进行有价值的交互, 这里仅仅是为了演示这么做 ...

  7. BZOJ_1003_[ZJOI2006]_物流运输_(动态规划+最短路)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1003 m个码头,从1运货到m,n天每天运,其中有一些码头在特定的天里不能使用.运货的代价:在两 ...

  8. (转载)SQL联合查询中的关键语法

    (转载)http://www.cnblogs.com/zhangliyu/archive/2009/03/21/1418215.html 联合查询效率较高.以下例子来说明联合查询的好处 t1表结构(用 ...

  9. webbrowser控件事件

    Beforenavigate2: Fired before navigate occurs in the given WebBrowser(window or frameset element). T ...

  10. [辅助类]NHibernateHelper

    对于学习ORM的人来说,NHibernate简直就是福音啊,而且此中技术是相当成熟,在这里分享一个小东西 public class NHibernateHelper { //数据库连接字符串 publ ...