Android(java)学习笔记193:利用谷歌API对数据库增删改查(推荐使用)
2015-08-24 15:54
1166 查看
接下来我们通过项目案例来介绍:这个利用谷歌API对数据库增删改查
1.首先项目图:
2.这里的布局文件activity_main.xml:
3.其次是MyDBOpenHelper.java 和 MainActivity.java
[b]MyDBOpenHelper.java :[/b]
MainActivity.java:
4.注意事项:
(1)首先是getWritableDatabase()和getReadableDatabase()使用:
[b]getWritableDatabase():[/b]
getReadableDatabase():
这里[b]getWritableDatabase()从源码可以看出,它是给数据库数据加锁,这是因为当我们写入数据到数据库的时候,我们考虑的线程安全,在多线程中,在写入数据到数据库中,不同线程写入数据顺序不一样。[/b]
[b][b]这里[b]getReadableDatabase([/b][b])[/b][b]从源码[/b][b]可以看出,它是给数据库数据没有加锁,这是因为当我们读取数据库数据的时候,可以多个线程同时读取[/b][/b][/b]
[b](2)google封装API[/b]
public long insert(String table, String nullColumnHack, ContentValues values)
参数table:要插入数据的数据库表名
参数nullColumnHack:比如如果我们定义[b]nullColumnHack为"phone",表示如果数据库中[b][b]"phone"[/b]这一列出现某一行为空,就会系统自动补一个null[/b][/b]
[b]通常我们这个[b]nullColumnHack我们设置为"null",就是不希望自动补null。[/b][/b]
[b][b]当values参数为空或者里面没有内容的时候,我们insert是会失败的(底层数据库不允许插入一个空行),为了防止这种情况,我们要在这里指定一个 列名,到时候如果发现将要插入的行为空行时,就会将你指定的这个列名的值设为null,然后再向数据库中插入。[/b][/b]
[b][b]参数[b]values:一个ContentValues对象,类似一个map.通过键值对的形式存储值。可以使用ContentValues的put()方法,put()原型如下:[/b][/b][/b]
返回值long类型:返回插入的数据在表中第几行(long),插入失败返回 -1
比如:values.put( "name", "王五" + random.nextInt(100) );
public int delete(String table, String whereClause, String[] whereArgs)
参数table:[b]要删除数据的数据库表名[/b]
参数[b]whereClause:更新的条件,为一个字符串。如果为null,则所有行都将更新[/b]
[b][b][b][b]参数whereArgs:字符串数组,和whereClause配合使用。有两种用法,如果whereClause的条件已经直接给出,如"class = " + num,num是传入的参数,则whereArgs可设为null。如果是”class = ?“,则?会被whereArgs这个数组中对应的值替换,whereArgs给出?代表的值,有多个?的,字符串数组里的值依次填入。[/b][/b][/b][/b]
[b][b][b][b]返回值int类型:返回删除了多少条(int)记录数据,删除失败返回0[/b][/b][/b][/b]
[b][b][b][b]这里[b][b]whereClause和[b][b][b][b][b]whereArgs通常我们设置都是null,表示没有过滤条件,表示全部删除[/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b]
[b][b][b][b][b][b][b][b][b][b][b]例:db.delete("info", null, null);[/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b]
[b][b][b][b][b][b][b][b][b][b][b] db.delete("info","phone=?",new String[] {"999"});----删除所有phone=999的数据,等价于SQL的:[b]delete from info where phone=999[/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b]
[b][b][b][b][b][b][b][b][b][b][b][b][b][b][b][b][b][b][b][b][b][b][b] db.delete("info","phone=[b][b][b][b][b][b][b][b][b][b][b][b][b][b][b][b][b][b][b][b][b][b][b][b]999[/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b]",null);----------------------[b][b][b][b][b][b][b][b][b][b][b]删除所有phone=999的数据,等价于SQL的:[b]delete from info where phone=999[/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b]
public int update(String table, ContentValues values, String whereClause, String[] whereArgs)
[b][b][b][b][b][b][b][b][b][b][b][b]参数table:[b][b]要更新数据的数据库表名[/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b]
参数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:[b][b][b][b][b][b][b][b][b][b][b][b][b][b][b]要查询数据的数据库表名[/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b];[/b]
参数culumns:需要返回的列的列表,如果为null,则返回全部的列;
参数selection:查询的条件,符合什么条件的行将返回。如果为null,则这个表里的所有行都将返回。其两种用法和update里的一样;
参数selectionArgs:用法和update里的一样。
[b]返回值Cursor类型:返回了一个游标指针的Cursor,接下来可以使用Cursor中方法可以查询数据[/b]
比如:
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();
由于往往我们不知道数据库表中字段的排列顺序,但是我们可以在查询的时候:
[b]db.query("info", new String[]{"name","phone","_id"}, null, null, null, null, null);[/b]
[b]这样的话下面使用游标Cursor时候:index=0就是 name; index=1就是phone; index=2就是 _id[/b]
[b]也就是:[b] String name = cursor.getString(0);
String phone = cursor.getString(1);
String id = cursor.getString(2);[/b][/b]
这里特别注意使用Cursor查询完了之后,一定要关闭使用cursor.close();
5.使用完了数据库一定要关闭
db.close();
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
[b]MyDBOpenHelper.java :[/b]
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()使用:
[b]getWritableDatabase():[/b]
public SQLiteDatabase getWritableDatabase() { synchronized (this) { return getDatabaseLocked(true); } }
getReadableDatabase():
public SQLiteDatabase getReadableDatabase() { synchronized (this) { return getDatabaseLocked(false); } }
这里[b]getWritableDatabase()从源码可以看出,它是给数据库数据加锁,这是因为当我们写入数据到数据库的时候,我们考虑的线程安全,在多线程中,在写入数据到数据库中,不同线程写入数据顺序不一样。[/b]
[b][b]这里[b]getReadableDatabase([/b][b])[/b][b]从源码[/b][b]可以看出,它是给数据库数据没有加锁,这是因为当我们读取数据库数据的时候,可以多个线程同时读取[/b][/b][/b]
[b](2)google封装API[/b]
public long insert(String table, String nullColumnHack, ContentValues values)
参数table:要插入数据的数据库表名
参数nullColumnHack:比如如果我们定义[b]nullColumnHack为"phone",表示如果数据库中[b][b]"phone"[/b]这一列出现某一行为空,就会系统自动补一个null[/b][/b]
[b]通常我们这个[b]nullColumnHack我们设置为"null",就是不希望自动补null。[/b][/b]
[b][b]当values参数为空或者里面没有内容的时候,我们insert是会失败的(底层数据库不允许插入一个空行),为了防止这种情况,我们要在这里指定一个 列名,到时候如果发现将要插入的行为空行时,就会将你指定的这个列名的值设为null,然后再向数据库中插入。[/b][/b]
[b][b]参数[b]values:一个ContentValues对象,类似一个map.通过键值对的形式存储值。可以使用ContentValues的put()方法,put()原型如下:[/b][/b][/b]
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:[b]要删除数据的数据库表名[/b]
参数[b]whereClause:更新的条件,为一个字符串。如果为null,则所有行都将更新[/b]
[b][b][b][b]参数whereArgs:字符串数组,和whereClause配合使用。有两种用法,如果whereClause的条件已经直接给出,如"class = " + num,num是传入的参数,则whereArgs可设为null。如果是”class = ?“,则?会被whereArgs这个数组中对应的值替换,whereArgs给出?代表的值,有多个?的,字符串数组里的值依次填入。[/b][/b][/b][/b]
[b][b][b][b]返回值int类型:返回删除了多少条(int)记录数据,删除失败返回0[/b][/b][/b][/b]
[b][b][b][b]这里[b][b]whereClause和[b][b][b][b][b]whereArgs通常我们设置都是null,表示没有过滤条件,表示全部删除[/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b]
[b][b][b][b][b][b][b][b][b][b][b]例:db.delete("info", null, null);[/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b]
[b][b][b][b][b][b][b][b][b][b][b] db.delete("info","phone=?",new String[] {"999"});----删除所有phone=999的数据,等价于SQL的:[b]delete from info where phone=999[/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b]
[b][b][b][b][b][b][b][b][b][b][b][b][b][b][b][b][b][b][b][b][b][b][b] db.delete("info","phone=[b][b][b][b][b][b][b][b][b][b][b][b][b][b][b][b][b][b][b][b][b][b][b][b]999[/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b]",null);----------------------[b][b][b][b][b][b][b][b][b][b][b]删除所有phone=999的数据,等价于SQL的:[b]delete from info where phone=999[/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b]
public int update(String table, ContentValues values, String whereClause, String[] whereArgs)
[b][b][b][b][b][b][b][b][b][b][b][b]参数table:[b][b]要更新数据的数据库表名[/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b]
参数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:[b][b][b][b][b][b][b][b][b][b][b][b][b][b][b]要查询数据的数据库表名[/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b][/b];[/b]
参数culumns:需要返回的列的列表,如果为null,则返回全部的列;
参数selection:查询的条件,符合什么条件的行将返回。如果为null,则这个表里的所有行都将返回。其两种用法和update里的一样;
参数selectionArgs:用法和update里的一样。
[b]返回值Cursor类型:返回了一个游标指针的Cursor,接下来可以使用Cursor中方法可以查询数据[/b]
比如:
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();
由于往往我们不知道数据库表中字段的排列顺序,但是我们可以在查询的时候:
[b]db.query("info", new String[]{"name","phone","_id"}, null, null, null, null, null);[/b]
[b]这样的话下面使用游标Cursor时候:index=0就是 name; index=1就是phone; index=2就是 _id[/b]
[b]也就是:[b] String name = cursor.getString(0);
String phone = cursor.getString(1);
String id = cursor.getString(2);[/b][/b]
这里特别注意使用Cursor查询完了之后,一定要关闭使用cursor.close();
5.使用完了数据库一定要关闭
db.close();
相关文章推荐
- Android与设计模式
- Android 监听键盘弹出关闭
- Android项目利用jinkens自动打包
- Android 打包签名(二)
- Android SurfaceView实战 带你玩转flabby bird (上)
- parseSdkContent failed Could not initialize class android.graphics.Typeface
- Android自定义ProgressDialog
- android中跨进程通讯的4种方式
- Android 打包签名(一)
- 关于Android最佳性能实践——高性能编码优化学习笔记
- Ubuntu 14.04配置Android编译环境
- Android ContentProvider使用样例
- Android自定义Dialog
- android 学习 广播机制的使用
- Android 自定义控件 优雅实现元素间的分割线 (支持3.0以下)
- Android平台aac谷歌软解框架和流程、解码库学习
- Android 通知栏Notification的整合 全面学习 (一个DEMO让你完全了解它)
- Android时区及语言代码
- android: AAC文件解析
- Android欢迎界面的创建方法