android sqlite数据库增删改查

来源:互联网 发布:代理商授权书源码系统 编辑:程序博客网 时间:2024/04/28 07:02

需要测试环境,启动模拟器 不需要对模拟器进行操作 只用junit就能完成本次的练习

一:

创建简单的person bean 有id和name属性 生成getset方法 在有一name的构造器 最好在有一空的构造器

二:

搭建JUnit测试环境 http://blog.csdn.net/hxy01245120/article/details/7897947

三:

编写sqlite的助手类 继承SQLiteOpenHelper类 因为父类没有空的构造器 所有要创建

   public DBOpenHelp(Context context, CursorFactory factory, int version) {} 构造器

在创建一个 public DBOpenHelp(Context context) {}构造器 方便调用 下面助手类源码

package com.itcast.service;import android.content.Context;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteDatabase.CursorFactory;import android.database.sqlite.SQLiteOpenHelper;/** * 实现了SQLiteOpenHelper的助手类 *  * @author Administrator *  */public class DBOpenHelp extends SQLiteOpenHelper {private static final String DATABASENAME = "itcast.db";// 数据库名称private static final int DATABASEVERSION = 1;// 数据库版本public DBOpenHelp(Context context, CursorFactory factory, int version) {/** * 1<br> * 2数据库名称<br> * 3游标工厂 一般都不需要 默认就行 null为默认<br> * 4数据库版本号<br> */super(context, DATABASENAME, null, DATABASEVERSION);}public DBOpenHelp(Context context) {/** * 1<br> * 2数据库名称<br> * 3游标工厂 一般都不需要 默认就行 null为默认<br> * 4数据库版本号<br> */super(context, DATABASENAME, null, DATABASEVERSION);}@Override/** * 该方法只调用一次 就是在数据库被创建的时候<br> * 可以完成数据库表的创建<br> * 可以通过擦参数SQLiteDatabase的对象 执行sql语句 */public void onCreate(SQLiteDatabase db) {/** * mysql有5个数据对象可存储 INTEGER TEXT(字符串文本) NULL REAL(浮点数字) BLOB(二进制对象)<br> * 但也可以存储其他的数据类型 比如 varchar(n) char(n) decimal(p,s)等数据类型 * 只不过在保存的时候会转成对应的5中数据类型<br> * sqlite 最大特点就是可以把各种数据类型保存到字段中 而不用关心数据库声明字段的类型 * 比如可以再integer类型存放字符串或者在字符类型中存放日期<br> * 但有一种是例外 定义为integer primary key的字段 只能64为整数 当向这种字段保存其他类型数据时 会产生错误<br> * sqlite 在创建表( create table )的时候会忽略字段后跟的数据类型 以及 他的长度 所以sqlite数据库中创建的表 * 是忽略字段类型 和长度的 除了上面说到的integer primary key<br> */db.execSQL("create table person(id integer primary key autoincrement,name varchar(20))");// 执行有更新行为的sql,比如创建,修改,删除}@Override/** * 更新数据库版本的时候调用 可以对数据表结构调整 基本信息添加等 */public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {db.execSQL("drop table if exists person ");// 真正项目中需要考虑数据的重要性 尽量少对数据库做删除onCreate(db);}}

四:

编写增删改查的业务类 android可用资源少 所以不建议面向接口编程 尽量少用接口 接口也只是为了代码的耦合 在android不存在多少代码的耦合 所以不需要 这也是android大多用内部类的一个原因 下面增删改查的业务类代码及注释

package com.itcast.service;import java.util.ArrayList;import java.util.List;import android.content.Context;import android.database.Cursor;import android.database.sqlite.SQLiteDatabase;import com.itcast.model.Person;public class PersonService {private DBOpenHelp dbOpenHelp;public PersonService(Context context) {this.dbOpenHelp = new DBOpenHelp(context);}/** * 添加一个person *  * @param person */public void savePerson(Person person) {// getWritableDatabase()如果磁盘空间满了,就只能以读的方式打开数据库,所以在磁盘空间满了的状态下调用该方法会出错SQLiteDatabase db = dbOpenHelp.getWritableDatabase();// 可读可写的方式打开数据库,如果要对数据进行增删改操作,调用该方法的到数据库操作实例// getReadableDatabase 该方法是先调用getWritableDatabase 如果磁盘空间满了// 调用getWritableDatabase方法会出错 之后就会调用另一开以只读的方法打开数据库dbOpenHelp.getReadableDatabase();// 以读的形式打开数据库,如果只对数据进行,就调用该方法db.execSQL("insert into person(name) values(?)", new Object[] { person.getName() });// 后面的数组用来填充前面的占位符}/** * 更新person对象 *  * @param person */public void updatePerson(Person person) {SQLiteDatabase db = dbOpenHelp.getWritableDatabase();// getWritableDatabase,getReadableDatabase调用后先检测数据库版本号// 如果跟上次不一样,就会调用@DBOpenHelp@onUpgrade()db.execSQL("update person set name=? where id=?", new Object[] { person.getName(), person.getId() });}/** * 删除一个person对象 *  * @param personId */public void deletePerson(Integer personId) {SQLiteDatabase db = dbOpenHelp.getWritableDatabase();db.execSQL("delete from person where id=?", new Object[] { personId.toString() });}/** * 查询一个person *  * @param personId * @return */public Person findPerson(Integer personId) {SQLiteDatabase db = dbOpenHelp.getReadableDatabase();// 如果磁盘空间没满的话,该对象与上面的对象是相等的,如果满了,该方法会调用另一只读方法,那么他们就不相等了Cursor cursor = db.rawQuery("select * from person where id=?", new String[] { personId.toString() });if (cursor.moveToFirst()) {Person person = new Person();person.setId(cursor.getInt(cursor.getColumnIndex("id")));person.setName(cursor.getString(cursor.getColumnIndex("name")));return person;}return null;}/** * 查询分页 *  * @param offSet *            忽略开始的多少条数据 * @param maxResult *            查询的记录数 * @return */public List<Person> findPersonForPage(int offset, int maxResult) {List<Person> persons = new ArrayList<Person>();SQLiteDatabase db = dbOpenHelp.getReadableDatabase();Cursor cursor = db.rawQuery("select * from person limit?,?", new String[] { String.valueOf(offset), String.valueOf(maxResult) });while (cursor.moveToNext()) {Person person = new Person();person.setId(cursor.getInt(cursor.getColumnIndex("id")));person.setName(cursor.getString(cursor.getColumnIndex("name")));persons.add(person);}cursor.close();return persons;}/** * 查询person表的总记录数 *  * @return */public Long countPerson() {SQLiteDatabase db = dbOpenHelp.getReadableDatabase();Cursor cursor = db.rawQuery("select count(*) from person", null);cursor.moveToFirst();// 一定要将光标移动到第一行 因为光标刚开始处于第一条记录的顶部// moveToFirst可以判断光标是否可以移到下一行并且移到下一行return cursor.getLong(0);}}

五:

测试类;需要测试环境 上面有连接

package com.itcast.db;import java.util.List;import android.test.AndroidTestCase;import android.util.Log;import com.itcast.model.Person;import com.itcast.service.DBOpenHelp;import com.itcast.service.PersonService;public class PersonServiceTest extends AndroidTestCase {private static final String TAG = "PersonServiceTest";public void testCreateDataBase() throws Throwable {DBOpenHelp dbHelp = new DBOpenHelp(getContext());dbHelp.getWritableDatabase();}public void testSavePerson() throws Throwable {PersonService personService = new PersonService(getContext());Person person = new Person("张三");Person person2 = new Person("李四");Person person3 = new Person("王五");Person person4 = new Person("赵六");Person person5 = new Person("黑七");Person person6 = new Person("马二");personService.savePerson(person);personService.savePerson(person2);personService.savePerson(person3);personService.savePerson(person4);personService.savePerson(person5);personService.savePerson(person6);}public void testUpdatePerson() throws Throwable {Person person = new Person();person.setId(1);person.setName("xxx");PersonService personService = new PersonService(getContext());personService.updatePerson(person);}public void testDeletePerson() throws Throwable {PersonService personService = new PersonService(getContext());personService.deletePerson(1);}public void testFindPerson() throws Throwable {PersonService personService = new PersonService(getContext());Person person = personService.findPerson(1);Log.i(TAG, person.toString());}public void testFindPersonForPage() throws Throwable {PersonService personService = new PersonService(getContext());List<Person> persons = personService.findPersonForPage(1, 3);for (Person person : persons) {Log.i(TAG, person.toString());}}public void testCountPerson() throws Throwable {PersonService personService = new PersonService(getContext());Long n = personService.countPerson();Log.i(TAG, n+"");}}

六:

另一种业务类的写法,这种写法一是为了不熟悉sql,而是如果开发过程中有第三方提供数据或者API符合下面的语句条件 可用下面的增删改查业务的方法实现对数据库的操作 一般情况下不建议下面着用 因为下面的语句都是自己有构造的sql语句 但从性能上说就没有上面的业务类高 为不同的需求 下面贴出源码

package com.itcast.service;import java.util.ArrayList;import java.util.List;import android.content.ContentValues;import android.content.Context;import android.database.Cursor;import android.database.sqlite.SQLiteDatabase;import com.itcast.model.Person;public class OtherPersonService {private DBOpenHelp dbOpenHelp;public OtherPersonService(Context context) {this.dbOpenHelp = new DBOpenHelp(context);}/** * 添加一个person *  * @param person */public void savePerson(Person person) {SQLiteDatabase db = dbOpenHelp.getWritableDatabase();ContentValues values = new ContentValues();values.put("name", person.getName());db.insert("person", null, values);// 该方法自己构造sql语句 所以性能比execSQL// 参数2表示;如果参数3为空的话,参数2将作为insert语句的字段名插入一个null值,除了主键 其他都为空值// 例如 db.insert("person", "name", null);// 等价于 insert into person(name) values(null);}/** * 更新person对象 *  * @param person */public void updatePerson(Person person) {SQLiteDatabase db = dbOpenHelp.getWritableDatabase();ContentValues values = new ContentValues();values.put("name", person.getName());/** * 1:表名<br> * 2:要修改的字段和值放在一个类似map的集合里 字段做key<br> * 3:sql语句中的条件语句 不带where 值可用占位符表示<br> * 4:数组,存放前面的占位符的值 */db.update("person", values, "id=?", new String[] { String.valueOf(person.getId()) });// 该方法构造了自己又构造了sql语句// 上面语句等价于 db.execSQL("update person set name=? where id=?", new// Object[] {// person.getName(), person.getId() });}/** * 删除一个person对象 *  * @param personId */public void deletePerson(Integer personId) {SQLiteDatabase db = dbOpenHelp.getWritableDatabase();db.delete("person", "id=?", new String[] { personId.toString() });// 上面语句等价于 db.execSQL("delete from person where id=?", new Object[] {// personId.toString() });}/** * 查询一个person *  * @param personId * @return */public Person findPerson(Integer personId) {SQLiteDatabase db = dbOpenHelp.getReadableDatabase();// 如果磁盘空间没满的话,该对象与上面的对象是相等的,如果满了,// 该方法会调用另一只读方法,那么他们就不相等了/** * 1:表名<br> * 2:查找表列名的组合 是一个字符串数组 如果为null的话 则表示全部<br> * 3:查询的条件,可用占位符<br> * 4:是参数3中占位符的值<br> * 5:分组依据<br> * 6:分组筛选语句<br> * 7:排序语句 */Cursor cursor = db.query("person", new String[] { "id", "name" }, "id=?", new String[] { personId.toString() }, null, null, null);// 上面语句等价于 Cursor cursor =// db.rawQuery("select * from person where id=?", new// String[] { personId.toString() });if (cursor.moveToFirst()) {Person person = new Person();person.setId(cursor.getInt(cursor.getColumnIndex("id")));person.setName(cursor.getString(cursor.getColumnIndex("name")));return person;}return null;}/** * 查询分页 *  * @param offSet *            忽略开始的多少条数据 * @param maxResult *            查询的记录数 * @return */public List<Person> findPersonForPage(int offset, int maxResult) {List<Person> persons = new ArrayList<Person>();SQLiteDatabase db = dbOpenHelp.getReadableDatabase();/** * 1:表名<br> * 2:查找表列名的组合 是一个字符串数组 如果为null的话 则表示全部<br> * 3:查询的条件,可用占位符<br> * 4:是参数3中占位符的值<br> * 5:分组依据<br> * 6:分组筛选语句<br> * 7:排序语句<br> * 8:分页语句 传入类似 2,5的字符串<br> */Cursor cursor = db.query("person", null, null, null, null, null, null, offset + "," + maxResult);// 上面语句等价于 Cursor cursor = db.rawQuery("select * from person limit?,?",// new// String[] { String.valueOf(offset), String.valueOf(maxResult) });while (cursor.moveToNext()) {Person person = new Person();person.setId(cursor.getInt(cursor.getColumnIndex("id")));person.setName(cursor.getString(cursor.getColumnIndex("name")));persons.add(person);}cursor.close();return persons;}/** * 查询person表的总记录数 *  * @return */public Long countPerson() {SQLiteDatabase db = dbOpenHelp.getReadableDatabase();Cursor cursor = db.query("person", new String[] { "count(*)" }, null, null, null, null, null);// 上面语句等价于 Cursor cursor = db.rawQuery("select count(*) from person",// null);cursor.moveToFirst();// 一定要将光标移动到第一行 因为光标刚开始处于第一条记录的顶部// moveToFirst可以判断光标是否可以移到下一行并且移到下一行return cursor.getLong(0);}}


这俩个测试类都是一样的 只是实现业务的实例对象不一样 方法都是一样 就不在放源码了 还有sqlite的一个工具

下载地址:http://download.csdn.net/detail/hxy01245120/4546917

用法:

安装好软件之后 先把数据库文件导出来 打开软件

 

 

 

 

 

 




 

原创粉丝点击