在Swift中使用NSPredicate进行数据库查询

在Swift中使用NSPredicate进行数据库查询,第1张

概述简介 NSPredicate提供了一个通用的数据查询方式,有两种Predicate类型,分别是comparison 和 compound: comparison predicate 使用运算符来比较两个表达式 compound predicate 对比两个或多个predicate的结果,或者让其他的predicate 失效. Cocoa 里支持非常多的 predicate 类型,例如: 简单的比较 简介

nspredicate提供了一个通用的数据查询方式,有两种Predicate类型,分别是comparison 和 compound:

comparison predicate 使用运算符来比较两个表达式 compound predicate 对比两个或多个predicate的结果,或者让其他的predicate 失效.

Cocoa 里支持非常多的 predicate 类型,例如:

简单的比较: grade == 7 或者 firstname like 'Mark' 大小写或读音敏感的查询:name contains[cd] 'citroen' 逻辑 *** 作符:(firstname beginswith 'M') AND (lastname like 'Adderley')

你还可以根据关系创建predicate,例如:group.name matches 'work.*'ALL children.age > 12以及ANY children.age > 12根据 *** 作创建例如:@sum.items.price < 1000.

你可以把 predicates 用在任何类上,但这个类必须是遵循 key-value-Coding 的类。

nspredicate的局限

predicate查询可能会翻译成SQL语句或xml格式或者其他格式,这取决于后端存储的类型。因此并不是所有的 *** 作后端存储都能支持。下面是一些例子:

matches 关键字使用正则来进行匹配,所以是不被CoreData的 sql 存储支持的,但是却可以用在内存中的过滤。 CoreData sql 存储里每次查询只能支持一对多的 *** 作,因此任何应用在sql存储的predicate都只能有 ALL AND IN 中的一个 *** 作符。 不能将任意的SQL查询转换成predicate。 ANYKEY *** 作符只能用在Spotlight的查询中。 Spotlight中不支持关系查询。 创建Predicate

使用格式化的字符串创建

可以使用nspredicate的类方法predicateWithFormat 从字符串创建一个predicate对象:

nspredicate* predicate = [nspredicate predicateWithFormat: @"(lastname like[cd] %@) AND (birthday > %@)",lastnameSearchString,birthdaySearchDate];

示例代码中的like[cd] *** 作符表示大小写(c 表示case-insensitive,)发音(d 表示 diacritic-insensitive)不敏感。

字符串常量、变量和通配符

字符串常量必须用引号包裹起来,用单引号或双引号都是可以的,如果你用%@来进行参数替换(例如firstname like %@),引号会自动添加,如果你用的是字符串常量,那你必须自己用引号包裹起来:

nspredicate* predicate = [nspredicate predicateWithFormat: @"lastname like[c] 'S*'"];// 或者nspredicate* predicate = [nspredicate predicateWithFormat: @"lastname like[c] \"S*\""];

在使用通配符时必须考虑引号的问题,你应该把通配符添加到一个预定义的变量中来进行参数替换:

Nsstring* prefix = @"prefix";Nsstring* suffix = @"suffix";nspredicate* predicate = [nspredicate predicateWithFormat: @"SELF like[c] %@",[[prefix stringByAppendingString: @"*"] stringByAppendingString: suffix]];BOol ok = [predicate evaluateWithObject: @"prefixxxxxxxsuffix"];

下面则是一个错误的例子:

predicate = [nspredicate predicateWithFormat: @"SELF like[c] %@*%@",prefix,suffix];ok = [predicate evaluateWithFormat: @"prefixxxxxsuffix"];

布尔值

用下面的方法可以来测试布尔值是否相等:

let aBool = truelet anotherPredicate = nspredicate(format: "anAttribute == %@",NSNumber(bool: aBool))nspredicate(format: "anAttribute == YES")

动态属性名

当通过参数替换时,因为string变量会被双引号包裹,所以不能用%@来指定动态属性:

Nsstring* attribute = @"firstname";Nsstring* attributeValue = @"Adam";nspredicate* predicate = [nspredicate predicateWithFormat: @"%@ like %@",attributename,attributeValue];

如果需要指定一个动态属性,可以使用%K:

predicate = [nspredicate predicateWithFormat: @"%K like %@",attributeValue];

直接用代码来创建的nspredicate

Objective-C:

NSExpression *lhs = [NSExpression ExpressionForKeyPath:@"revenue"]; NSExpression *greaterThanRhs = [NSExpression ExpressionForConstantValue:[NSNumber numberWithInt:1000000]]; nspredicate *greaterThanPredicate = [NSComparisonPredicate predicateWithleftExpression:lhs rightExpression:greaterThanRhs modifIEr:NSDirectPredicateModifIEr type:NSGreaterThanorEqualtopredicateOperatorType options:0]; NSExpression *lessthanRhs = [NSExpression ExpressionForConstantValue:[NSNumber numberWithInt:100000000]]; nspredicate *lessthanPredicate = [NSComparisonPredicate predicateWithleftExpression:lhs rightExpression:lessthanRhs modifIEr:NSDirectPredicateModifIEr type:NSLessthanPredicateOperatorType options:0]; NSCompoundPredicate *predicate = [NSCompoundPredicate andPredicateWithSubpredicates: @[greaterThanPredicate,lessthanPredicate]];

Swift:

let lhs = NSExpression(forKeyPath: "revenue")let greaterThanRhs = NSExpression(forConstantValue: "张三")let greaterPredicate = NSComparisonPredicate(leftExpression: lhs,rightExpression: greaterThanRhs,modifIEr: .DirectPredicateModifIEr,type: .BeginsWithPredicateOperatorType,options: .CaseInsensitivePredicateOption)let lessthanRhs = NSExpression(forConstantValue: 1000000000000)let lessthanPredicate = NSComparisonPredicate(leftExpression: lhs,rightExpression: lessthanRhs,type: .LessthanorEqualtopredicateOperatorType,options: .CaseInsensitivePredicateOption)let compoundPredicate = NSCompoundPredicate(andPredicateWithSubpredicates: [greaterPredicate,lessthanPredicate])

使用模板来创建predicate

Objective-C:

nspredicate* predicateTemplate = [nspredicate predicateWithFormat: @"lastname like[c] $LAST_name"];nspredicate* predicate = [predicateTemplate predicateWithSubstitutionVariables: [NSDictionary dictionaryWithObject:@"Turner" forKey:@"LAST_name"]];

Swift:

let predicateTemplate = nspredicate(format: "lastname like[c] $LAST_name")let new = predicateTemplate.predicateWithSubstitutionVariables(["LAST_name":"turner"])

使用Predicate

使用nspredicate的evaluateWithObject方法并传入要查询的数据,这个方法会返回一个布尔值:

Objective-C:

nspredicate* predicate = [nspredicate predicateWithFormat: @"SELF in %@",@[@"Stig",@"Shaffig",@"Chris"]];BOol result = [predicate evaluateWithObject: @"Shaffig"];

Swift:

let predicate = nspredicate(format: "SELF in %@",["Stig","Shaffig","Chris"]) // SELF IN {"Stig","Chris"}let result = predicate.evaluateWithObject("Stig") // true

在数组中使用Predicate

Objective-C:

NSMutableArray* array = [NSMutableArray arrayWithObjects: @"Nick",@"Ben",@"Adam",@"Melissa",nil];nspredicate* sPredicate - [nspredicate predicateWithFormat: @"SELF contains[c] 'e'"];[array filterUsingPredicate: sPredicate];

在predicate中传入key-path

Nsstring* departmentname = ...;nspredicate* predicate = [nspredicate predicateWithFormat: @"department.name like %@",departmentname];

如果你使用的是一对多的关系,那么predicate的构造会有些许不同:

nspredicate* predicate = [nspredicate predicateWithFormat: @"ANY employees.firtname like 'Matthew'"];
nspredicate* predicate = [nspredicate predicateWithFormat: @"ANY employees.salary > %f",salary];

使用空值

comparison predicate不会匹配任何的null值,除非nil或者NSNull,也就是($value == nil)。看一下下面的例子:

Nsstring* firstname = @"Ben";       NSArray* array = @[@{@"lastname" : @"Turner"},@{@"firstname" : @"Ben",@"lastname" : @"Ballard",@"birthday" : [NSDate dateWithString: @"1972-03-24 10:45:32 +0600"]}                          ];       nspredicate* predicate = [nspredicate predicateWithFormat:@"firstname like %@",firstname];       NSArray* filteredArray = [array filteredArrayUsingPredicate:predicate];       NSLog(@"%@",filteredArray);

predicate 匹配了包含firstname 键的值,却没匹配上不包含这个键的值,下面的例子是同样的道理:

NSDate* referenceDate = [NSDate dateWithTimeIntervalSince1970:0];       predicate = [nspredicate predicateWithFormat:@"birthday > %@",referenceDate];       filteredArray = [array filteredArrayUsingPredicate:predicate];       NSLog(@"%@",filteredArray); // (       // { birthday = "1972-03-24 04:45:32 +0000";        // firstname = Ben;        //lastname = Ballard; })

如果你想要匹配null值,你就得添加一条额外的对比:

predicate = [nspredicate predicateWithFormat:@"(firstname == %@) || (firstname == nil)"];       filteredArray = [array filteredArrayUsingPredicate:predicate];       NSLog(@"%@",filteredArray);

在 CoreData 上使用predicate

下面的例子展示了在CoreData中使用nspredicate进行查询:

NSFetchRequest *request = [[NSFetchRequest alloc] init];       NSEntityDescription *entity = [[NSEntityDescription entityForname: @"Employee"] inManagedobjectContext: managedobjectContext];       [request setEntity: entity];       NSNumber *salarylimit = @2000;       nspredicate *predicate = [nspredicate predicateWithFormat:@"salary > %@",salarylimit];       [request setPredicate: predicate];       NSError *error;       NSArray *array = [managedobjectContext executeFetchRequest: request error: &error];
总结

以上是内存溢出为你收集整理的在Swift中使用NSPredicate进行数据库查询全部内容,希望文章能够帮你解决在Swift中使用NSPredicate进行数据库查询所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/1075306.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-26
下一篇 2022-05-26

发表评论

登录后才能评论

评论列表(0条)

保存