接下来我们通过项目案例来介绍:这个利用谷歌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. Code First:如何实现一个主类中包含多个复类

    假设我们在程序中要用到的类的结构是这样的,这里比较特别的是B在A中出现了最少两次 public class B { [Key] public int Id { get; set; } public s ...

  2. Json 返回日期格式转换

    //日期转换 function ChangeDateFormat(time) { if (time != null) { var date = new Date(parseInt(time.repla ...

  3. C# 的 WCF文章 消息契约(Message Contract)在流(Stream )传输大文件中的应用

    我也遇到同样问题,所以抄下做MARK http://www.cnblogs.com/lmjq/archive/2011/07/19/2110319.html 刚做完一个binding为netTcpBi ...

  4. 【Xamarin挖墙脚系列:Xamarin开发环境配置需求】

    原文:[Xamarin挖墙脚系列:Xamarin开发环境配置需求] 前言 因为操作的全是大块头,加大你们的内存,CPU网上飙.... 卤煮的机器配置  最近的版本部署包,百度云离线下载:版本:Xama ...

  5. 微信JSSDK录音的一些bug

    UPDATE: 这篇博文已经过期, 新的BUG总结请看微信JSSDK与录音相关的坑 微信JSSDK有不少坑, 最近做一个webapp, 用到了其中的录音功能, 发现不少问题, 总结一下: 当你调用st ...

  6. WCF Concurrency (Single, Multiple, and Reentrant) and Throttling

    http://www.codeproject.com/Articles/89858/WCF-Concurrency-Single-Multiple-and-Reentrant-and Introduc ...

  7. cocos2d-x 添加自定义字体---中文,英文

    1: 找到字体   xxx.ttf 2: 在xcode工程的 Info.plist文件中添加key Fonts provided by application,   或者 UIAppFonts(raw ...

  8. HNOI 2008:水平可见直线

    Description 在xoy直角坐标平面上有n条直线L1,L2,...Ln,若在y值为正无穷大处往下看,能见到Li的某个子线段,则称Li为 可见的,否则Li为被覆盖的. 例如,对于直线: L1:y ...

  9. Selenium WebDriver + Grid2 + RSpec之旅(五)---面向对象设计用例

    Selenium WebDriver + Grid2 + RSpec之旅(五) ----面向对象设计用例 前几节讲了怎么一步一步的从零开始到编写出一个简单的测试用例,这一节将要讲一下怎么让测试用例变得 ...

  10. Linux学习笔记32——select()函数分析【转】

    Select在Socket编程中还是比较重要的,可是对于初学Socket的人来说都不太爱用Select写程序,他们只是习惯写诸如 connect.accept.recv或recvfrom这样的阻塞程序 ...