Realm数据库如何运作?

时间:2017-06-14 12:30:42

标签: java android database realm

我已经开始在我的应用程序中使用Realm数据库但是我无法理解Realm如何知道我的模型类的成员。

我的领域模型类唯一的注释是@PrimaryKey只有一个变量,其他变量没有注释。

我能想到的另一种方式是Realm使用反射来计算模型类中的变量,但由于Android上的反射很慢,我认为Realm不依赖于反射,因为它们将自己推销为快速数据库。 / p>

有人可以告诉我领域是如何运作的,或者可以指向一些显示领域如何运作的文章?

2 个答案:

答案 0 :(得分:0)

Realm使用注释处理。

注释处理是一种允许您在编译时执行相当强大功能的技术。它可以访问您的所有课程并检查您的所有属性和方法。

我认为Realm也会使用AST(抽象语法树)修改来代理get / set方法。这是一种更先进(但功能更强大)的技术

您可以在this tutorial

中找到有关注释处理的更多信息

此外,如果您想检查注释处理和AST修改的另一个示例,您可以查看this repo。这是我前段时间制作的一个项目

答案 1 :(得分:0)

  

我的领域模型类唯一的注释是@PrimaryKey只有一个变量,其他变量没有注释。

错误:)当你说extends RealmObject时,你实际上是从一个定义为

的类继承的
@RealmClass  // <---- annotation
public abstract class RealmObject implements RealmModel {
}

因此,您的类具有注释处理器注册的@RealmClass注释,然后它可以读取所有字段,如:

@AutoService(Processor.class)
public class ExampleProcessor extends AbstractProcessor {
    ProcessingEnvironment processingEnvironment;
    Elements elements;
    Messager messager;
    Filer filer;
    Types types;

    @Override
    public synchronized void init(ProcessingEnvironment processingEnv) {
        super.init(processingEnv);
        this.processingEnvironment = processingEnv;
        this.filer = processingEnvironment.getFiler();
        this.elements = processingEnvironment.getElementUtils();
        this.messager = processingEnvironment.getMessager();
        this.types = processingEnvironment.getTypeUtils();
    }

    @Override
    public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
        Set<? extends Element> annotatedElements = roundEnv.getElementsAnnotatedWith(RealmClass.class);
        for(Element element : annotatedElements) {
            // ...
        }
        // ...
    }

    @Override
    public SourceVersion getSupportedSourceVersion() {
        return SourceVersion.latest();
    }

    @Override
    public Set<String> getSupportedAnnotationTypes() {
        Set<String> annotations = new HashSet<>();
        annotations.add(RealmClass.class.getName());
        return Collections.unmodifiableSet(annotations);
    }
}

然后,它可以为使用@RealmClass注释的每个对象生成代理类。该代码在here开源时可用。

当您拥有包含RealmObjects的库项目时,它会变得有点棘手,因此您需要指定@RealmModule(以定义架构并且它是库模块)。

至于用代理getter / setter替换字段访问,这是由一个名为Realm-Transformer的Gradle插件(使用Javassist)完成的,它使用所谓的 Transform API ,并且是用Groovy编写的。