Android数据库知识点总结


本文主要讲述建库建表的流程以及增删改查操作。Android 数据库可以考虑自带的SQLite数据库或各种开源的三方库。本文先讲述系统自带的SQlite数据库的相关操作然后讲述使用WCDB开源库。

 

1、SQlite数据库的使用

1.1建库、建表、库升级

第一步、编写继承SQLiteOpenHelper的子类并定义该子类相关的数据库名称、数据库版本信息。如下所示:

public class MyDbHelper extends SQLiteOpenHelper {
    private static final String TAG = "MyDbHelper";
    //数据库名称
    private static final  String DATABASE_NAME = "test.db";
    //数据库版本信息用于数据库升级
    private static int sVersion = 2;
	......
}

第二步、私有化该子类构造方法,设计成单例模式,本文采用DCL(双重检测)单例模式。如下所示:

public static MyDbHelper getInstance(Context context) {
    if (null == sDbHelper) {
        synchronized (MyDbHelper.class) {
			//防止内存泄漏context.getApplicationContext()
            sDbHelper = new MyDbHelper(context.getApplicationContext());
        }
    }
    return sDbHelper;
}

private MyDbHelper(Context context) {
    super(context, DATABASE_NAME, null, sVersion);
    // TODO Auto-generated constructor stub

}

第三步、在onCreate方法中进行建表操作,onCreate方法会在APP第一次安装的时候调用。建表语句如下所示

//建表
db.execSQL("CREATE table IF NOT EXISTS "
        + mTableName
        + " (_id INTEGER PRIMARY KEY AUTOINCREMENT, " //
        + DatabaseFiled.COL_NAME
        + " TEXT, " //
        + DatabaseFiled.COL_CARDNUM
        + " TEXT  UNIQUE, " //
        + DatabaseFiled.COL_AGE
        + " INTEGER, "//
        + DatabaseFiled.COL_SEX
        + " INTEGER  ,"//
        + DatabaseFiled.COL_ADDR
        + " TEXT ); ");//


至此建库建表完成。

 

由于需求的变化数据库表结构经常会发生变化,但是又要保留以前的数据,这时候我们可以通过采用保留数据升级的方式处理该问题。本文示例在数据表中新增一个字段DatabaseFiled.COL_MARK用来做备注,具体操作如下

第一步、在onUpgrade方法中对数据库版本进行判断(数据库的默认版本好像是1)。只要是老版本低于这次升级的版本的数据库都要执行这段添加字段操作,如下所示:


@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    try{
        switch (oldVersion){
            case 1:
                db.execSQL("ALTER TABLE  " + "" + mTableName + " ADD COLUMN "
                        + DatabaseFiled.COL_MARK + "  TEXT   ");
              .......
}

这样就能搞定数据库升级的问题?对于非第一安装该APP的用户来说确实可以做到;但是对于第一次安装该APP的用户只会执行onCreate方法从而无法升级到这个字段。所以需要在onCreate方法中的建表语句下增加这条sql语句:


db.execSQL("ALTER TABLE  " + "" + mTableName + " ADD COLUMN "
        + DatabaseFiled.COL_MARK + "  TEXT   ");

这样就实现了数据库保留以前数据,第一次安装的用户也能实现"升级"的数据库升级。


1.2数据表的相关操作

数据库表的操作即CRUD。

第一步,定义数据表操作接口:

public interface UserDao {

    boolean addUser(User user);
    boolean addUser4Many(List<User> users);
    List<User> getUserInfo();
    boolean delUser(User user);
    boolean modifyUser(User user);
    void closeDatabase();
}

第二步,实现该接口

public class UserDaoImpl implements UserDao {
    private static final  String TAG="UserDaoImpl";
    private String mTableName="user";
    private MyDbHelper myDbHelper;
    public UserDaoImpl(Context ctx){
        myDbHelper=MyDbHelper.getInstance(ctx);
        myDbHelper.setWriteAheadLoggingEnabled(true);//支持并发
    }
    //REPLACE INTO 去重 UNIQUE约束
    @Override
    public boolean addUser(User user) {
        SQLiteDatabase database = null;
        try{
            database = myDbHelper.getWritableDatabase();
            if(database.isOpen()){

                int sex = user.mSex.equals("M") ? 1 : 0;
                String sql="INSERT INTO "+mTableName+"("+ DatabaseFiled.COL_NAME+","+DatabaseFiled.COL_AGE+","+
                        DatabaseFiled.COL_CARDNUM+","+
                        DatabaseFiled.COL_SEX+","
                        +DatabaseFiled.COL_ADDR+")VALUES(?,?,?,?,?)";
                database.execSQL(sql,new Object[]{user.mName,Integer.valueOf(user.mAge),user.mCardNum,sex,user.mAddr});

                Log.e(TAG,"数据插入成功");
                return true;
            }

            return false;
        }catch (Exception e){
          e.printStackTrace();
            Log.e(TAG,e.toString());
            return false;
        }


    }
    //批量操作还可以使用sql预编译进行优化
    @Override
    public boolean addUser4Many(List<User> users) {
//        SQLiteDatabase database = null;
//        try{
//            database = myDbHelper.getWritableDatabase();
//            database.beginTransaction();
//            if(database.isOpen()){
//                String sql="INSERT INTO "+mTableName+"("+ DatabaseFiled.COL_NAME+","+DatabaseFiled.COL_AGE+","+
//                        DatabaseFiled.COL_CARDNUM+","+
//                        DatabaseFiled.COL_SEX+","
//                        +DatabaseFiled.COL_ADDR+")VALUES(?,?,?,?,?)";
//              for(User user:users){
//                  int sex = user.mSex.equals("M") ? 1 : 0;
//                  database.execSQL(sql,new Object[]{user.mName,Integer.valueOf(user.mAge),user.mCardNum,sex,user.mAddr});
//
//              }
//                database.setTransactionSuccessful();
//                Log.e(TAG,"数据批量操作完成");
//                return true;
//            }
//
//            return false;
//        }catch (Exception e){
//            e.printStackTrace();
//            Log.e(TAG,e.toString());
//            return false;
//        }finally {
//            if(null!=database){
//                database.endTransaction();
//            }
//        }
        //SQL预编译优化
        SQLiteDatabase database = null;
        try{
            database = myDbHelper.getWritableDatabase();
            database.beginTransaction();
            if(database.isOpen()){
                String sql="INSERT INTO "+mTableName+"("+ DatabaseFiled.COL_NAME+","+DatabaseFiled.COL_AGE+","+
                        DatabaseFiled.COL_CARDNUM+","+
                        DatabaseFiled.COL_SEX+","
                        +DatabaseFiled.COL_ADDR+")VALUES(?,?,?,?,?)";
                SQLiteStatement statement = database.compileStatement(sql);




                for(User user:users){
                    statement.clearBindings();
                    if(null!=user.mName) {
                        statement.bindString(1,user.mName);
                    }
                    if(null!=user.mAge) {
                        statement.bindString(2,user.mAge);
                    }
                    if(null!=user.mCardNum) {
                        statement.bindString(3,user.mCardNum);
                    }

                    if(null!=user.mSex) {
                        statement.bindString(4,user.mSex);
                    }

                    if(null!=user.mAddr) {
                        statement.bindString(5,user.mAddr);
                    }
                    statement.executeInsert();

                }
                database.setTransactionSuccessful();
                Log.e(TAG,"sql预编译数据批量操作完成");
                return true;
            }

            return false;
        }catch (Exception e){
            e.printStackTrace();
            Log.e(TAG,e.toString());
            return false;
        }finally {
            if(null!=database){
                database.endTransaction();
            }
        }








    }
    //查询建索引优化
    @Override
    public List<User> getUserInfo() {
        SQLiteDatabase database = null;
        Cursor cursor=null;
        try{
            database = myDbHelper.getReadableDatabase();
            if(database.isOpen()){

                String sql="SELECT "+DatabaseFiled.COL_NAME+","+DatabaseFiled.COL_AGE+","+DatabaseFiled.COL_ADDR+","+DatabaseFiled.COL_SEX+"  FROM "+mTableName;
                cursor= database.rawQuery(sql,null);
                User user=null;
                ArrayList<User> users=new ArrayList<>();
                while (cursor.moveToNext()) {

                    String name = cursor.getString(cursor
                            .getColumnIndex(DatabaseFiled.COL_NAME));
                    String age = cursor.getString(cursor
                            .getColumnIndex(DatabaseFiled.COL_AGE));
                    String addr = cursor.getString(cursor
                            .getColumnIndex(DatabaseFiled.COL_ADDR));
                    String sex = cursor.getString(cursor
                            .getColumnIndex(DatabaseFiled.COL_SEX));
                    user=new User();
                    user.mName=name;
                    user.mAge=age;
                    user.mAddr=addr;
                    user.mSex=sex;
                    users.add(user);
                    user=null;


                }

                return users;
            }

            return null;
        }catch (Exception e){
            e.printStackTrace();
            Log.e(TAG,e.toString());
            return null;
        }finally {
            if(null!=cursor){
                cursor.close();

            }
        }
    }

    @Override
    public boolean delUser(User user) {
        SQLiteDatabase database = null;
        try{
            database = myDbHelper.getWritableDatabase();
            if(database.isOpen()){
                String sql="DELETE FROM  "+mTableName +" WHERE  "+DatabaseFiled.COL_NAME+"=?";
                database.execSQL(sql,new String[]{user.mName});

                return true;
            }

            return false;
        }catch (Exception e){
            e.printStackTrace();
            Log.e(TAG,e.toString());
            return false;
        }
    }

    /**
     * 根据用户名修改地址和年龄
     * @param user
     * @return
     */
    @Override
    public boolean modifyUser(User user) {
        SQLiteDatabase database = null;
        try{
            database = myDbHelper.getWritableDatabase();
            if(database.isOpen()){
                String sql="UPDATE  "+mTableName +" SET  "+DatabaseFiled.COL_ADDR+"=?,"+DatabaseFiled.COL_AGE+"=?" +"  WHERE  "+DatabaseFiled.COL_NAME+"=?";
                database.execSQL(sql,new String[]{user.mAddr,user.mAge,user.mName});
                    Log.e(TAG,"数据修改成功");
                return true;
            }

            return false;
        }catch (Exception e){
            e.printStackTrace();
            Log.e(TAG,e.toString());
            return false;
        }
    }

    @Override
    public void closeDatabase() {
        try {
            SQLiteDatabase database = myDbHelper.getWritableDatabase();

            if (null != database) {
                database.close();
                database = null;
            }

            if (null != myDbHelper) {
                myDbHelper.close();
                myDbHelper = null;
            }

        } catch (Exception e) {
            e.printStackTrace();
            Log.e(TAG,e.toString());

        }
    }
}


第三步对外提供方法调用如下所示


public class DataInfoFactory {
   private static final String TAG = "DataInfoFactory";

   private DataInfoFactory() {

   }


   public static synchronized UserDao getUserDao(Context context,String type) {
      switch (type){
         case "user":
            if ( null== MyApplication.getInstance().mUserDao) {

               MyApplication.getInstance().mUserDao = new UserDaoImpl(context.getApplicationContext());
            }
            return     MyApplication.getInstance().mUserDao;




      }

   return null;
   }
   

}

1.3数据表操作的相关优化

1、查询建立索引优化

2、批量插入用事务以及SQL语句预编译见代码。

2、WCDB的集成使用

2.1 WCDB集成

添加如下依赖

compile 'com.tencent.wcdb:wcdb-android:1.0.2'

 

并将SQLiteDatabase、SQLiteOpenHelper替换成腾讯的就OK了

其余操作一样。

wcdb地址:https://github.com/Tencent/wcdb

 

 

公司项目是个IM系统,客户端需要存储大量的数据,经过自己的大量的压力测试,在低配机上用系统数据库容易爆,但是集成了wcdb后数据不再是问题了,感谢大公司的开源。

 

 

本文源码https://github.com/1010540672/MyDbStudy




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值