上一讲中我们讲到了SQLite数据库的操作方法 [数据存储之SQLite数据库操作(二)],我们主要是以SQL语句对数据库进行增删改查,这一讲我们来学习一下 Android 建议的对数据库的操作方法

    查看 SQLiteDatabase 中, 在上一讲中有讲到 execSQL (String sql, Object[] bindArgs) 这个方法,在这里Android建议我们在操纵数据库的时候用以下几种方式:

1) 插入:

insert(String, String, ContentValues)

insertOrThrow(String, String, ContentValues)

insertWithOnConflict(String, String, ContentValues, int)

2) 更新:

update(String, ContentValues, String, String[])

updateWithOnConflict(String, ContentValues, String, String[], int)
3) 删除:

delete(String, String, String[])
[注]这一讲中我们就来使用Android推荐的这些操作数据库的方法来进行数据库的操作,Demo 还是与上一讲类似,读者可以结合上一讲内容来学习,对比之间的不同。

1. 方法概要



    1) 查看API文档 SQLiteDatabase 中的
    public long insert (String table, String nullColumnHack, ContentValues values)
    插入一行数据到数据库中


参数:

table :  需要插入行的表的名称

nullColumnHack :  这个参数是可选的,可以为null, SQL 不允许插入一个至少一列都不命名的完全空的行。如果你提供的 values 是空的,而且
没有已知的的列名,这就是一个空行,这是不能被插入的。如果设置非空,nullColumnHack 参数提供一个可为空的列的名称,当插入的 values 是空的时候,就将这个列名置为NULL,然后values值插入。

values :  指定行对应的列的值,这个类型很类似Map,key表示列的名称,values表示列的值

返回值:

返回新插入的行的ID,如果存在错误默认返回 -1

[备注]第二个参数翻译的有些拘谨,我们可以这样理解

当在没有任何已知的列名的情况下,values参数为空的时候,insert是会失败的(数据库不允许插入一个空行),为了防止Insert()方法要求必须添加一条除了主键之外其它字段为Null值的记录,我们要在这里必须指定一个列名[因为values值是以ContentValues 的形式来存储的],到时候如果发现将要插入的行为空行时,就会将你指定的这个列名的值设为null,然后再将values值向NULL列中插入。查看源代码,我们可以发现 Android 中操作数据库的方法底层也是通过构造SQL语句来实现的。


2) 查看API文档SQLiteDatabase 中的
public int delete (String table, String whereClause, String[] whereArgs)
删除操作 

参数:

table : 表示表名

whereClause :  可选项,是可以通过 SQL语句中where语句来过滤条件删除的条目,如果是null 表示删除所有行

whereArgs :  紧跟第二个参数,作为删除过滤条件的占位符,详情请看下面程序 PersonDao2 的 deletePerson() 方法的操作。

返回值:

如果是 0 表示未删除任何行,如果已经有删除行的操作 会得到 count > 0的数,表示删除的行数

3) 查看API文档SQLiteDatabase 中的

public int update (String table, ContentValues values, String whereClause, String[] whereArgs)
更新操作


参数 :


table : 表示表名

values :  Map 中指定列名用来更新新的值,如果是null 值则为修改为 NULL

whereClause : 可选项,支持SQL中的更新语句,用来做条件过滤,如果设置null 则会更新所有行

whereArgs : 紧跟第二个参数,作为更新过滤条件的占位符,详情请看下面程序 PersonDao2 的updatePerson() 方法的操作。


返回值:

返回所更新的数据库的行数

4)查看API文档SQLiteDatabase 中的

.

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

参数:

distinct :   判断是否返回的行是唯一值,如果想要返回唯一的行,则为true,否则为false。

table : 需要查询的表的名称。

columns : 需要返回的列,如果要返回所有列则置为null。

selection : 过滤需要返回的行,格式遵从SQL中 SQL WHERE 语句(除了Where关键字以外).如果返回给定表的所有行,则置为Null。

selectionArgs : 过滤条件的占位符,这里的值会代替过滤语句中 "?"。

groupBy :  过滤条件对行进行分组,格式遵从SQL中 SQL GROUP BY 语句 (除了关键字GROUP BY之外),如果不分组,置为Null。

having :  对分组过滤条件的占位符操作。

orderBy :  如何进行排序,遵从SQL中的SQL ORDER BY 语句, 如果是null表示使用默认的排序顺序。

limit :是否对数据库进行分页的查询。

返回值:

它返回的是一个游标,这个用法之前有讲过,不懂的可以查看前面几讲内容的介绍


2. 代码实现

1) 程序布局文件 activity_main.xml,这里只是定义了几个按钮,就不贴出来了

2) DBOpenHelper.java 用来创建数据库使用

[java]  
1. package com.android.sqlitedemo.db;  
2.   
3. import android.content.Context;  
4. import android.database.sqlite.SQLiteDatabase;  
5. import android.database.sqlite.SQLiteOpenHelper;  
6.   
7. public class DBOpenHelper extends SQLiteOpenHelper {  
8.   
9. private static String name = "mydb.db"; // 表示数据库的名称  
10. private static int version = 1; // 表示数据库的版本号  
11.   
12. public DBOpenHelper(Context context) {  
13. super(context, name, null, version);  
14. // TODO Auto-generated constructor stub  
15.     }  
16.   
17. // 当数据库创建的时候,是第一次被执行,完成对数据库的表的创建  
18. @Override  
19. public void onCreate(SQLiteDatabase db) {  
20. // TODO Auto-generated method stub  
21. // SQLite 数据创建支持的数据类型: 整型数据,字符串类型,日期类型,二进制的数据类型  
22. // 数据库这边有一个特点,就是SQLite数据库中文本类型没有过多的约束,也就是可以把布尔类型的数据存储到文本类型中,这样也是可以的  
23. "create table person(id integer primary key autoincrement,name varchar(64),address varchar(64),sex varchar(8))";  
24. // 完成数据库的创建  
25.     }  
26.   
27. @Override  
28. public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {  
29. // TODO Auto-generated method stub  
30.     }  
31.   
32. }

3) PersonService2.java 定义操作数据库(增删改查)的接口

[java] 
1. package com.android.sqlitedemo.service;  
2.   
3. import android.content.ContentValues;  
4.   
5. import java.util.List;  
6. import java.util.Map;  
7.   
8.   
9. /**
10.  * 定义好增删改查接口
11.  * @author xukunhui
12.  *
13.  */  
14. public interface PersonService2 {  
15.   
16. public boolean addPersion(ContentValues values);   
17.       
18. public boolean deletePerson(String whereClause, String[] whereArgs);  
19.       
20. public boolean updatePerson(ContentValues values, String whereClause, String[] whereArgs);  
21.       
22. //使用 Map<String, String> 做一个封装,比如说查询数据库的时候返回的单条记录  
23. public Map<String, String> viewPerson(String selection, String[] selectionArgs);  
24.       
25. //使用 List<Map<String, String>> 做一个封装,比如说查询数据库的时候返回的多条记录  
26. public List<Map<String, String>> listPersonMaps(String selection, String[] selectionArgs);  
27. }

3) PersonDao2.java 实现操作数据库的增删改查的功能

[java] 
1. package com.android.sqlitedemo.dao;  
2.   
3. import android.content.ContentValues;  
4. import android.content.Context;  
5. import android.database.Cursor;  
6. import android.database.sqlite.SQLiteDatabase;  
7.   
8. import com.android.sqlitedemo.db.DBOpenHelper;  
9. import com.android.sqlitedemo.service.PersonService2;  
10.   
11. import java.util.ArrayList;  
12. import java.util.HashMap;  
13. import java.util.List;  
14. import java.util.Map;  
15.   
16. public class PersonDao2 implements PersonService2 {  
17.   
18. private DBOpenHelper helper = null;  
19.   
20. public PersonDao2(Context context) {  
21. new DBOpenHelper(context);  
22.     }  
23.   
24. @Override  
25. public boolean addPersion(ContentValues values) {  
26. // TODO Auto-generated method stub  
27. boolean flag = false;  
28. null;  
29. long id = -1;  
30. try {  
31.             database = helper.getWritableDatabase();  
32. "person", null, values);  
33. 1 ? true : false);  
34. catch (Exception e) {  
35. // TODO: handle exception  
36. finally {  
37. if (database != null) {  
38.                 database.close();  
39.             }  
40.         }  
41. return flag;  
42.     }  
43.   
44. @Override  
45. public boolean deletePerson(String whereClause, String[] whereArgs) {  
46. // TODO Auto-generated method stub  
47. boolean flag = false;  
48. null;  
49. int count = 0;  
50. try {  
51.             database = helper.getWritableDatabase();  
52. "person", whereClause, whereArgs);  
53. 0 ? true : false);  
54. catch (Exception e) {  
55. // TODO: handle exception  
56. finally {  
57. if (database != null) {  
58.                 database.close();  
59.             }  
60.         }  
61. return flag;  
62.     }  
63.   
64. @Override  
65. public boolean updatePerson(ContentValues values, String whereClause, String[] whereArgs) {  
66. // TODO Auto-generated method stub  
67. boolean flag = false;  
68. null;  
69. int count = 0; // 影响数据库的行数  
70. try {  
71.             database = helper.getWritableDatabase();  
72. "person", values, whereClause, whereArgs);  
73. 0 ? true : false);  
74. catch (Exception e) {  
75. // TODO: handle exception  
76. finally {  
77. if (database != null) {  
78.                 database.close();  
79.             }  
80.         }  
81. return flag;  
82.     }  
83.   
84. // 查询单条记录  
85. @Override  
86. public Map<String, String> viewPerson(String selection, String[] selectionArgs) {  
87. // TODO Auto-generated method stub  
88. // select * from  
89. // * 表示 返回的列的名称(投影查询) from  
90. null;  
91. null;  
92. new HashMap<String, String>();  
93. try {  
94.             database = helper.getReadableDatabase();  
95. true, "person", null, selection, selectionArgs, null,  
96. null, null, null); //查询单条记录,记录是唯一的,所以第一个参数置为 true.  
97. int cols_len = cursor.getColumnCount(); // 获取游标个数,即查询所得的结果数目  
98. while (cursor.moveToNext()) {  
99. for (int i = 0; i < cols_len; i++) {  
100.                     String cols_name = cursor.getColumnName(i);  
101.                     String cols_values = cursor.getString(cursor.getColumnIndex(cols_name));  
102. if (cols_values == null) {  
103. "";  
104.                     }  
105.                     map.put(cols_name, cols_values);  
106.                 }  
107.             }  
108. catch (Exception e) {  
109. // TODO: handle exception  
110.             e.printStackTrace();  
111. finally {  
112. if (database != null) {  
113.                 database.close();  
114.             }  
115.         }  
116. return map;  
117.     }  
118.   
119. // 查询多条记录  
120. @Override  
121. public List<Map<String, String>> listPersonMaps(String selection, String[] selectionArgs) {  
122. // TODO Auto-generated method stub  
123. null;  
124. null;  
125. new ArrayList<Map<String,String>>();  
126. try {  
127.             database = helper.getReadableDatabase();  
128. false, "person", null, selection, selectionArgs, null,  
129. null, null, null); //查询所有记录,所以有重复的数据也要全部检出,所以第一参数置为false.  
130. int cols_len = cursor.getColumnCount();  
131. while (cursor.moveToNext()) {  
132. new HashMap<String, String>();  
133. for (int i = 0; i < cols_len; i++) {  
134.                     String cols_name = cursor.getColumnName(i);  
135.                     String cols_values = cursor.getString(cursor.getColumnIndex(cols_name));  
136. if (cols_values == null) {  
137. "";  
138.                     }  
139.                     map.put(cols_name, cols_values);  
140.                 }  
141.                 list.add(map);  
142.             }  
143. catch (Exception e) {  
144. // TODO: handle exception  
145.             e.printStackTrace();  
146. finally {  
147. if (database != null) {  
148.                 database.close();  
149.             }  
150.         }  
151. return list;  
152.     }  
153. }

 

4) MainActivity.java 点击按钮触发操作数据的事件

[java]
1. package com.android.sqlitedemo;  
2.   
3. import java.util.List;  
4. import java.util.Map;  
5.   
6. import com.android.sqlitedemo.dao.PersonDao2;  
7. import com.android.sqlitedemo.db.DBOpenHelper;  
8. import com.android.sqlitedemo.service.PersonService2;  
9.   
10. import android.os.Bundle;  
11. import android.app.Activity;  
12. import android.content.ContentValues;  
13. import android.util.Log;  
14. import android.view.Menu;  
15. import android.view.View;  
16. import android.view.View.OnClickListener;  
17. import android.widget.Button;  
18.   
19. public class MainActivity extends Activity {  
20.   
21. private Button button1;  
22. private Button button2;  
23. private Button button3;  
24. private Button button4;  
25. private Button button5;  
26. private Button button6;  
27.   
28. private static final String TAG = "MainActivity";  
29.   
30. @Override  
31. protected void onCreate(Bundle savedInstanceState) {  
32. super.onCreate(savedInstanceState);  
33.         setContentView(R.layout.activity_main);  
34.         initComponent();  
35. new OnClickListener() {  
36.   
37. @Override  
38. public void onClick(View v) {  
39. // TODO Auto-generated method stub  
40. new DBOpenHelper(MainActivity.this);  
41. // 调用 getWritableDatabase()或者 getReadableDatabase()其中一个方法将数据库建立  
42.                 helper.getWritableDatabase();  
43.             }  
44.         });  
45. new OnClickListener() {  
46.   
47. @Override  
48. public void onClick(View v) {  
49. // TODO Auto-generated method stub  
50. new PersonDao2(MainActivity.this);  
51. new ContentValues();  
52. "name", "AHuier");  
53. "address", "XIAMEN");  
54. "sex", "male");  
55. boolean flag = service2.addPersion(values);  
56. "---- addPersion --->" + flag);  
57.             }  
58.         });  
59. new OnClickListener() {  
60. @Override  
61. public void onClick(View v) {  
62. new PersonDao2(MainActivity.this);  
63. // 删除的SQL语句 :delete from person where id = ?  
64. // 不包含 where 关键字  
65. boolean flag = service2.deletePerson(" id = ? ", new String[] {  
66. "4"  
67.                 });  
68. "---- deletePerson ---->" + flag);  
69.             }  
70.         });  
71. new OnClickListener() {  
72.   
73. @Override  
74. public void onClick(View v) {  
75. // TODO Auto-generated method stub  
76. new PersonDao2(MainActivity.this);  
77. new ContentValues();  
78. "name", "AHuier");  
79. "address", "XIAMEN");  
80. "sex", "female");  
81. boolean flag = service2.updatePerson(values, " id = ? ", new String[] {  
82. "1"  
83.                 });  
84. "---- updatePerson --->" + flag);  
85.             }  
86.         });  
87. new OnClickListener() {  
88.   
89. @Override  
90. public void onClick(View v) {  
91. new PersonDao2(MainActivity.this);  
92. " id = ? ", new String[] { "2" });  
93. "---- viewPerson --->" + map.toString());  
94.             }  
95.         });  
96. new OnClickListener() {  
97.   
98. @Override  
99. public void onClick(View v) {  
100. new PersonDao2(MainActivity.this);  
101. // select * from person  
102. null, null);  
103. "---- viewPerson --->" + list.toString());  
104.             }  
105.         });  
106.     }  
107.   
108. @Override  
109. public boolean onCreateOptionsMenu(Menu menu) {  
110. // Inflate the menu; this adds items to the action bar if it is present.  
111.         getMenuInflater().inflate(R.menu.main, menu);  
112. return true;  
113.     }  
114.   
115. private void initComponent() {  
116.         button1 = (Button) findViewById(R.id.button1);  
117.         button2 = (Button) findViewById(R.id.button2);  
118.         button3 = (Button) findViewById(R.id.button3);  
119.         button4 = (Button) findViewById(R.id.button4);  
120.         button5 = (Button) findViewById(R.id.button5);  
121.         button6 = (Button) findViewById(R.id.button6);  
122.     }  
123.   
124. }

 


3. 程序执行过程

1) 插入数据

sqlite 数据库 timestamp SQlite 数据库操作ppt_数据库

2) 删除ID = 4 的数据

sqlite 数据库 timestamp SQlite 数据库操作ppt_android_02

3) 修改ID = 1 的数据

sqlite 数据库 timestamp SQlite 数据库操作ppt_SQL_03

4) 返回查询的单条记录和多条记录

sqlite 数据库 timestamp SQlite 数据库操作ppt_数据库_04