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, ); } // 在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()); ;i<;i++){ dao.add("+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("); } public void testFindAll() throws Exception{ PersonDao dao = new PersonDao(getContext()); List<Person> persons = dao.getAllPersons(); assertEquals(, 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()) ALTER TABLE person ADD phone VARCHAR() NULL
怎办办?
1.使用占位符;
2.框架解析重建法:搭建框架,对增删改查功能进行单独封装,传入容器对象即可;
.原生: db.execSQL("insert into person (name,age) values ("xiaoli",20)"); .站位符:db.execSQL(}); .框架 : 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 = ); query.append("SELECT "); if (distinct) { query.append("DISTINCT "); } ) { 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=?", , "zhangsan98" }); // 把张三的账户扣除200块钱 db.execSQL("update person set account=account-? where name=?", , "zhangsan98" }); // 出现了异常 // 把张三的钱给李四 //初始化李四账户 为 0 db.execSQL("update person set account=? where name=?", , "lisi" }); db.execSQL("update person set account=account+? where name=?", , "lisi" }); db.setTransactionSuccessful(); } // 显示的设置事务是否成功 catch (Exception e) { // TODO: handle exception } finally { db.endTransaction(); db.close(); } } } }
Android本地数据存储之SQLite关系型数据库 ——SQLiteDatabase的更多相关文章
- Android本地数据存储复习
Android本地数据存储复习 Android无论是应用层还是系统层都需要在本地保存一些数据,尤其在应用层中使用的就更为普遍,大体有这么几种:SharedPreference,file,sqlite数 ...
- Spring Boot干货系列:(八)数据存储篇-SQL关系型数据库之JdbcTemplate的使用
Spring Boot干货系列:(八)数据存储篇-SQL关系型数据库之JdbcTemplate的使用 原创 2017-04-13 嘟嘟MD 嘟爷java超神学堂 前言 前面几章介绍了一些基础,但都是静 ...
- Android本地数据存储: ASimpleCache
一:前言 在上一篇博客Android本地数据存储: Reservoir 博客中,我提到,除了Reservoir库,还可以采用ASimpleCache开源库,来实现本地数据存储.昨天并没有仔细的对比Re ...
- Android之ListView,AsyncTask,GridView,CardView,本地数据存储,SQLite数据库
版权声明:未经博主允许不得转载 补充 补充上一节,使用ListView是用来显示列表项的,使用ListView需要两个xml文件,一个是列表布局,一个是单个列表项的布局.如我们要在要显示系统所有app ...
- Android本地数据存储: Reservoir
一:前言 今天做项目,准备使用本地存储,把一些数据存在本地磁盘上,比如用户名.密码这样的.其实大家都知道,这种情况最常用的就是SharedPreferences了,我也不例外,脑子里第一个想到的就是用 ...
- 理解 Android 本地数据存储 API
利用首选项.SQLite 和内部及外部内存 API 对于需要跨应用程序执行期间或生命期而维护重要信息的应用程序来说,能够在移动设备上本地存储数据是一种非常关键的功能.作为一名开发人员,您经常需要存储诸 ...
- android之数据存储之SQLite
SQLite开源轻量级数据库,支持92-SQL标准,主要用于嵌入式系统,只占几百K系统资源此外,SQLite 不支持一些标准的 SQL 功能,特别是外键约束(FOREIGN KEY constrain ...
- 大数据时代的数据存储,非关系型数据库MongoDB
在过去的很长一段时间中,关系型数据库(Relational Database Management System)一直是最主流的数据库解决方案,他运用真实世界中事物与关系来解释数据库中抽象的数据架构. ...
- Android:数据存储之SQLite
Android在运行时集成了SQLite , 所以每个Android应用程序都可以使用SQLite数据库. 我们通过SQLiteDatabase这个类的对象操作SQLite数据库,而且不需要身份验证. ...
随机推荐
- JavaScript中局部变量与全局变量的不同
JavaScript中局部变量与全局变量 我们知道,JavaScript的变量是松散型的变量,也就是说,其变量只需用var声明,其赋值的类型是不限定的.比如: var person=18; perso ...
- C#编写滤镜 图片色调取反效果(Invert)
转自:http://www.it165.net/pro/html/201208/3469.html Invert 英文叫做颠倒.. 原理很简单也就是 将 255- 原本的值.. 这样 0(黑) 就会变 ...
- 20145212 《Java程序设计》第10周学习总结
20145212 <Java程序设计>第10周学习总结 学习内容总结 一.Java的网络编程 网络编程是指编写运行在多个设备(计算机)的程序,这些设备都通过网络连接起来. java.net ...
- Java数据结构——栈
//================================================= // File Name : Stack_demo //-------------------- ...
- dedecms标签的sql语句
{dede:sql sql='Select content from dede_arctype where id=1' titlelen='40′} [field:content/] {/dede:s ...
- -[UIWindow viewForFirstBaselineLayout]: unrecognized selector sent to instance
#ifdef DEBUG #import <UIKit/UIKit.h> #import <objc/runtime.h> @implementation UIView (Fi ...
- 如何使Python完美升级到新版本
这里提供一种解决的方法 (加上一句话,发现一个新问题:这种方法yum update 后,需要将/usr/bin下的python文件删除,然后执行: # ln -s /usr/local/python2 ...
- sqlserver权限体系(下)
简介 在上一篇文章中,我对主体的概念做了全面的阐述.本篇文章接着讲述主体所作用的安全对象以及所对应的权限. 理解安全对象(Securable) 安全对象,是SQL Server 数据库引擎授权系统控制 ...
- tmux常用命令
tmux命令可以启动一个tmux服务,tmux服务包含多个session,session包含多个window,window包含多个pane. 常用命令tmux ls #显示已有tmux列表(C-b s ...
- 把字符转换为 HTML 实体
把字符转换为HTML实体:htmlentities() 把HTML实体转换回字符:html_entity_decode() 把预定义的字符 "<" (小于)和 "& ...