Realm 数据库笔记(一)

delphi写EXECL文件的总结 delphi写EXECL文件的总结    首先,介绍一下delphi 中EXECL2000.pas 操作EXECL文件的借口函数(从网络上找的,仅供参考,这里着重列出使用控件的方法):参考网址http://cache.baidu.com/c?m=9d78d513d99516f11ab7cf690d67c0101d43f6612bd6a0572c95d51f84652b000531b2e0747c 阅读详情

Realm 数据库

ORMlite,greenDao这些框架都是在SQLite的基础上封装的ORM对象关系映射框架,简化了代码操作。
而今天的主角:Realm是一个可以替代SQLite以及ORM Libraries的轻量级数据库。
相比SQLite,Realm更快并且具有很多现代数据库的特性,比如支持JSON,流式api,数据变更通知,以及加密支持,这些都为安卓开发者带来了方便。不多介绍,更详细的介绍参见官网:https://realm.io/


安装

第一步: 在项目的 build.gradle 文件中添加如下 class path 依赖。
buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath "io.realm:realm-gradle-plugin:3.1.1"
    }
}
第二步: 在 app 的 build.gradle 文件中应用 realm-android 插件。
apply plugin: 'realm-android'

使用

Realm 数据模型定义需要继承自 RealmObject 类。

public class User extends RealmObject {

    private String          name;
    private int             age;

    @Ignore
    private int             sessionId;

    // Standard getters & setters generated by your IDE…
    public String getName() { return name; }
    public void   setName(String name) { this.name = name; }
    public int    getAge() { return age; }
    public void   setAge(int age) { this.age = age; }
    public int    getSessionId() { return sessionId; }
    public void   setSessionId(int sessionId) { this.sessionId = sessionId; }
}

RealmModel 接口
除直接继承于 RealmObject 来声明 Realm 数据模型之外,还可以通过实现 RealmModel 接口并添加 @RealmClass 修饰符来声明。

@RealmClass
public class User implements RealmModel {

}
写入

在任何时间都可以对对象进行访问和查询(读取事务是隐式的)。 所有的写操作(添加、修改和删除对象),必须包含在写入事务(transaction)中。写入事务可以提交或取消。在提交期间,所有更改都将被写入磁盘,并且,只有当所有更改可以被持久化时,提交才会成功。通过取消一个写入事务,所有更改将被丢弃。使用写入事务,会确保你的数据的一致性。

写入事务也用于确保线程安全:

// Obtain a Realm instance
Realm realm = Realm.getDefaultInstance();
realm.beginTransaction();
//... add or update objects here ...
realm.cancelTransaction();
//  ...
realm.commitTransaction();

事务执行块(Transaction blocks)
事务会相互阻塞其所在的线程,在后台线程中开启事务进行写入操作可以有效避免 UI 线程被阻塞。通过使用异步事务,Realm 会在后台线程中进行写入操作,并在事务完成时将结果传回调用线程。OnSuccess 和 OnError 并不是必须重载的,重载了的回调函数会在事务成功或者失败时在被调用发生的线程执行。回调函数是通过 Looper 被执行的,所以在非 Looper 线程中只有空(null)回调函数被允许使用。

//同步
realm.executeTransaction(new Realm.Transaction() {
    @Override
    public void execute(Realm realm) {
        User user = realm.createObject(User.class);
        user.setName("John");
        user.setEmail("john@corporation.com");
    }
});

//异步
realm.executeTransactionAsync(new Realm.Transaction() {
    @Override
    public void execute(Realm bgRealm) {
        User user = bgRealm.createObject(User.class);
        user.setName("John");
        user.setEmail("john@corporation.com");
    }
}, new Realm.Transaction.OnSuccess() {
    @Override
    public void onSuccess() {
        // Transaction was a success.
    }
}, new Realm.Transaction.OnError() {
    @Override
    public void onError(Throwable error) {
        // Transaction failed and was automatically canceled.
    }
});

//异步事务调用会返回一个 RealmAsyncTask 对象。当你退出 Activity 或者 Fragment 时可以使用该对象取消异步事务。如果你在回调函数中更新 UI,那么忘记取消异步事务可能会造成你的应用崩溃。
public void onStop () {
    if (transaction != null && !transaction.isCancelled()) {
        transaction.cancel();
    }
}
快照(Snapshots)

这段代码预期通过一个简单循环来邀请所有的 Guest 对象。因为 RealmResults 在每次循环都会被更新,你会发现最终的运行结果是只有一半的 Guest 对象收到了邀请。当 Guest 对象收到邀请以后,它会被立即从集合中移除,因为它不再满足查询条件,集合的大小在此刻发生了改变,所以当 i 增加时,循环会错过一个集合元素。

你可以通过使用集合数据的 快照 来解决这个问题。集合快照保证其中的元素及其顺序不会改变,即使在元素被修改甚至删除的情况下。

Realm 集合的迭代子(Iterator)会自动使用快照。你也可以通过 RealmResults 和 RealmList 的 createSnapshot() 方法来创建一个快照。

RealmResults<Person> guests = realm.where(Person.class).equalTo("invited", false).findAll();

// Use an iterator to invite all guests
realm.beginTransaction();
for (Person guest : guests) {
    guest.setInvited(true);
}
realm.commitTransaction();

// Use a snapshot to invite all guests
realm.beginTransaction();
OrderedRealmCollectionSnapshot<Person> guestsSnapshot = guests.createSnapshot();
for (int i = 0; guestsSnapshot.size(); i++) {
    guestsSnapshot.get(i).setInvited(true);
}
realm.commitTransaction();
查询

Realm 中的所有读取(包括查询)操作都是延迟执行的,且数据绝不会被拷贝。

比如查找所有叫做 John 或 Peter 的用户,你可以这么写:

public class User extends RealmObject {

    @PrimaryKey
    private String          name;
    private int             age;

    @Ignore
    private int             sessionId;

    // Standard getters & setters generated by your IDE…
    public String getName() { return name; }
    public void   setName(String name) { this.name = name; }
    public int    getAge() { return age; }
    public void   setAge(int age) { this.age = age; }
    public int    getSessionId() { return sessionId; }
    public void   setSessionId(int sessionId) { this.sessionId = sessionId; }
}

// Build the query looking at all users:
RealmQuery<User> query = realm.where(User.class);

// Add query conditions:
query.equalTo("name", "John");
query.or().equalTo("name", "Peter");

// Execute the query:
RealmResults<User> result1 = query.findAll();

// Or alternatively do the same all at once (the "Fluent interface"):
RealmResults<User> result2 = realm.where(User.class)
                                  .equalTo("name", "John")
                                  .or()
                                  .equalTo("name", "Peter")
                                  .findAll();

查询条件
通过 where() 方法你可以得到一个 RealmQuery 对象并通过该对象创建各种查询条件。

查询的第一个参数是字段名称。假如字段不支持这个查询条件异常会被抛出。

所有数据类型均支持如下查询条件:

equalTo()
notEqualTo()
in() 可以用来匹配一组数据中的某个成员。例如来查询 name 为 ”Jill“、”William” 或者 “Trillian” 的对象,你可以使用 in(“name”, new String[]{“Jill”, “William”, “Trillian”})。in() 支持字符串、二进制数据和数值型字段。

数值型字段,包括 Date 还支持如下这些查询条件:
between()
greaterThan()
lessThan()
greaterThanOrEqualTo()
lessThanOrEqualTo()
字符串类型字段额外支持如下查询条件:
contains()
beginsWith()
endsWith()
like()
示例:

RealmResults<User> r = realm.where(User.class)
                            .greaterThan("age", 10)  //implicit AND
                            .beginGroup()
                                .equalTo("name", "Peter")
                                .or()
                                .contains("name", "Jo")
                            .endGroup()
                            .findAll();

RealmResults<User> r = realm.where(User.class)
                           .not()
                           .beginGroup()
                                .equalTo("name", "Peter")
                                .or()
                                .contains("name", "Jo")
                            .endGroup()
                            .findAll();

RealmResults<User> r = realm.where(User.class)
                           .not()
                           .in("name", new String[]{"Peter", "Jo"})

RealmResults<User> result = realm.where(User.class).findAll();
result = result.sort("age"); // Sort ascending
result = result.sort("age", Sort.DESCENDING);
查询结果的自动更新(Auto-Updating Results)

RealmResults 是对其所包含数据的自动更新视图,这意味着它永远不需要被重新查询获取。数据对象的改变会立刻被反映到相应的查询结果。

final RealmResults<Dog> puppies = realm.where(Dog.class).lessThan("age", 2).findAll();
puppies.size(); // => 0

realm.executeTransaction(new Realm.Transaction() {
    @Override
    void public execute(Realm realm) {
        Dog dog = realm.createObject(Dog.class);
        dog.setName("Fido");
        dog.setAge(1);
    }
});

puppies.addChangeListener(new RealmChangeListener() {
    @Override
    public void onChange(RealmResults<Dog> results) {
      // results and puppies point are both up to date
      results.size(); // => 1
      puppies.size(); // => 1
    }
});

这对所有的 RealmResults 有效 —— 无论是否有过滤条件、是否是链式查询。

RealmResults 的这个特性不仅使得 Realm 快速高效,而且让你的代码更简洁。举例来说,假设你的 Activity 或者 Fragment 依赖于某个查询结果,你可以将相应的 Realm 对象或者 RealmResults 保存为一个属性,你不需要在每次访问时确定其是否被更新 —— Realm 会保证这些。

你可以通过订阅 Realm notifications 来得知 Realm 数据更新了,进而刷新 UI 而不必重新查询获得 RealmResults。

因为查询结果的自动更新特性,请不要依赖于固定的索引(indices)、不变的条目数。

删除
// obtain the results of a query
final RealmResults<Dog> results = realm.where(Dog.class).findAll();

// All changes to data must happen in a transaction
realm.executeTransaction(new Realm.Transaction() {
    @Override
    public void execute(Realm realm) {
        // remove single match
        results.deleteFirstFromRealm();
        results.deleteLastFromRealm();

        // remove a single object
        Dog dog = results.get(5);
        dog.deleteFromRealm();

        // Delete all matches
        results.deleteAllFromRealm();
    }
});
异步查询(Asynchronous Queries)
RealmResults<User> result = realm.where(User.class)
                              .equalTo("name", "John")
                              .or()
                              .equalTo("name", "Peter")
                              .findAllAsync();

请注意,这里的调用并不会阻塞,而是立即返回一个 RealmResults。这很类似于标准 Java 中 Future 的概念。查询将会在后台线程中被执行,当其完成时,之前返回的 RealmResults 实例会被更新。

如果你希望当查询完成、RealmResults 被更新时获得通知,你可以注册一个 RealmChangeListener。这个监听器会在 RealmResults 被更新时被调用(通常是在事务被提交后)。

注册回调

···
private RealmChangeListener callback = new RealmChangeListener

public void onStop () {
    result.removeChangeListener(callback); // remove a particular listener
    // or
    result.removeChangeListeners(); // remove all registered listeners
}
DELPHI存取JPEG文件到SQL Server数据库(续文) 在"DELPHI存取JPEG文件到SQL Server数据库"发表之后,有许多网友来电表示支持和相关的技术咨询,在此首先对那些关心本文的朋友们表示衷心的感谢。   由于网友的需要做一个档案管理系统,存取jpeg文件到sql 2000数据库中,但在dbimage中及qrdbimage中均不能正常显示jpeg的文件,此为borland的限制,虽然使用第三方控件能达到要求,但我们还是来原始的实现一下 阅读详情

相关推荐

自动扫雷程序

很多人喜欢玩Windows的扫雷程序,去年11月份写了这个小程序,那时还在Infosys。以下是去年在我的MSN Sapce上写的:“这两天挺无聊的,Bob的扫雷战绩越来越令人惊叹,中级达到26秒,于此情况,我不得不使出了杀手锏——改注册表,将战绩定格为1秒,不过或许这样显得太贪心了,所以马上被识破,于是,鄙视的眼光投了过来,似乎我成了一个“卑鄙龌鹾”,用下三烂的手段获取胜利的人,一下子一种“

Zerostone Growth 3834

Realm数据库操作,版本更新(数据迁移)及自定义使用

1.Realm数据库在Android中的基本操作-增删改查 2.Android Realm数据库的逻辑封装,有需要的直接下载拿去使用。 3.部分代码,请查看:https://blog.youkuaiyun.com/qq_24580361/article/details/80303557

转贴 打印机自定义纸张

转贴近日因项目需要接触了打印机,自定义纸张的大小问题困扰了我一个多星期,还以为XP系统无法自定义纸张,后来在网上搜索时无意中发现,打印机都有最小纸张的标准,如果小于或大于这个标准,就算自定义好了页面,都无法选择它(不会显示出来),如果用程序强制设置打印的话,它会按A4的标准走纸,比如我用的Epson LQ-300K+这款打印机,最小纸张是10CM*10.16CM,而我要的宽度正好小于10CM,后来

Persistent8813的专栏 4104

Realm数据库使用教程(四):更新数据

更新数据 同步操作:executeTransaction修改 mRealm.executeTransaction(new Realm.Transaction() { @Override public void execute(Realm realm) { Men m...

android开发笔记 2138

陷阱式API HOOK及重入问题的解决

 小弟最近研究API Hook,参考了许多资料,阅读了很多高手的文章之后终于做好了,颇有心得,写出来以免自己以后忘记API HOOK主要由陷阱式和改引入表式,二者各有局限,改引入表式则复杂,需要一定的PE知识,他要遍历当前所有的模块,然后还要遍历模块中的IAT(引入地址表),看是否有对于某个函数的调用,而且还有两个问题:就是当前进程建立一个新的线程的时候,我们必须重新这个工作,而且,如果

zhaoyu_me的专栏 2916

Raize Components 6.2.3 for Delphi 10.4 安装指南与核心组件实战解析

在Windows桌面应用开发领域,VCL(Visual Component Library)作为Delphi/C++Builder的原生控件框架,长期支撑着企业级软件的界面构建。面对Delphi 10.4 Sydney的发布,很多老项目在升级时面临第三方组件库的适配问题,而Raize Components(现以Konopka Signature VCL Controls名义发布)正是解决这类痛点的经典选择。该组件库6.2.3版本针对Delphi 10.4提供了完整的Win32/Win64支持,通过增强的按钮

weixin_28695537的博客 323

移动端数据库神器-Realm 项目配置(入门一)

Realm是一个用来替代sqlite的解决方案,它比sqlite更轻量,同时速度更快,而且使用起来很简单顺手,还跨平台,目前已支持Java,Objective C,Swift,React-Native,Xamarin这五种语言。本篇博客以Android语言为基础,带大家一起探索realm的神奇之处。Realm官网:https://realm.io/工欲善其事,必先利其器。我们在Android Stu

z轴的博客 2315

Winpcap for delphi (Snoop 3.0)

winpcap(windows packet capture)是windows平台下一个免费,公共的网络访问系统。开发winpcap这个项目的目的在于为win32应用程序提供访问网络底层的能力。   winpcap 驱动各项功能    1> 捕获原始数据包,包括在共享网络上各主机发送/接收的以及相互之间交换的数据包;   2> 在数据包发往应用程序之前,按照自定义的规则将某些

delphi藏经阁 3716

realm数据库 For android

realm 数据库代替sqlite。面向对象存储的数据库。 网址:http://realm.io/news/realm-for-android/

huowen1990的专栏 842

Win10 LTSC秒变Win11专业版?实测无损升级全流程(附工具包下载)

本文详细介绍了如何将Win10 LTSC版本无损升级至Win11专业版的完整流程。通过实测验证,提供了关键准备工作、版本转换步骤、安装限制破解方法以及后续优化调整,确保企业用户在保留数据和配置的同时,顺利迁移到最新系统。文章包含实用工具包下载和常见问题解决方案,助力用户高效完成升级。

weixin_38166560的博客 315

串口通讯mscomm控件下载

<br />串口通讯mscomm控件下载<br /> <br />       大家知道,当我们安装VC++6.0/VB6.0时,如果选择了ACtiveX控件项(自定义安装),MSComm控件就会自动安装在计算机上了,并在系统文件夹下多了3个文件:Mscomm.srg, Mscomm32.ocx,Mscomm32.dep <br />  注意,操作系统不同,则系统文件夹不同:<br />       Win98:    windows/system<br />       Win2000:  winnt/s

微笑的艾米 4108

Ream的入门使用

一.介绍 Realm是一个不错的手机平台上的数据库,支持多种编程环境,如:Java、Object-C、React Native、Swift、Xamari等。 Realm的官网:https://realm.io/ github地址:https://github.com/realm realm-java库的文档:https://realm.io/docs/java/latest/ 二.使...

weixin_30539625的博客 272

C++ builder 中如何使用Mscomm控件

要将Mscomm加入C++ builder,分成两种情况:   第一种:机子上,装有VC,VB的。   我们就可以直接打开C++ builder 选择component->import activeX control ->选择“Microsoft comm control 6

leon444383212的专栏 5145

Android Realm数据库完美解析

当我们的app有数据需要保存到本地缓存时,可以使用file,sharedpreferences,还有sqlite。 sharedpreferences其实使用xml的方式,以键值对形式存储基本数据类型的数据。对于有复杂筛选查询的 操作,file和sharedpreferences都不能满足了。sqlite可以满足有大量复杂查询要求的缓存数据操作。但是sqlite的使用略复杂,代码量很大,还好网

阿杜 3万+

个人防火墙--中间层NDIS中间层驱动发送和接收流程

1)用户态(user-mode)。 在用户态下进行网络数据包的拦截有三种方法:WinsockLayeredServiceProvider(LSP)、Windows2000包过滤接口、替换系统自带的WINSOCK动态连接库。在用户态下进行数据包拦截最致命的缺点就是只能在Winsock层次上进行,而对于网络协议栈中底层协议的数据包无法进行处理。因此,这些方法并不适合个人防火墙。 2)内核态

u011386637的博客 4024

nvlddmkm.sys蓝屏真相:VIDEO_TDR_FAILURE根因与实战排查

VIDEO_TDR_FAILURE(显卡超时故障)是Windows图形子系统中WDDM驱动模型的关键保护机制,本质是GPU任务响应超时触发的强制恢复,而非驱动程序错误。其核心原理在于TDR(Timeout Detection and Recovery)机制对GPU指令执行时限的硬性约束,默认2秒阈值兼顾系统稳定性与响应实时性。该问题的技术价值在于暴露GPU算力、显存带宽、供电散热及软件资源调度等多维度协同瓶颈,广泛应用于游戏、AI训练、视频渲染和CAD设计等高负载场景。深入理解nvlddmkm.sys与TD

weixin_33755649的博客 425

C#与C++工程选型:从上位机到边缘AI的实战决策逻辑

在工业软件与嵌入式系统开发中,C#和C++并非简单的语言性能比拼,而是面向不同工程约束的技术契约选择。C#凭借.NET生态的确定性、调试链路完整性与COM/互操作能力,在上位机、HMI、遗留系统改造等场景提供可预测的交付节奏与低维护成本;C++则依托对内存、硬件资源与底层API的直接掌控力,在边缘AI推理、实时控制环、高密度计算等资源紧绷场景中不可替代。二者差异本质是抽象层级与控制粒度的权衡:C#降低工程风险,C++换取极致性能。本文结合产线MES、Jetson AI部署、三菱PLC互通等真实案例,解析如何

weixin_34357436的博客 366

.NET Framework 1.0到4.0底层演进:CLR、泛型、LINQ与并发模型的技术脉络

.NET Framework 是微软构建的统一托管运行时平台,其核心在于公共语言运行时(CLR)对内存管理、线程调度与类型系统的深度控制。从1.0初代寄生式设计,到2.0引入分代垃圾回收与泛型支持,再到3.5依托表达式树实现LINQ声明式查询,最终在4.0完成IOCP线程池与Task并行库的工程落地——这一演进本质是运行时能力持续解耦、强化与标准化的过程。它奠定了现代.NET跨平台、高性能与安全隔离的技术根基,广泛应用于企业级Web服务、桌面应用及混合部署系统。理解CLR版本差异、泛型JIT特化机制与LIN

as2886089的博客 414
上一篇: SAX解析xml characters方法要注意的问题
下一篇: Android AOP(一):APT Annotation Processing Tool 注解处理器
trinity2018
博客等级 码龄14年 3粉丝 19原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值