Android本地数据存储之SQLite关系型数据库 ——SQLiteDatabase

数据库的创建,获取,执行sql语句:

框架搭建:dao


思考:

1.数据库保存在哪里?

2.如何创建数据库?如何创建表?

3.如何更新数据库?如何更改表的列数据?

4.如何获取数据库?

5.如何修改数据库中的表的数据?


框架思想

思考:如何使得编程更加简单?

一个sql语言,容易写错;

1.使用占位符;

2.框架解析重建法:搭建框架,对增删改查功能进行单独封装,传入容器对象即可;



思考:

1.数据库保存在哪里?

data/data/包名/databases/xiaoo.db

2.如何创建数据库?如何创建表?

db.execSQL("CREATE TABLE person (personid integer primary key autoincrement, name varchar(20))");

3.如何更新数据库?如何更改表的列数据?

db.execSQL("ALTER TABLE person ADD phone VARCHAR(12) NULL ");

4.如何获取数据库?

5.如何修改数据库中的表的数据?



一、创建数据库打开助手:

二、创建dao

三、测试dao

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class MyDBOpenHelper extends SQLiteOpenHelper {

	/**
	 * 
	 * @param context 应用程序上下文
	 * @param name    数据库的名字
	 * @param factory 查询数据库的游标工厂 一般情况下 用sdk默认的
	 * @param version  数据库的版本 版本号必须不小1 
	 *  
	 */
	public MyDBOpenHelper(Context context) {
		super(context, "xiaoo.db", null, 6);
	}

	// 在mydbOpenHelper 在数据库第一次被创建的时候  会执行onCreate();
	@Override
	public void onCreate(SQLiteDatabase db) {
		System.out.println("我被调用了 oncreate");
		db.execSQL("CREATE TABLE person (personid integer primary key autoincrement, name varchar(20))");
	}
        // 通过version的增加来执行数据库版本更新,版本号改为6的同时,调用onUpgrade ,让程序员执行具体更新;
	@Override
	public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
		System.out.println("on update ");
		db.execSQL("ALTER TABLE person ADD phone VARCHAR(12) NULL ");
	}
}

二、创建dao

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;
import cn.itcast.db.MyDBOpenHelper;
import cn.itcast.db.domain.Person;

public class PersonDao {
	private static final String TAG = "PersonDao";
	private MyDBOpenHelper dbOpenHelper;

	// 在personDao被new出来的时候 就完成初始化

	public PersonDao(Context context) {
		dbOpenHelper = new MyDBOpenHelper(context);
		// dbOpenHelper.getReadableDatabase()
		// dbOpenHelper.getWritableDatabase()
	}

	// 增删改查

	/**
	 * 往数据库添加一条数据
	 */
	public void add(String name, String phone) {
		boolean result = find(name);
		if (result)
			return;

		SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
		if (db.isOpen()) {
			db.execSQL("insert into person (name,phone) values (?,?)",
					new Object[] { name, phone });
			// 关闭数据库 释放数据库的链接
			db.close();
		}
	}

	/**
	 * 查找数据库的操作
	 */
	public boolean find(String name) {
		boolean result = false;
		SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
		if (db.isOpen()) {
			Cursor cursor = db.rawQuery("select * from person where name=?",
					new String[] { name });
			if (cursor.moveToFirst()) {
				int index = cursor.getColumnIndex("phone"); // 得到phone在表中是第几列
				String phone = cursor.getString(index);
				Log.i(TAG, "phone =" + phone);
				result = true;

			}
			// 记得关闭掉 cursor
			cursor.close();
			result = false;
			// 释放数据库的链接
			db.close();
		}
		return result;
	}

	/**
	 * 删除一条记录
	 * 
	 * @param name
	 */
	public void delete(String name) {
		SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
		if (db.isOpen()) {
			db.execSQL("delete from person where name =?",
					new Object[] { name });
			db.close();
		}
	}

	/**
	 * 更新一条记录
	 * 
	 */
	public void update(String name, String newname, String newphone) {
		SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
		if (db.isOpen()) {
			db.execSQL("update person set name=? , phone=? where name=?",
					new Object[] { newname, newphone, name });
			db.close();
		}
	}

	/**
	 * 查找全部
	 */
	public List<Person> getAllPersons() {
		List<Person> persons=null;
		SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
		if (db.isOpen()) {
			persons = new ArrayList<Person>();
			Cursor cursor = db.rawQuery("select * from person ", null);
			while (cursor.moveToNext()) {
				Person person = new Person();
				int nameindex = cursor.getColumnIndex("name");
				int phoneindex = cursor.getColumnIndex("phone");
				String name = cursor.getString(nameindex);
				String phone = cursor.getString(phoneindex);
				person.setName(name);
				person.setNumber(phone);
				persons.add(person);
			}
			cursor.close();
			db.close();
		}
		return persons;
	}

}


三、单元测试:测试dao

1.配置

instrumentation 和 uses-library

    <instrumentation
        android:name="android.test.InstrumentationTestRunner"   //使用测试框架中的哪个测试运行器
        android:targetPackage="cn.xiaoo.db" />      //测试哪个工程?

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <uses-library android:name="android.test.runner" />      //该程序需要添加哪个jar包(用于测试)?


2.编程测试

package cn.itcast.db.dao.test;

import java.util.List;

import cn.itcast.db.dao.PersonDao;
import cn.itcast.db.domain.Person;
import android.test.AndroidTestCase;

public class TestPersonDao extends AndroidTestCase {
	PersonDao dao;
	// 测试在执行测试代码时候的流程 
	//1 .new TestPersonDao 框架new出来 
	//2. 调用 setUp()
	//3. testAdd()  这个时候 上下文 才被创建出来 
	
	
/*	@Override
	protected void setUp() throws Exception {
		dao = new PersonDao(getContext());
		super.setUp();
	}*/
	public void testAdd() throws Exception{
		PersonDao dao = new PersonDao(getContext());
		for(int i=0;i<100;i++){
		dao.add("lisi"+i, "123456789"+i);
		}
	}
	public void testdelete() throws Exception{
		PersonDao dao = new PersonDao(getContext());
		dao.delete("lisi99");
	}
	public void testupdate() throws Exception{
		PersonDao dao = new PersonDao(getContext());
		dao.update("lisi98", "wangwu", "120");
	}
	
	public void testFindAll() throws Exception{
		PersonDao dao = new PersonDao(getContext());
		List<Person>  persons  = dao.getAllPersons();
		assertEquals("testFindAll获取集合的大小",98, persons.size());
	}
	
	/**
	 * 测试的流程:
	 */
	/*
	[2012-10-05 13:47:51 - db] ------------------------------
	[2012-10-05 13:47:51 - db] Android Launch!    //系统启动
	[2012-10-05 13:47:51 - db] adb is running normally.   //调试桥正常运行
	[2012-10-05 13:47:51 - db] Performing android.test.InstrumentationTestRunner JUnit launch   //运行测试运行器,启动JUnit
	[2012-10-05 13:47:51 - db] Automatic Target Mode: using existing emulator 'emulator-5554' running compatible AVD '2.3.3_QVGA'
	[2012-10-05 13:47:53 - db] Application already deployed. No need to reinstall.//不需要重新安装
	[2012-10-05 13:47:53 - db] Launching instrumentation android.test.InstrumentationTestRunner on device emulator-5554//在设备上运行测试运行器
	[2012-10-05 13:47:53 - db] Collecting test information //收集运行信息
	[2012-10-05 13:47:56 - db] Sending test information to Eclipse  //发送测试信息到Eclipse
	[2012-10-05 13:47:56 - db] Running tests...    //执行代码
	[2012-10-05 13:47:58 - db] Test run finished   //执行完毕
	*/
 }


框架思想

思考:如何使得编程更加简单?

一条sql语句,容易写错;

操作表
insert into person (name,phone) values (?,?)---------public long insert(String table, String nullColumnHack, ContentValues values)
delete from person where name =?---------------------public int delete(String table, String whereClause, String[] whereArgs)
update person set name=? , phone=? where name=?------public int update(String table, ContentValues values, String whereClause, String[] whereArgs)
select * from person where name=?--------------------public Cursor query(boolean distinct, String table, String[] columns,
                                                                         String selection, String[] selectionArgs, String groupBy,
                                                                         String having, String orderBy, String limit)
insert:在哪张表插入哪些数据?string string contentvalues
delete:在哪张表删除哪些数据?String String String[]
update:在哪张表的那条数据上更改什么数据? String ContentValues String  String[]
query:是否保证唯一?查哪张表?查哪些列?
       什么查询条件?占位符值?分组?
       包含?排序?区间?
操作数据库:
CREATE TABLE person (personid integer primary key autoincrement, name varchar(20))
ALTER TABLE person ADD phone VARCHAR(12) NULL 

怎办办?

1.使用占位符;

2.框架解析重建法:搭建框架,对增删改查功能进行单独封装,传入容器对象即可;

1.原生:  db.execSQL("insert into person (name,age) values ("xiaoli",20)");

2.站位符:db.execSQL("insert into person (name,age) values (?,?)",new Object[]{"xiaoli",20});

3.框架 :

            ContentValues values = new ContentValues();
            values.put("name", name);
            values.put("age", age);
            db.insert("person", null, values);

 public void add(String name, int age) {
        SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
        if (db.isOpen()) {
           
            ContentValues values = new ContentValues();
            values.put("name", name);
            values.put("age", age);
            // 如果 contentvalues为空
            db.insert("person", null, values); // 组拼sql语句完成的添加的操作
            
            // insert into person name values (NULL) ;
            db.close();
        }
}

最复杂的方法是查询:query

我们一起来看看底层是怎么封装的:

    public static String buildQueryString(
            boolean distinct, String tables, String[] columns, String where,
            String groupBy, String having, String orderBy, String limit) {
        if (TextUtils.isEmpty(groupBy) && !TextUtils.isEmpty(having)) {
            throw new IllegalArgumentException(
                    "HAVING clauses are only permitted when using a groupBy clause");
        }
        if (!TextUtils.isEmpty(limit) && !sLimitPattern.matcher(limit).matches()) {
            throw new IllegalArgumentException("invalid LIMIT clauses:" + limit);
        }

        StringBuilder query = new StringBuilder(120);

        query.append("SELECT ");
        if (distinct) {
            query.append("DISTINCT ");
        }
        if (columns != null && columns.length != 0) {
            appendColumns(query, columns);
        } else {
            query.append("* ");
        }
        query.append("FROM ");
        query.append(tables);
        appendClause(query, " WHERE ", where);
        appendClause(query, " GROUP BY ", groupBy);
        appendClause(query, " HAVING ", having);
        appendClause(query, " ORDER BY ", orderBy);
        appendClause(query, " LIMIT ", limit);

        return query.toString();
    }


另一种增删改查:dao


import java.util.ArrayList;
import java.util.List;

import cn.itcast.db.MyDBOpenHelper;
import cn.itcast.db.domain.Person;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;

public class PersonDBDao {
	private Context context;
	MyDBOpenHelper dbOpenHelper;

	public PersonDBDao(Context context) {
		this.context = context;
		dbOpenHelper = new MyDBOpenHelper(context);
	}

	/**
	 * 添加一条记录
	 */
	public void add(String name, int age) {
		SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
		if (db.isOpen()) {
			// db.execSQL("insert into person (name,age) values (?,?)",new
			// Object[]{name,age});
			// db.execSQL("insert into person ",null) // 不合法的sql语句
			ContentValues values = new ContentValues();
			values.put("name", name);
			values.put("age", age);
			// 如果 contentvalues为空
			db.insert("person", null, values); // 组拼sql语句完成的添加的操作
			
			// insert into person name values (NULL) ;
			db.close();
		}

	}

	/**
	 * 删除一条记录
	 */
	public void delete(String name) {
		SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
		if (db.isOpen()) {
			db.delete("person", "name=?", new String[] { name });
			db.close();
		}
	}

	/**
	 * 数据库的更改操作
	 */
	public void update(String name, String newname, int newage) {
		SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
		if (db.isOpen()) {
			ContentValues values = new ContentValues();
			values.put("name", newname);
			values.put("age", newage);
			db.update("person", values, "name=?", new String[] { name });
			db.close();
		}
	}

	/**
	 * 数据库的查询操作
	 */
	public boolean find(String name) {
		boolean result = false;
		SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
		if (db.isOpen()) {
			// select * from person
			Cursor cursor = db.query("person", null, "name=?",
					new String[] { name }, null, null, null);
			if (cursor.moveToFirst()) {
				result = true;
			}
			cursor.close();
			db.close();
		}
		return result;

	}

	/**
	 * 查询所有信息
	 */
	public List<Person> findAll() {
		List<Person> persons = null;
		SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
		if (db.isOpen()) {
			Cursor cursor = db.query("person", null, null, null, null, null,
					null);
			persons = new ArrayList<Person>();
			while (cursor.moveToNext()) {
				Person person = new Person();
				String name = cursor.getString(cursor.getColumnIndex("name"));
				person.setName(name);
				int age = cursor.getInt(cursor.getColumnIndex("age"));
				person.setAge(age);
				persons.add(person);
			}
			cursor.close();
			db.close();
		}
		return persons;
	}
	/**
	 * 查询所有信息
	 */
	public Cursor findAllbyCursor() {
		SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
		if (db.isOpen()) {
			/*Cursor cursor = db.query("person", null, null, null, null, null,
					null);*/
			Cursor cursor = db.rawQuery("select personid as _id,age,name from person", null);
			
			return cursor;
			// 注意了  一定不要把数据库 关闭了 
			}
		return null;
		
	}

       /**
        * 银行转账的方法
        * 1.开始事务:db.beginTransaction();
        * 2.设置事务成功:db.setTransactionSuccessful();
        * 3.结束事务:db.endTransaction();
        * 4.关闭连接:db.close();
        */
	public void transaction() {
		SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
		if (db.isOpen()) {

			try {
				// 开启数据库的事务
				db.beginTransaction();
				// 给张三设置1000块钱的账户
				db.execSQL("update person set account=? where name=?",
						new Object[] { 1000, "zhangsan98" });
				// 把张三的账户扣除200块钱
				db.execSQL("update person set account=account-? where name=?",
						new Object[] { 200, "zhangsan98" });
				// 出现了异常
				// 把张三的钱给李四
				//初始化李四账户 为 0
				db.execSQL("update person set account=? where name=?",
						new Object[] { 0, "lisi" });
				db.execSQL("update person set account=account+? where name=?",
						new Object[] { 200, "lisi" });
				db.setTransactionSuccessful();
			}
			// 显示的设置事务是否成功
			catch (Exception e) {
				// TODO: handle exception
			} finally {
				db.endTransaction();
				db.close();
			}
		}
	}
}
  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值