Android数据库相关知识总结

210 阅读5分钟

1,背景

在做一个工具类的App,想把部分流程离线化,这个时候需要使用到数据库,但是现在App开发中,尽量都是把相关的业务放到后台,App做展示逻辑,所以关于数据库的使用基本上忘的差不多了,网上查了很多的资料,现在把自己关于数据库的相关总结在这里记录下,方便自己以后学习

2,数据库基础知识

说起数据库肯定,离不开各种Sql命令了 下面是具体的sql命令教程,可以在这里学习

www.w3school.com.cn/sql/index.a…   

下面是关于数据库的一些基本命令

创建数据库
CREATE DATABASE database_name
创建表

CREATE TABLE Persons(
Id_P int,
LastName varchar(255),
FirstName varchar(255),
Address varchar(255),
City varchar(255)
)

增
INSERT INTO Persons VALUES ('Gates', 'Bill', 'Xuanwumen 10', 'Beijing')

删
DELETE FROM Person WHERE LastName = 'Wilson'UPDATE Person SET FirstName = 'Fred' WHERE LastName = 'Wilson'SELECT LastName,FirstName FROM Persons
SELECT * FROM Persons

3,Android中的数据库

1,SQLite


SqlLite是什么?
SqlLite是一种轻量级的关系型数据库


SqlLite的创建

1,创建DB

通过SqlLiteHelper创建

dbHelper = new MyDatabaseHelper( this, "glodStore.db", null, 1);
db=dbHelper.getWritableDatabase();

直接传数据库的名字,那么数据库直接创建在内部存储的位置
/data/data/<package_name>/databases/    

dbHelper = new MyDatabaseHelper( this, getExternalFilesDir(null)+"/glodStore.db", null, 1);
db=dbHelper.getWritableDatabase();
传数据库的路径,可以创建到对应的文件夹下面


创建table,在SqlLiteHelper的onCreate方法中
String sql = "create table manager(id integer primary key autoincrement,name text ,password text)”
db.execSQL(sql);


2,增删改查
增
String sql="insert into stock(name,buyprice,number,buyfee) values('"+name+"',"+price+","+num+","+buyfee+")";
db.execSQL(sql);

删
String sql="DELETE FROM stock where id="+strid;
db.execSQL(sql);

改
String sql="update stock set sellprice="+strsell+",sellfee="+strfee+",selltax="+strtax+",profit="+strfit+",selldate=datetime(CURRENT_TIMESTAMP,'localtime') where id="+Integer.toString(id);
db.execSQL(sql);

查
Cursor cursor = db.rawQuery("select id,number,buyprice,buyfee,sellprice,profit from stock where name='"+stockname+"' order by sellprice ASC,buyprice ASC",null);
while(cursor.moveToNext()){
    int id = cursor.getInt(cursor.getColumnIndex("id"));
    float buyprice = cursor.getFloat(cursor.getColumnIndex("buyprice"));
    float buyfee = cursor.getFloat(cursor.getColumnIndex("buyfee"));
    int num = cursor.getInt(cursor.getColumnIndex("number"));
    float sellprice = cursor.getFloat(cursor.getColumnIndex("sellprice"));
    float profit = cursor.getFloat(cursor.getColumnIndex("profit"));
    float cost=(buyprice*num*1.001f+buyfee*2.0f)/num;
    cost=Math.round(cost*100)/100.0f;
    stockitem st = new stockitem(id,sellprice,buyprice,buyfee,Float.toString(cost),Float.toString(profit),Integer.toString(num));
    stockitemlist.add(st);

}

2,Room

Orm框架—将Java对象映射到数据库表(称为ORM,对象/映射关系),使用一个简单的面向对象的API来存储,更新,删除,查询数据库


    RoomGoogle官方提供的ORM框架,本质上,Room是在SQLite提供一个抽象层,方便使用,同时帮助用户更流畅的访问数据库

    Room的使用非常简单,
    Room主要有三个组件
    Database
    Entity
    Dao

1Database

@Database(entities = {Emperor.class}, version = 3, exportSchema = true)
public abstract class MyDatabase extends RoomDatabase {
    private static final String DATABASE_NAME = "emperor_db";
    private static MyDatabase databaseInstance;

    public static synchronized MyDatabase getDatabaseInstance(Context context) {
        if (databaseInstance == null) {
            databaseInstance = Room
                    .databaseBuilder(context.getApplicationContext(), MyDatabase.class, DATABASE_NAME)
                    .addMigrations(MIGRATION_1_2, MIGRATION_2_3)
                    //为了防止数据库升级失败导致崩溃,加入该方法可以在出现异常时创建数据表而不崩溃,但表中数据会丢失
                    .fallbackToDestructiveMigration()
                    .build();
        }
        return databaseInstance;
    }

    public abstract EmperorDao getEmperorDao();

    //升级相关
    private static final Migration MIGRATION_1_2 = new Migration(1, 2) {
        @Override
        public void migrate(@NonNull SupportSQLiteDatabase database) {
            //在这里做升级操作,比如增加或者减少表中的字段
            database.execSQL("ALTER TABLE emperor_table ADD COLUMN gender TEXT");
        }
    };

    private static final Migration MIGRATION_2_3 = new Migration(2, 3) {
        @Override
        public void migrate(@NonNull SupportSQLiteDatabase database) {
            //创建临时表
            database.execSQL("CREATE TABLE tem_emperor (" + "id INTEGER PRIMARY KEY NOT NULL," +
                    "emperor_name TEXT," +
                    "age INTEGER," +
                    "gender TEXT)");
            //将数据导入临时表
            database.execSQL("INSERT INTO tem_emperor (id,emperor_name,age,gender) SELECT id,emperor_name,age,gender FROM emperor_table");
            //删除原表
            database.execSQL("DROP TABLE emperor_table");
            //临时表改成原表的名字
            database.execSQL("ALTER TABLE tem_emperor RENAME TO emperor_table");
        }
    };
}



2,Entity

@Entity(tableName = "emperor_table")
public class Emperor {

    @PrimaryKey(autoGenerate = true)
    @ColumnInfo(name = "id", typeAffinity = ColumnInfo.INTEGER)
    public int id;
    @ColumnInfo(name = "emperor_name", typeAffinity = ColumnInfo.TEXT)
    public String name;
    @ColumnInfo(name = "age", typeAffinity = ColumnInfo.INTEGER)
    public Integer age;
    //增加一个性别的字段
    @ColumnInfo(name = "gender", typeAffinity = ColumnInfo.TEXT)
    public String gender;

    public Emperor(int id, String name, Integer age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    @Ignore
    public Emperor(int id, String name, Integer age, String gender) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.gender = gender;
    }

    @Ignore
    public Emperor(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Emperor{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age='" + age + '\'' +
                ", gender='" + gender + '\'' +
                '}';
    }
}

3,Dao
@Dao
public interface EmperorDao {

    //增
    @Insert
    public void insertEmperor(Emperor... emperor);

    //删
    @Delete
    public void deleteEmperor(Emperor... emperor);

    //改
    @Update
    public void updateEmperor(Emperor... emperor);

    //查符合指定条件的某一个
    @Query("SELECt * FROM emperor_table WHERE id=:id")
    public Emperor queryEmperorById(int id);

    //查所有符合条件的
    @Query("SELECt * FROM emperor_table WHERE age=:age")
    public List<Emperor> queryEmperorsByAge(Integer age);

    //查所有
    @Query("SELECt * FROM emperor_table")
    public List<Emperor> queryEmperors();

    //查所有,使用LiveData将结果List<Emperor>包装起来
    @Query("SELECt * FROM emperor_table")
    public List<Emperor> queryEmperorsByLiveData();
}

4,使用
@Override
public void onClick(View v) {
    switch (v.getId()) {
        case R.id.btn_insertEmperor:
            new Thread(() -> {
                Emperor caoCao = new Emperor(1, "曹操", 54);
                Emperor liuBei = new Emperor("刘备", 34);
                Emperor sunQuan = new Emperor(4, "孙权", 18);
                dao.insertEmperor(caoCao, liuBei, sunQuan);
            }).start();
            break;
        case R.id.btn_deleteEmperor:
            new Thread(() -> {
                Emperor caoCao = dao.queryEmperorById(1);
                Emperor liuBei = dao.queryEmperorById(2);
                dao.deleteEmperor(caoCao, liuBei);
            }).start();
            break;
        case R.id.btn_updateEmperor:
            new Thread(() -> {
                Emperor caoCao = dao.queryEmperorById(1);
                caoCao.age = 34;
                Emperor liuBei = dao.queryEmperorById(2);
                liuBei.age = 49;
                dao.updateEmperor(caoCao, liuBei);
            }).start();
            break;
        case R.id.btn_queryEmperorById:
            new Thread(() -> {
                Emperor sunQuan = dao.queryEmperorById(1);
                Log.e("main","====================sunQuan==" + JSON.toJSONString(sunQuan));
            }).start();
            break;
        case R.id.btn_queryEmperorsByAge:
            new Thread(() -> {
                List<Emperor> list = dao.queryEmperorsByAge(54);
                Log.e("main","====================list==" + JSON.toJSONString(list));
            }).start();
            break;
        case R.id.btn_queryEmperors:
            new Thread(() -> {
                List<Emperor> emperors = dao.queryEmperors();
                Log.e("main","====================emperors==" + JSON.toJSONString(emperors));
            }).start();
            break;
    }
}

Room同时会通过APT生成相应的方法 image.png

看完上面的操作,是不是比Sql命令简单很多,我大部分,操作对象就可以,这样更简单,方便使用

同时Room可以搭配mvvm使用,

A46E783E-F529-46BB-90AB-C4CF6AD006CE.png

3,GreenDao

GreenDao也是一个ORM框架,先于room出现,同样是用户更方便的使用

38305494-AB88-4582-B2CA-C9F01F31FFBD.png

1Gradle配置
implementation 'org.greenrobot:greendao:3.2.2’

greendao {
    schemaVersion 1//数据库版本号
    targetGenDir 'src/main/java'//设置DaoMaster、DaoSession、Dao目录
    daoPackage 'com.example.gen'
    //targetGenDirTest:设置生成单元测试目录
    //generateTests:设置自动生成单元测试用例
}

2,写对应的对象
@Entity
public class User {
    @Id(autoincrement = true)
    private Long id;
    
    @Unique
    private String userId;

    @Property
    private String userName;

    @Property
    private int age;
}

3,Application初始化GreenDao
private void initGreenDao() {
    DaoMaster.DevOpenHelper helper = new DaoMaster.DevOpenHelper(this, DB_NAME);
    SQLiteDatabase db = helper.getWritableDatabase();
    DaoMaster daoMaster = new DaoMaster(db);
    mDaoSession = daoMaster.newSession();
}

这个时候点击build项目,自动生成
DaoMaster    
DaoSession
UserDao  
这三个类


4,操作数据库
public void onViewClick(View view) {
        UserTest user = new UserTest();
        int id = view.getId();
        if(id == R.id.tv_save){
//            添加一条数据
            user.setAge(18);
            user.setId(System.currentTimeMillis());
            user.setLike("喜欢北京");
            user.setName("张胜男");
            mUserDao.insert(user);
        }else if(id == R.id.tv_delete){
            mUserDao.delete(user);
        }else if(id == R.id.tv_updata){
            user.setAge(19);
            mUserDao.delete(user);
        }else if(id == R.id.tv_select){
            List<UserTest> userList = mUserDao.loadAll();
//            User user = mUserDao.load(1L);
            Log.e("l;djgk","===========" + JSON.toJSONString(userList));
        }

}