android sqlite数据库增删改查

需要测试环境,启动模拟器 不需要对模拟器进行操作 只用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

用法:

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

 

 

 

 

 

 




 

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值