2015.07.22

距离上一次记录已经有5天时间了......这几天进度比较慢.主要是一直在纠结一些问题(后面会说到).最终将数据库封装好了!进度条又跳了一节有木有!!!

其实进度慢的原因主要是在纠结该怎么写.看了很多别人的写法,总感觉没办法用在我这里.一开始纠结要不要用SQLite,打算直接用读文件绑定控件的,后来发现行不通,还是得乖乖用SQLite.于是问题来了----怎么具体化这个数据库?其实面临的问题无非是一下几个

a.怎么创建数据库?

b.准备让数据库具有什么功能?

c.如何将单词表封装到数据库中?

d.如何将数据库和控件绑定----也就是让单词显示在屏幕上

e.如何处理进度问题和其他细节(比如占用更少资源,怎么避免重复创建等等)?

以上这些问题是我这几天来思考良久想到的接下来急需解决的问题,其他的细节可以暂且放在一边.今天主要记录的是数据库的准备工作.

本文基本上是参考scott's blog的代码改写的.本质上是重复.我下面会贴出代码还有相应简略的介绍,更多细节请移步http://blog.csdn.net/liuhe688/article/details/6715983/  查看:

1.常用方法概述:

//打开或创建test.db数据库  SQLiteDatabase db = openOrCreateDatabase("test.db", Context.MODE_PRIVATE, null);  db.execSQL("DROP TABLE IF EXISTS person");  //创建person表  db.execSQL("CREATE TABLE person (_id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR, age SMALLINT)");  Person person = new Person();  person.name = "john";  person.age = 30;  //插入数据  db.execSQL("INSERT INTO person VALUES (NULL, ?, ?)", new Object[]{person.name, person.age});  person.name = "david";  person.age = 33;  //ContentValues以键值对的形式存放数据  ContentValues cv = new ContentValues();  cv.put("name", person.name);  cv.put("age", person.age);  //插入ContentValues中的数据  db.insert("person", null, cv);  cv = new ContentValues();  cv.put("age", 35);  //更新数据  db.update("person", cv, "name = ?", new String[]{"john"});  Cursor c = db.rawQuery("SELECT * FROM person WHERE age >= ?", new String[]{"33"});  while (c.moveToNext()) {  int _id = c.getInt(c.getColumnIndex("_id"));  String name = c.getString(c.getColumnIndex("name"));  int age = c.getInt(c.getColumnIndex("age"));  Log.i("db", "_id=>" + _id + ", name=>" + name + ", age=>" + age);  }  c.close();  //删除数据  db.delete("person", "age < ?", new String[]{"35"});  //关闭当前数据库  db.close();  //删除test.db数据库  deleteDatabase("test.db");  

这些是比较基础的,对于插入删除我们还有:

db.executeSQL(String sql);
db.executeSQL(String sql, Object[] bindArgs);//sql语句中使用占位符,然后第二个参数是实际的参数集
db.insert(String table, String nullColumnHack, ContentValues values);
db.update(String table, Contentvalues values, String whereClause, String whereArgs);
db.delete(String table, String whereClause, String whereArgs);  

对于查询操作,可以这样:

db.rawQuery(String sql, String[] selectionArgs);
db.query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy);
db.query(String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit);
db.query(String distinct, String table, String[] columns, String selection, String[] selectionArgs, String groupBy, String having, String orderBy, String limit);

他们最终都返回一个Cursor对象,其操作有:

c.move(int offset);  //以当前位置为参考,移动到指定行
c.moveToFirst();    //移动到第一行
c.moveToLast();     //移动到最后一行
c.moveToPosition(int position); //移动到指定行
c.moveToPrevious(); //移动到前一行
c.moveToNext();     //移动到下一行
c.isFirst();        //是否指向第一条
c.isLast();     //是否指向最后一条
c.isBeforeFirst();  //是否指向第一条之前
c.isAfterLast();    //是否指向最后一条之后
c.isNull(int columnIndex);  //指定列是否为空(列基数为0)
c.isClosed();       //游标是否已关闭
c.getCount();       //总数据项数
c.getPosition();    //返回当前游标所指向的行数
c.getColumnIndex(String columnName);//返回某列名对应的列索引值
c.getString(int columnIndex);   //返回当前行指定列的值

具体细节参见链接.

2.具体在app里面的实现:

我将和数据库有关的文件单独建了一个包.这三个文件中:DBHelper是一个继承SQLiteOpenHelper的子类,他的作用是替我们生成一个生成一个新的数据库,并且含有一个更新版本的操作,这两个方法会在onCreate方法执行后启动.具体代码见下:

<span style="font-family:SimSun;">package mywordapp.wordsqlite;import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;public class DBHelper extends SQLiteOpenHelper{private static final String DATABASE_NAME = "vocabulary_db";private static final int DATABASE_VERSION = 1;public DBHelper(Context context){//CursorFactory 设置为默认值nullsuper(context, DATABASE_NAME, null, DATABASE_VERSION);}//数据库第一次被创建时onCreate会被调用@Overridepublic void onCreate(SQLiteDatabase db) {db.execSQL("CREATE TABLE IF NOT EXISTS word"+"(_id INTEGER PRIMARY KEY AUTOINCREMENT,en_meaning VARCHAR,cn_meaning VARCHAR,repeating_number INTEGER)");}//如果DATABASE_VERSION的值被改成2,系统发现现有数据库版本不同,就会调用onUpgrade@Overridepublic void onUpgrade(SQLiteDatabase db,int oldVersion,int newVersion){db.execSQL("ALTER TABLE word ADD COLUMN other STRING");}
}</span>

当然,在生成数据库之前,写一个相关的对象是必要的,这就是Word类.它代表的就是单词这个类,其中的属性我目前只设置了三个----分别是en_meaning(单词的英文),cn_meaning()单词的中文释义,repeating_number(已经记忆的遍数),但让还有id,这个是数据库默认的.非常简单,注意每个属性都必须要get和set方法,至于单独写还是写成一个函数看自己了,这里不在多说.有了这个类之后,我们便可以着手将一些常用的功能封装在DBManager这个类里面以便我们后续的操作:

<span style="font-family:SimSun;">package mywordapp.wordsqlite;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;public class DBManager {private DBHelper helper;private SQLiteDatabase db;public DBManager(Context context){helper=new DBHelper(context);db=helper.getWritableDatabase();}/** 添加单词*/public void add(List<Word> words){db.beginTransaction();try{for (Word word : words) {db.execSQL("INSERT INTO word VALUES(null,?,?,?)",new Object[]{word.en_meaning,word.cn_meaning,word.repeating_number});}db.setTransactionSuccessful();}finally{db.endTransaction();}}/*更新记忆次数*/public void updateRepeating_Number(Word word) {ContentValues cv=new ContentValues();cv.put("repeating_number", word.repeating_number);db.update("word", cv, "en_meaning=?", new String[]{word.en_meaning});}/*删除烂熟的单词*/public void deleteAdroidWord(Word word) {  db.delete("word", "repeating_number >=40", new String[]{String.valueOf(word.repeating_number)});  }  /*查询所有单词,返回一个完整的单词表*/public List<Word> query() {ArrayList<Word> words=new ArrayList<Word>();Cursor csr=queryTheCursor();while (csr.moveToNext()) {Word word = new Word();word._id=csr.getInt(csr.getColumnIndex("_id"));word.en_meaning=csr.getString(csr.getColumnIndex("en_meaning"));word.cn_meaning=csr.getString(csr.getColumnIndex("cn_meaning"));word.repeating_number=csr.getInt(csr.getColumnIndex("repeating_number"));}return words;}public Cursor queryTheCursor() {Cursor c=db.rawQuery("SELECT*FROM word", null);           return c;}/*关闭数据库*/public void closeDB(){db.close();}
}</span>

我们在DBManager构造方法中实例化DBHelper并获取一个SQLiteDatabase对象,作为整个应用的数据库实例;在添加多个Person信息时,我们采用了事务处理,确保数据完整性;最后我们提供了一个closeDB方法,释放数据库资源,这一个步骤在我们整个应用关闭时执行,这个环节容易被忘记,所以要注意一下。至于选择获取可写数据库而不是只读数据库的原因,我没有深究,有兴趣的可以看一下链接中的解释.

3.控件的设置

经过以上的设置,数据库已经有框架了,万事俱备,只欠东风----东风就是我们单词表.限于能力和自己的惰性,我没有去学习比较可行的模式:诸如读写缓存,读写SDcard,读写raw之类的方法.我的做法很原始----利用asset里面的文件不会被压缩的特性将单词表的txt格式存入,然后用读写文件的方式将它里面的内容导入数据库.

<span style="font-family:SimSun;">package example.mywordapp;import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;import org.apache.http.util.EncodingUtils;import android.app.Activity;
import android.database.Cursor;
import android.database.CursorWrapper;
import android.os.Bundle;
import android.view.View;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.SimpleCursorAdapter;
import mywordapp.wordsqlite.DBManager;
import mywordapp.wordsqlite.Word;
public class MySQLiteActivity extends Activity{private DBManager mgr;private ListView listView;@Overridepublic void onCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_sqlite);listView=(ListView)findViewById(R.id.listView);//初始化DBManagermgr=new DBManager(this);}//添加单词public void add(View view) {ArrayList<Word> words=new ArrayList<Word>();String fileName = "GRE.txt"; //单词表名字  ,文件要放在asset文件夹下String res="";   try{   //得到资源中的asset数据流  InputStream in = getResources().getAssets().open(fileName);   int length = in.available();           byte [] buffer = new byte[length];          in.read(buffer);              in.close();  res = EncodingUtils.getString(buffer, "UTF-8");       }catch(Exception e){   e.printStackTrace();           } String []tmp=res.split("\n");for(int i=0;i<tmp.length;i++){String []tmp_word=tmp[i].split(" ");System.out.println(i+1+"  "+tmp_word[0]+"      "+tmp_word[1]);Word word=new Word(tmp_word[0],tmp_word[1],0);words.add(word);}mgr.add(words);}//更新记忆次数public void update(View view){Word word=new Word();word.en_meaning="son";word.repeating_number=1;mgr.updateRepeating_Number(word);}//利用HashMap获得单词以便查询public void query(View view) {  List<Word> words = mgr.query();  ArrayList<Map<String, Integer>> list = new ArrayList<Map<String, Integer>>();  for (Word word : words) {  HashMap<String, Integer> map = new HashMap<String, Integer>();  map.put("repeating_number", word.repeating_number);  //map.put("en_meaning", word.en_meaning);  list.add(map);  }  SimpleAdapter adapter = new SimpleAdapter(this, list, android.R.layout.simple_list_item_2,  new String[]{"en_meaning"}, new int[]{android.R.id.text1});  listView.setAdapter(adapter); }  //删除烂熟的单词public void delete(View view) {  Word word = new Word();  word.repeating_number = 40;  mgr.deleteAdroidWord(word);} //全体查询,返回的是整个单词表,然后利用SimpleAdapter和ListView绑定在一起//注意要确保查询结果中有"_id"列  @SuppressWarnings("deprecation")public void queryTheCursor(View view) {  Cursor c = mgr.queryTheCursor();  startManagingCursor(c); //托付给activity根据自己的生命周期去管理Cursor的生命周期  CursorWrapper cursorWrapper = new CursorWrapper(c) {  @Override  public String getString(int columnIndex) {  //在英文后加上中文if (getColumnName(columnIndex).equals("en_meaning")) {  String cn_meaning = getString(getColumnIndex("cn_meaning"));  return  super.getString(columnIndex)+"   "+cn_meaning;  }  return super.getString(columnIndex);  }  };  //下面是在绑定语句----其结果是每个list显示两行:第一行是单词+释义,第二行是记忆次数.SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, android.R.layout.simple_list_item_2,   cursorWrapper, new String[]{"en_meaning", "repeating_number"}, new int[]{android.R.id.text1, android.R.id.text2});  ListView listView = (ListView) findViewById(R.id.listView);  listView.setAdapter(adapter);  }
}</span><span style="font-family:SimHei;">
</span>

注意的一点是加入调试的时候发现logcat里面显示id列找不到证明你的word类里面的id列的名称不是"_id",这个很重要,解决办法是要么按规范做(列名称改为_id而不是id),要么在数据库里面的查询语句该名称(声明在id里面查而不是_id)

以上就是建立数据库的全过程,进度条感觉前进了好大一截!!!好开森!!!!

接下来是考虑如何将单词导入进去,加油!!!!

背单词App开发日记3相关推荐

  1. 背单词App开发日记5(上)

    2015.07.28 今天是我阳历生日,先自己庆祝一下!哈哈. 为什么总是写博客的时间和发博客的时间不一样那?这我也没办法啊.....因为每天花在这上面的时间比较少,所以做完一项的时间很长(回家全是事 ...

  2. 背单词App开发日记5(下)

    2015.08.06 自上次实现可用控件显示不同的单词之后,经过自己的调试我终于实现了显示单词的前提工作----读取进度和今日计划.下面分别记录一下: 1.读取进度和今日计划 既然是背单词软件必然需要 ...

  3. 基于AndroidStudio+Java+SQLite开发的背单词APP系统

    目 录 第一章 绪论 1 1.1 选题设计开发的应用背景及价值 1 1.2 选题的研究现状 1 1.3 关于本课题 2 第二章 开发环境与主要技术 3 2.1 开发平台 3 2.2 主要技术 4 2. ...

  4. 免费自定义txt背单词APP(其它科目也可以)

    需求: 本人觉得现有的背单词 APP 不能满足自己的需要(其实是自己懒的找,或者某些APP要收费),个性化不足,因此根据 自己的需要开发了一个背单词 APP 供自己使用. 代码免费下载地址: http ...

  5. 考研词汇测试软件,考研有哪些好用的背单词APP神器

    原标题:考研有哪些好用的背单词APP神器 英语单词大家都很脑阔疼吧,但是不背又不行,目前市面上背单词的啊婆婆(APP)这么多,想挑一款适合考研用的应该很费时间吧,不用担心了,今天给大家推荐几个备受考研 ...

  6. 背单词app软件测试与评估

    一.计划说明 1.本小组选择的对比测试产品是百词斩和不背单词. 2.Psp表格  测试进度表 项目 内容说明 预估耗时 (分钟) 实际耗时 (分钟) Planning 计划 10 10 · Estim ...

  7. 基于Jquery编写的背单词app

    这是我的第一款基于Jquery编写的背单词app,使用Hbuilder工具,借助Eclipse软件,可以实现在手机直接安装app.该app界面比较简单,但主要是关于内容展现的,不涉及到数据库,所以看起 ...

  8. 还在用背单词App?使用Python开发英语单词自测工具,助你逆袭单词王!

    学英语广告 最近也许是刚开学的原因,不管是公众号,还是刷抖音,导出都能看到关于学英语.背单词的广告. 不知道现在学生们背单词买的什么辅导材料.反正我们上学那会,<星火阅读>特别的火.记得当 ...

  9. python单词软件哪个好_还在用背单词App?使用Python开发英语单词自测工具,助你逆袭单词王!...

    学英语广告 最近也许是刚开学的原因,不管是公众号,还是刷抖音,导出都能看到关于学英语.背单词的广告. 不知道现在学生们背单词买的什么辅导材料.反正我们上学那会,<星火阅读>特别的火.记得当 ...

  10. 扇贝和不背单词_你还没找到中意的背单词APP?我都试过,我来帮你盘点盘点

    为了背单词,我试了很多APP(感觉相亲似的哈哈哈),这是主要的几个.现在,我来给大家盘点盘点. 呐~就是上面六款APP啦~跟着我的脚步来看一看吧 这里的每款软件都可以自己选择词书,查看单词列表,个性化 ...

最新文章

  1. (0026)iOS 开发之模块化封装初步实践
  2. 西门子标准报文1常用_基于Snap7使用C#编程访问西门子PLC系列教程(2)-S7协议
  3. 关于 Method Swizzing方法
  4. JAVA程序设计计时器代码_Java中的定时器Timer使用示例代码详解
  5. 多选取值_机制砂如何控制MB值和石粉含量
  6. IPC--进程间通信三(共享内存)
  7. tushare pro接口_Python与交易策略分析amp;tushare/baostock库介绍(附代码)
  8. 触发事件_SAP 通过事件触发后台JOB
  9. git 使用笔记(一)
  10. 说说微信聊天记录收费这件事
  11. 年仅44岁,又一高校教师英年早逝
  12. cvHoughLines2() 霍夫线变换
  13. 遥控器进入鼠标模式,退出鼠标模式,上下左右移动和确认
  14. 理财笔记 - 关于沪深300指数基金
  15. linux aufs,UnionFS有什么用?AUFS的一些特性
  16. Python网速监控
  17. python图像白色背景变透明
  18. winmerge多个文件夹生成html,功能强大的文件、文件夹比对工具-WinMerge使用教程
  19. 【Docker基本原理和常用命令】
  20. 802.11--802.11ac协议

热门文章

  1. wordpress网站添加百度导航地图
  2. Python--邮件处理
  3. android 实现重力感应,Android重力感应实现方式是怎样实现的?
  4. Unity3D高级编程之进阶主程-陆泽西 (Jesse Lu)
  5. PyTorch注意力机制【动手学深度学习v2】
  6. 关于360评估的全面介绍
  7. 基于bootstrap的二维码支付系统webAPP设计
  8. 揭秘:顶级产品经理是如何写产品需求文档(PRD)的
  9. 学校计算机社团面试问题及答案,社团二轮面试题目
  10. 人到中年,没事多休息,有空多赚钱!