android之SQLite项目分析

            android在数据存储和访问方面有四个,分别是SharedPreferences、文件存储、SQLiteContentProvider。这篇 博客只写SQLite,另外三,个人感觉不太难,花点时间看下,就能明白。学习时用到了SQLite,有例子,所以好讲点。废话不多 说,先上代码,在代码中分步讲解

要使用SQLite,写一个帮助类(DBHelper)继承SQLiteOpenHelper是必须的,不要问为什么(它是abstract的),不知道,大家都这么写的。

public class DBHelper extends SQLiteOpenHelper {
    private static final String SQLNAME="dataBase.db";//创建数据库名,后缀名(.db)可以有,可以没有
    private static final int VERSION=1;

    //这个构造函数必须有,后面会用到(步骤"三"中init()),里面参数主要是上下文,数据库名,游标(基本上用不到),数据库版本号
    public DBHelper(Context context) {
        super(context, SQLNAME, null, VERSION);
        
    }

    //onCreate()函数是覆写SQLiteOpenHelper这个超类的,也是必须有
    @Override
    public void onCreate(SQLiteDatabase db) {

        /**表中的字段主要有一下几种类型:null,integer,real(浮点数字),text(字符串文本) ,varchar,char,decimal(k,v)等数据类型

        这些类型的长度不是固定的,例如表aerobic中time text(10),其实不止这么长,可以填更长,

        还有一点是,虽然知道类型是text或者是varchar,但是可以往这个字段上存入任何类型,例如往varchar字段上存boolean类型都行

        在dataBase.db中创建三个表,每个表中的id是integer primary key这个没什么好讲的,主键嘛,id也有写成integer primary key autoincrement

        这两个有什么不同。我也没发现,刚测试了一下,都一样,如果有谁知道的,麻烦告知下

        */

        String aerobic="create table aerobic (id integer primary key,time text(10),journey varchar(10),pulmonary varchar(10))";
    
        db.execSQL(aerobic);
    }

    //这个方法,是更新数据库版本用,基本上用不到
    @Override
    public void onUpgrade(SQLiteDatabase arg0, int arg1, int arg2) {

    }

}


写一个操作类,这个操作类是对DBHelper进行操作使用

/**

      这里解释getWritableDatabase()和getReadableDatabase()的区别。

     它们都可以获取SQLiteDatabase的一个实例,这个实例使用来操作数据库用的,例子中是db

     区别:getWritableDatabase()是以读写的方式打开数据库,如果磁盘空间没满的话(这里是android系统的手机或平板中的内存),那么就正常对数据库访问

     如果倒霉的话,磁盘空间满了,那么只能读而不能写了,如果再次使用它实例化SQLiteDatabase的db去往数据库写东西,那么很不幸,就会报错

     getReadableDatabase()也是读写方式(这里的读写是指这个方法里面有getWritableDatabase(),查看源代码会发现,它里面有getWritableDatabase()方法)打开

     数据库,如果磁盘空间满了,就会打开失败,但是它会以读的方式访问数据库

     注意:在这个类中,有add()、query()等方法,在这些方法中,我有时用db.execSQL()语句,有时用的是SQLiteDatabase自带的方法,为的是操作方便,还望谅解

*/

public class DBHelperOperate{
    private DBHelper helper;
    private SQLiteDatabase db;
    
    public DBHelperOperate(Context context)
    {
        helper=new DBHelper(context);

    }

    //3.3.5

    //三个参数是自定义的,分别是,表名,要插入的字段,添加进数据库的内容
    public void add(String table,String nullColumnHack,ContentValues values)

    {

        //这里没有db.close(),因为在手机或者平板上我们使用SQLite时,并不会牵扯到多用户访问这个数据库,所以可以一直保持链接,这对提高效率很有用

        db=helper.getWritableDatabase();
        db.insert(table, nullColumnHack, values);
        
    }
    //这个方法给注释了,因为在开发时,没用到删除数据库操作,而是最后直接删除表,再创建表
    /*public void delete(String sql,Object[] objs)
    {
        db=helper.getWritableDatabase();
        db.execSQL("delete from aerobic where id=?", objs);
        
        

    }*/

    //3.2

    //这里可能会看不懂,查询的结果是存放到lists集合当中,Information是自定义的一个类,是javabean类,因为我在做开发时,用到了android绘图,因为需要才这么做的

    //这个方法中用到了Cursor,顾名思义,是个光标,是用来操作表的,cursor.moveToNext()是将光标先移到表的最前端,然后再一个一个读每条数据

    public  ArrayList<Information> query(String table,String key)
    {
        db=helper.getWritableDatabase();
        
        Cursor cursor=db.query(table, null, null, null,
                null, null, null, null);
        
        Information informationData=null;
        ArrayList<Information> lists=new ArrayList<Information>();

        while(cursor.moveToNext()){

            //cursor.getDouble()是取出某个字段的值,但是是那个字段的值?(里面的cursor.getColumnIndex("journey")就是具体到读哪个字段)

            //取出以后还是以javabean的方式存到Infroamtion中

            double jounery=cursor.getDouble(cursor.getColumnIndex("journey"));
            double purposeVal=cursor.getDouble(cursor.getColumnIndex(key));
            String time=cursor.getString(cursor.getColumnIndex("time"));
            
            informationData=new Information(jounery,purposeVal,time);
            lists.add(informationData);
        }
        return lists;
        

    }

     //3.3.4

    //更新数据库,看不懂没关系,会有一个类专门来操作这个类中的诸多方法,参数都是在那个类中传进来的
    public boolean update(String table,ContentValues values,String whereClause,String[] whereArgs)
    {
        db=helper.getWritableDatabase();
        db.update(table, values, whereClause, whereArgs);
        return false;
        
    }

     //3.3.3

    public List<Double> find(String sql,String time,String key)
    {
        List<Double> lists=new ArrayList<Double>();
        db=helper.getWritableDatabase();
        Cursor cursor=db.rawQuery(sql, 
                        new String[]{time});
        while(cursor.moveToNext())
        {

            lists.add(cursor.getDouble(cursor.getColumnIndex("journey")));
            lists.add(cursor.getDouble(cursor.getColumnIndex(key)));
            
        }
        return lists;
    }

    //分页,将数据库中某个表从某条数据从哪到哪取出,这个我真开发过程中没用到,不过这里会大致介绍下,limit  3,6 的意思是:从某个表中取出数据,但是要忽略

    //前面的3条后再取6条数据

    public List<Map<String, String>> getScrollData(int min,int max)
    {
        //List<String> lists=new ArrayList<String>();
        List<Map<String, String>> lists=new ArrayList<Map<String,String>>();
        Map<String, String> maps=new HashMap<String, String>();
        db=helper.getWritableDatabase();
        //Cursor cursor=db.rawQuery(sql, objs);
        Cursor cursor=db.rawQuery("select * from aerobic limit ?,?",
                                    new String[]{String.valueOf(min),String.valueOf(max)});
        
        while(cursor.moveToNext())
        {
            
            String time=cursor.getString(cursor.getColumnIndex("time"));
            String journey=cursor.getString(cursor.getColumnIndex("journey"));
            
            
            maps.put("time", time);
            maps.put("journey", journey);
            
            lists.add(maps);
        }
        return lists;
        
    }
    
    //3.1.1
    //获取数据库中某个表中的数据条数
    public long getCount(String sql)
    {
        db=helper.getWritableDatabase();
        Cursor cursor=db.rawQuery(sql, null);
        if(cursor.moveToNext())
        {
            return cursor.getLong(0);
        }
        return 0;

    }

     //3.1.2

    //删除表,在注释的delete方法中,说了不删除单个数据,只删整个表
    public void deleteSql(String sql)
    {
        db=helper.getWritableDatabase();
        db.execSQL(sql);
        
    

    }

    //3.1.2

    //创建deleteSql()中删除的表
    public void createNew(String sql)
    {
        db=helper.getWritableDatabase();
        db.execSQL(sql);
    }
    
    
    

}


.具体实现,上面的代码肯定看的很糊涂,因为根本不知道那里用到数据库了,那么下面你再坚持下,就知道了

public class AerobicMethod extends Activity{
    private String sqlGetCount="select count(id) from aerobic";
    private String sqlDeleteTable="drop table if exists aerobic";
    private String sqlCreateTable="create table aerobic (id integer primary key,time text(10),journey varchar(10),pulmonary varchar(10))";
    private String sqlFind="select * from aerobic where time=?";
    private DBHelperOperate dbHelperOperate;
    public ArrayList<Information> dataList=null;
    private long start;//一进入这个activity时的时间,结合savaData()中end使用,就是要存放到表中,time的值,具体看savaData()和saveAerobicMethod()
    private double journey;//要存放到表中,pulmonary键的值
    private double pulmonary=0.0;//要存放到表中,journey键的值
    private String sysTime=null;
   
    
    //3.1
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        
        super.onCreate(savedInstanceState);
        
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.aerobic);
        //3.1
        init();        
        //3.1.1判断表“aerobic”中的数据项,是否大于31,如果是则删除原有表,再重新创建同样的表,目的:更新一个月的数据
        if(dbHelperOperate.getCount(sqlGetCount)>31)
        {
            //3.1.2这里看到了吧,我是先判断,标中的数据是否达到一个数值,达到了就删除整个表,接着再重新创建表
            dbHelperOperate.deleteSql(sqlDeleteTable);
            dbHelperOperate.createNew(sqlCreateTable);
        }
        
    }
    //3.1
    private void init(){    
        start=System.currentTimeMillis();

        //注意一、二、三这个3个步骤中类的构造方法,这里一初始化DBHelperOperate的一个实例时,就会调用DBHelperOperate类的构造方法,

       //DBHelperOperate的构造方法又会调用DBHelper类的构造方法,好了数据库dataBase.db创建了,在这个类中,只要调用DBHelperOperate类中的方法,

       //DBHelperOperate类中的方法只要有getWritableDatabase()或getReadableDatabase()是,就会自动调用DBHelper类中的onCreate()方法来创建表了

        //这里初始化了操作数据库的一个实例,就是步骤“二”中类DBHelperOperate的一个实例
        dbHelperOperate=new DBHelperOperate(this);
    }
    
    //3.2
    @Override
    protected void onStart() {
        super.onStart();
        /*因为考虑到读数据库是个耗时的操作,所以以消息队列的方式读数据库
         * */
        Message m=new Message().obtain(mHandler, PublicUtils.DB_QUNEY);
        mHandler.sendMessage(m);
    }

    
    
    //3.3
    @Override
    protected void onDestroy() {
        //3.3.1
        saveData();
        
        
        //3.3.2更新数据库,先找到当天日期(time)键对应的数据,将数据更新
        String[] whereArgs={sysTime};
        //这个ContentValues就是存放到数据库中的值,有点像Map
        ContentValues values=new ContentValues();
        //3.3.3这里是先查看数据库是否有数据,如果list.size()>0说明数据库中已经有数据了,不要再添加,只要
        //更新数据就行
        List<Double> list=dbHelperOperate.find(sqlFind,sysTime,"pulmonary");
        if(list.size()>0)
        {
            values.put("journey", list.get(0)+journey);
            values.put("pulmonary", list.get(1)+pulmonary);
            //3.3.4
            dbHelperOperate.update("aerobic", values, "time=?", whereArgs);
        }else{
            //3.3.5
            saveAerobicMethod();
        }
        
        super.onDestroy();
    }
    
    //保存要存放到数据库的数据,例如,路程(journey)、血氧量(pulmonary)
    //3.3.1
    public void saveData()
    {
        long end=System.currentTimeMillis();
        
        double dTime=(end-start)/3600000.0;
        int iTime=(int) (dTime*100);
        double c=iTime/100.0;
        
        double dJourney=dataWhat*c;
        int iJourney=(int) (dJourney*100);
        journey=iJourney/100.0;
        
        SimpleDateFormat formatter=new SimpleDateFormat("yyyy-MM-dd");
        Date date=new Date(end);
        sysTime=formatter.format(date);
        
    }
    
    
    //3.3.5当退出此模块,调用此方法,将数据保存到数据库中
    public  void saveAerobicMethod()
    {
        
        ContentValues values=new ContentValues();
        values.put("time", sysTime);
        values.put("journey", journey);
        values.put("pulmonary", pulmonary);
        //3.3.5
        dbHelperOperate.add("aerobic", "id",values);
        
    }
    
    //3.2
    Handler mHandler=new Handler(){

        @Override
        public void handleMessage(Message msg) {
            switch(msg.what){
                //3.2
            case PublicUtils.DB_QUNEY:
                dataList=
                 dbHelperOperate.query("aerobic","pulmonary");
                
                break;
            }
        }
        
    };
}


四,最后还有一个javabean。很简单,看出了这个类继承了Parcelable,为什么要这样做,在上面说过,因为要用到android绘图(就是条形图、折线图)

绘 图需要数据,我把AerobicMethod类中取得的数据放到dataList中后,需要跳转到另一个activity中,我要传值,并且是以list 集合的方式传过去,具体Parcelable怎么用的,不是本文的主题这里就不说了,只要知道Information是一个javaBean即可

/**例如:

Intent intent=new Intent(AerobicMethod.this,AerobicChart.class);
        intent.putParcelableArrayListExtra("aerobicData", dataList);
        startActivity(intent);

*/

public class Information implements Parcelable{
    private double journey;
    private double purposeVal;
    private String time;
    
    
    public Information(double journey, double purposeVal, String time) {
        super();
        this.journey = journey;
        this.purposeVal = purposeVal;
        this.time = time;
    }
    public String getTime() {
        return time;
    }
    public void setTime(String time) {
        this.time = time;
    }
    public double getPurposeVal() {
        return purposeVal;
    }
    public void setPurposeVal(double purposeVal) {
        this.purposeVal = purposeVal;
    }
    public double getJourney() {
        return journey;
    }
    public void setJourney(double journey) {
        this.journey = journey;
    }
    @Override
    public int describeContents() {
        return 0;
    }
    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeDouble(this.journey);
        dest.writeDouble(this.purposeVal);
        dest.writeString(this.time);
    }
    
    public static final Parcelable.Creator<Information> CREATOR=new Creator<Information>() {

        @Override
        public Information createFromParcel(Parcel source) {
            return new Information(source.readDouble(), source.readDouble(), source.readString());
        }

        @Override
        public Information[] newArray(int size) {
            return new Information[size];
        }
    };
    

    
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值