Realm for Android 使用入门


Realm 是一个手机数据库,是用来替代 SQlite 的解决方案,比 SQlite 更轻量级,速度更快,因为它有一套自己的数据库搜索引擎,并且还具有很多现代数据库的优点,支持 JSON,流式 API 调用,数据变更通知,自动数据同步,简单身份验证,访问控制,事件处理,最重要的是跨平台,目前已经支持 Java、Swift、Object - C、React - Native 等多种实现,今天我们就来简单的入门 Ream 数据库的使用
GITHub地址: GitHub地址
Realm官网: Realm官网

一、使用要求

首先使用 Realm 的一些使用要求我们还是需要先来了解

Android Studio 的使用版本必须在 1.5.1 或更高使用 JDK 7 或更高版本Android API 9 或更高(即 Android 2.3 及以上)Realm 不在 Android 支持 Java,不支持 Eclipse 作为 IDE,如果使用请转到 Android Studio

上面基本就是我们要注意的事项,大家了解即可

二. 环境配置

1)首先在工程的根目录(工程目录) build.gradle 中引入如下代码,注意是工程的 build.gradle 而不是 app 的build.gradle
由于Realm是外网,为了下载的方便,可以使用阿里的镜像文件,即在buildscript和allprojects添加如下代码

 maven {
  url'http://maven.aliyun.com/nexus/content/groups/public/'
}
 
buildscript {
    repositories {
    maven {
  url'http://maven.aliyun.com/nexus/content/groups/public/'
}
        jcenter()
    }
    dependencies {
        classpath "io.realm:realm-gradle-plugin:6.0.2"
    }
}
allprojects {
    repositories {
        maven {
            url'http://maven.aliyun.com/nexus/content/groups/public/'
        }
        google()
        jcenter()
        
    }

可以看到 Realm 是作为一个插件来安装的

如图所示
在这里插入图片描述
2)在 app 的 build.gradle 中添加如下代码

apply plugin: 'realm-android'

在这里插入图片描述
当上面的这两步做好以后,可以刷新我们的 Gradle 依赖,如果你是通过 v 0.88 以前的版本来更新,你需要去清理一下你的 Gradle 项目(./gradlew clean),来移除之前的安装,另外对 Maven 和 Ant 并不支持

使用优点
个人觉得最主要的是两点:1. 访问快,直接操作底层数据;2. 支持跨平台。什么是ORM? object relation model,对象关系映射模型,就是通过使用描述对象和数据库之间映射的元数据,来实现面向对象语言程序中的对象与关系数据库中数据的映射。简单来说,就是一个类对应数据库中的表,一个属性对应数据库中的一列,一个类的对象对应数据库中的一条记录。 基于ORM技术的框架称为ORM框架,它使得使用者更容易理解和操作数据库,但是由于中间需要转换,所以性能上比直接使用SQL语句要慢,另外还需要保存数据对应的类,所以需要更多的内存。

几个基本概念

1.数据模型

  • 一个模型(java中的一个类)表示数据库中的一张表,模型中的字段表示表中的列

  • 模型需要继承RealmObject类
    在这里插入图片描述

  • 模型实时、自动更新(需要获得当前线程的looper,在主线程中是满足的);操作模型就相当于直接操作数据库中底层数据

2. 事务

  • 所有会使数据发生变化 的操作必须在事务中进行。如:增、删、改
  • 查询操作可以不需要在事务中进行
  • 事务分为同步事务和异步事务两种

3. 引用计数

  • Realm实例使用引用计数的方式
  • 生成的Realm实例在使用完后需要手动close。

4. 数据库的迁移

在Realm中如果增加、删除了模型或者模型的字段,需要进行数据库的迁移。这个概念类似于数据库的升级。

初始化Realm并配置Realm

1.初始化Realm,获得Realm对象

初始化

在application的onCreate()中使用Realm.init()初始化,所以在项目中一般要创建一个Application类,来完成一些数据的缓存。数据的迁移一般放在初始化后进行。

public class MyApplication extends Application {
    @Override
    public void onCreate() {
        super.onCreate();
        Utils.init(this);
        Realm.init(this);
        RealmHelp.migration();
    }
}

获得使用默认配置的Realm对象

方式一

Realm realm = Realm.getDefaultInstance();

方式二:先获取默认配置对象,在设置配置,最终用getInstance(config)得到对象

RealmConfiguration config = new RealmConfiguration.Builder().build();
Realm.setDefaultConfiguration(conf);
Realm realm = Realm.getInstance(config);

默认配置的话,会得到一个名为default.realm数据库,数据库保存地址:data/data/包名/files/default.realm。可将其导出,使用RealmStudio进行查看内容。

配置不是必须的,如果不配置,会使用默认配置;但是如果有数据库的迁移,那么是需要配置数据库,并调用migrateRealm静态方法。具体的在数据库迁移中阐述。

public static void migrateRealm(RealmConfiguration configuration) throws FileNotFoundException {
    migrateRealm(configuration, null);
}

2. Realm使用完了之后要关闭

要注意是否有数据从Realm数据库中读出
在界面类中使用Realm,一般在activity.onDestroy()中关闭,或者在finally语句块中关闭。因为从Realm数据库中获取的数据是一个模型对象的引用,如果关闭realm。之前所获取的引用将无法找到对应的数据源。

创建模型

一般来说都是写一个类继承RealmObject

public class UserModel extends RealmObject {
//    主键不可重复
    @PrimaryKey
    private String phone;
    @Required
    private String password;

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

注意 所有属性修饰符可以为private、public, protected ,一般使用private,提供setter/getter方法供外部访问。支持定义普通方法。

字段类型

  • 整形变量byte, short, int, long在Realm会转换为long;
  • List只能使用RealmList<? extends RealmObject>
public class MusicSourceModel extends RealmObject {
    private RealmList<AlbumModel> album;
    private RealmList<MusicModel> hot;
  • 其中继承RealmObject 的类型

修饰符

  • @primarykey:主键,一个模型中只能由一个主键
  • @Required:表示该字段非空
  • @Ignore:表示忽略该字段,添加 @Ignore 标签后,存储数据时会忽略该字段
@PrimaryKey
private String phone;
@Required
private String password;

事务

在Realm中事务有两种,同步和异步事务,共有三种开启方式

1. 手动开启事务

//开启事务
realm.beginTransaction();
//创建被Realm管理的实例对象,该对象的所有变更都会被直接应用到Realm数据源中
User user = reaml.createObject(User.calss);
//更改数据
user.setUserName("tudou");
//提交事务:所有的修改数据相关的操作只有在执行事务提交之后,才会被写入到数据库
realm.commitTransaction();
//取消事务:取消事务后,所有对数据 的修改都会被取消
realm.cancelTransaction();

2. 同步事务执行块

//这种方式会自动开启事务,提交事务;并在发生错误时取消事务
realm.executeTransaction(new Realm.Transaction(){
   @Override
    public void execute(Realm realm){
        User user = reaml.createObject(User.calss);
        user.setUserName("tudou");
    }
});

3. 异步事务执行块

//使用异步事务,Realm会在后台线程中进行写入操作,并在事务完成时将结构返回调用线程;
//OnSuccess和OnError不是必须的,重载函数的会在事务成功或者失败时在调用线程执行。
RealmAsyncTask asyncTask = realm.executeTransactionAsync(new Realm.Transaction(){
    @Override
    public void execute(Realm realm){
        User user = reaml.createObject(User.calss);
        user.setUserName("tudou");
    }
}, new Realm.Transaction.OnSuccess(){
    @Override
    public void onSuccess(Realm realm){
        //事务执行成功时回调
    }
},new Realm.Transaction.OnError(){
    @Override
    public void onError(Realm realm){
        //事务执行失败时回调
    }
});

当你退出Activity或者Fragment时,要记得使用RealmAsyncTask取消异步事务;

if(asyncTask != null && !asyncTask.isCancelled()){
    asyncTask.cancel();
}

数据库的操作

1.createObject()获取自动更新的Realm模型

realm.beginTransaction();
User user = realm.createObject(User.class); // Create a new object
user.setName("John");
user.setEmail("john@corporation.com");
realm.commitTransaction();

2. createObjectFromJson()

Realm支持从Json文件中创建模型;需要两者对应
使用场景是从json文件中读取内容

//假如Json文件格式如下:
{
    "musicId": "7",
    "name": "Nostalgic Piano",
}
//则可以创建一个模型类
public class MusicModel extends RealmObject{
    private String musicId;
    private String name;
    //省略了setter/getter方法
}
realm.beginTransaction();
realm.createObjectFromJson(MusicModel.class, musicSourceJson);//musicSourceJson为json文件的字符串。如果json文件中有几层,直接使用最外层即可。
realm.commitTransaction();

如果json文件中有几层,直接使用最外层即可。

3. inserOrUpdate()

如果要插入的是多个数据,比如List,则使用insertorUpdate()

List<User> users = Arrays.asList(new User("John"), new User("Jane"));

realm.beginTransaction();
realm.insert(users);
realm.commitTransaction();

或者有一个模型作为参数时

public void saveUser(UserModel userModel){
        mRealm.beginTransaction();
        mRealm.insert(userModel);
        mRealm.commitTransaction();
}

1. realm.where(User.class)

该方法返回一个RealmQuery对象,大致意思就是得到一张表,然后在表中查询

2. 条件过滤

//所有类型的字段共有的方法
equalTo("name", "John");//第一个参数为字段名,肯定为String,第二个参数为字段的值
notEqualTo();
in(); // 比如:想找名字是否在集合中in("name", new String[]{"Jill", "William", "Trillian"})

//整形字段
between (includes both end points, i.e., it is a bounded interval);
greaterThan();
lessThan();
greaterThanOrEqualTo();
lessThanOrEqualTo();

//String字段
contains();
beginsWith();
endsWith();
like();

//RealmList,String等
isEmpty();
isNotEmpty();
//如果一个字段没有使用 @required 修饰,那么它的值可以为null;可以检查他的值是否为null
isNull();
isNotNull()

or();//使用or()的使用要配合beginGroup()--->endGroup()使用
and();//默认支持的
not();

3. findXxxx()

上几步操作返回的是RealmQuery对象,调用该对象的findXxx()返回查询的结果,一个RealmResults对象,或者直接时一个对应模型对象:

findAll();//查找出所有满足条件的记录,返回一个RealmResults<> set
findFirst();//查找出满足条件的第一个结果,一个 Moudle 对象
findAllAsync();//异步查找结果

主要有两种形式
1.先使用findAll(),获取一个RealmResults<> 对象,再删除
userlist为RealmResults<> 对象

 userList.get(0).deleteFromRealm();  
 userList.deleteFirstFromRealm(); //删除user表的第一条数据  
userList.deleteLastFromRealm();//删除user表的最后一条数据  
results.deleteAllFromRealm();//删除user表的全部数据

2.直接调用类方法delete()

mRealm.delete(MusicModel.class); //直接删除一张表

修改操作也是需要在事务中进行的。先查找到数据,然后由于模型是可以自动更新的,直接调用setter方法就可以更改数据了。

mRealm.executeTransaction(new Realm.Transaction() {  
    @Override  
    public void execute(Realm realm) {  
        //先查找后得到User对象  
        User user = mRealm.where(User.class).findFirst();  
        user.setAge(26);  
    }  
}); 

数据迁移

当数据库新增了模型或者模型中的字段新增、删除时要进行数据库的迁移。一般情况下,是在刚启动APP的时候,磁盘中已经存在一个Realm数据库了,这个时候就需要进行数据库的迁移。
一般与初始化写在一起

Realm.init(this);
RealmHelp.migration();

迁移之前要设置一个新的配置,再调用Realm.migrateRealm(configuration),传入所设配置。

public static void migration(){
//        获取最新的配置
        RealmConfiguration configuration = getRealmConf();
        Realm.setDefaultConfiguration(configuration);
//        需要告诉Realm 数据需要迁移
        try {
            Realm.migrateRealm(configuration);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

配置对象的建立需要传入一个migration类的实现对象。
故要新建一个migration实现类

public class Migration implements RealmMigration {
    /**
     *
     * @param realm
     * @param oldVersion 老的数据库版本
     * @param newVersion 新的数据库版本 为RealmConfiguration.Builder().schemaVersion(1)中所传入的值
     */
    @Override
    public void migrate(DynamicRealm realm, long oldVersion, long newVersion) {
        //获取可编辑的图表schema,之前版本的字段和表都已经存在schema之中
        RealmSchema schema = realm.getSchema();
        /**
         * 第一次迁移
         */
        /**
         *  private String musicId;
         *     private String name;
         *     private String poster;
         *     private String path;
         *     private String author;
         */
        if (oldVersion ==0){
//            要将新增的结构告诉数据库(包括模型和字段)
// 	结构的书写要从最基础的往复杂的去写。

            schema.create("MusicModel")
                    .addField("musicId",String.class)
                    .addField("name",String.class)
                    .addField("poster",String.class)
                    .addField("path",String.class)
                    .addField("author",String.class);
            schema.create("AlbumModel")
                    .addField("albumId",String.class)
                    .addField("name",String.class)
                    .addField("poster",String.class)
                    .addField("playNum",String.class)
                    .addRealmListField("list",schema.get("MusicModel"));
//           RealmObjectSchema get(String className);
            schema.create("MusicSourceModel")
                    .addRealmListField("album",schema.get("AlbumModel"))
                    .addRealmListField("hot",schema.get("MusicModel"));
            oldVersion = newVersion;
        }
    }

public static RealmConfiguration getRealmConf(){
    return new RealmConfiguration.Builder()
            .schemaVersion(1)//迁移后的版本号
            .migration(new Migration())
            .build();

总结

使用Realm数据库的步骤:1,2,3,4,5。

  1. 在项目中配置初始化Realm并配置Realm、获取Realm的实例。
  2. 对数据库进行增、删、改、查等操作。
  3. 如果磁盘中已经有数据库了,在初始化后需要对数据库进行迁移
  4. 在不使用时,需要关闭数据库连接。一般
  5. 可以写一个帮助类来辅助完成数据库的相关操作。

参考Realm数据库的使用

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android Studio提供了多种数据库选项,其中包括SQLite、Realm和Room等。其中,SQLite是默认的本地数据库选项,而Realm和Room则提供更高级别的功能。 以下是使用SQLite在Android Studio中创建和使用数据库的基本步骤: 1. 创建一个新的Android Studio项目,并在build.gradle文件中添加以下依赖项: ``` dependencies { implementation 'com.android.support:support-v4:28.0.0' implementation 'com.android.support:appcompat-v7:28.0.0' implementation 'com.android.support.constraint:constraint-layout:1.1.3' implementation 'com.android.support:design:28.0.0' implementation 'com.android.support:recyclerview-v7:28.0.0' implementation 'com.android.support:cardview-v7:28.0.0' implementation 'com.android.support:support-core-utils:28.0.0' implementation 'com.android.support:support-annotations:28.0.0' implementation 'com.google.android.gms:play-services-maps:15.0.1' // SQLite implementation 'com.readystatesoftware.sqliteasset:sqliteassethelper:+' } ``` 2. 在app的build.gradle文件中添加以下配置: ``` defaultConfig { applicationId "com.example.myapp" minSdkVersion 21 targetSdkVersion 28 versionCode 1 versionName "1.0" // 添加数据库的名称和版本号 javaCompileOptions { annotationProcessorOptions { arguments = ["room.schemaLocation": "$projectDir/schemas".toString()] } } ndk { abiFilters 'armeabi-v7a','arm64-v8a','x86','x86_64' } } // 定义数据库的版本号 def ROOM_VERSION = "2.2.5" // 添加Room的依赖项 dependencies { // Room components implementation "androidx.room:room-runtime:$ROOM_VERSION" annotationProcessor "androidx.room:room-compiler:$ROOM_VERSION" // Optional RxJava2 support for Room implementation "androidx.room:room-rxjava2:$ROOM_VERSION" // Optional Guava support for Room, including Optional and ListenableFuture implementation "androidx.room:room-guava:$ROOM_VERSION" // Test helpers testImplementation "androidx.room:room-testing:$ROOM_VERSION" } ``` 3. 创建一个DatabaseHelper类,用于创建和管理数据库: ``` public class DatabaseHelper extends SQLiteOpenHelper { private static final int DATABASE_VERSION = 1; private static final String DATABASE_NAME = "myapp.db"; private static final String TABLE_NAME = "mytable"; private static final String COLUMN_ID = "id"; private static final String COLUMN_NAME = "name"; public DatabaseHelper(Context context) { super(context, DATABASE_NAME, null, DATABASE_VERSION); } @Override public void onCreate(SQLiteDatabase db) { String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME + "(" + COLUMN_ID + " INTEGER PRIMARY KEY," + COLUMN_NAME + " TEXT" + ")"; db.execSQL(CREATE_TABLE); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME); onCreate(db); } public void addData(String name) { SQLiteDatabase db = this.getWritableDatabase(); ContentValues values = new ContentValues(); values.put(COLUMN_NAME, name); db.insert(TABLE_NAME, null, values); db.close(); } public List<String> getAllData() { List<String> data = new ArrayList<>(); SQLiteDatabase db = this.getReadableDatabase(); Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_NAME, null); if (cursor.moveToFirst()) { do { data.add(cursor.getString(1)); } while (cursor.moveToNext()); } cursor.close(); db.close(); return data; } } ``` 4. 在Activity中使用DatabaseHelper类来添加和获取数据: ``` public class MainActivity extends AppCompatActivity { private DatabaseHelper db; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); db = new DatabaseHelper(this); db.addData("John"); db.addData("Jane"); List<String> data = db.getAllData(); for (String name : data) { Log.d("MainActivity", "Name: " + name); } } } ``` 这样就可以在Android Studio中使用SQLite数据库了。当然,如果需要更高级别的功能,可以考虑使用Realm或Room。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值