走进 Realm 的世界

来源:XcodeMen(郭杰)

链接:http://www.jianshu.com/p/0e248f000405

本文由我们团队的郭杰童鞋分享。



Realm是什么

Realm是由Y Combinator公司孵化出来的一款可以用于iOS(同样适用于Swift&Objective-C)和Android的跨平台移动数据库。历经几年才打造出来,为了彻底解决性能问题,核心数据引擎用C++打造,并不是建立在SQLite之上的ORM,所以Realm相比SQLite和CoreData而言更快、更好、更容易去使用和完成数据库的操作花费更少的代码。它旨在取代CoredData和sqlite,它不是对coreData的简单封装、相反的,Realm它使用了它自己的一套持久化存储引擎。而且Realm是完全免费的,这不仅让它变得更加的流行也使开发者使用起来没有任何限制。

Realm的特点

Realm以难以令人置信的快速和易用让开发者能够用仅仅几行代码完成你所需要的一切功能。它旨在打造让用户得在到移动领域离线时的最好体验,我整理了Realm具有的如下特点:

  • 易安装:正如你在将要看到的使用Realm工作。安装Realm就像你想象中一样简单。在Cocoapods中使用简单命令,你就可以使用Realm工作。
  • 速度上:Realm是令人无法想象的快速使用数据库工作的库。Realm比SQLite和CoreData更快,这里的数据就是最好的证明。
  • 跨平台:Realm数据库文件能够跨平台和可以同时在iOS和Andriod使用。无论你是使用Java, Objective-C, or Swift,你都可以使用你的高级模型。
  • 可扩展性:在开发你的移动App特别是如果你的应用程序涉及到大量的用户和大量的记录时,具有良好的可扩展性是非常重要的。
  • 好的文档&支持:Realm团队提供了可读的,非常有组织的并且丰富的文档。如果你遇到什么问题通过Twitter、GitHub或者Stackoverflow与他们交流。
  • 可靠性:Realm已经被巨头公司使用在他们的移动App中,像Pinterest, Dubsmash, and Hipmunk。
  • 免费性:使用Realm的所有功能都是免费的。
  • 懒加载:只有当你真正访问对象的值时候才真正从磁盘中加载进来。

必备条件

  • iOS7及以后, OS X 10.9及以后。
  • 至少Xcode7.3及以后。
  • Realm针对iOS分为两部分,一个是Swift版本,一个是Objective-C版本。

Realm安装

  • 动态Framework库。直接下载最新Realm的release版本,拖入项目工程中即可。
  • CocoaPods管理工具。使用CocoaPods0.39版本以及上。
  • Carthage管理工具。使用Carthage 0.17.0版本及以上。
  • 静态Framework库。直接下载最新Realm的release版本,拖入项目工程中即可。

(注意:本文将重点讲解使用CocoaPods的方式安装Realm到项目中)

配置Xcode和所需的工具

在配置Xcode项目之前,请确保你的电脑上已经安装了CocoaPods,因为我们会使用CocoaPods在项目中安装Realm。如果你不熟悉CocoaPods,你可以查看给你的网上的相关教程。

现在创建一个新的工程,选择”Single View Application”,命名为RealmDemo或者任何你想的名称。请确保创建的项目是Objective-C语言。现在在终端打开你的项目目录并执行如下的CocoaPods命令:

Pod init

然后,使用Xcode打开Podfile文件,向其中添加如下内容:

接下来执行Pod install命令去下载Realm安装到项目中。完成之后,你将看到新的Xcode项目的workspace在Podfile文件被生成。请打开Xcode的RealmDemo.xworkspace和不要打开xcodeproj。打开workspace之后,你将看到Pod相关文件已经被集成进去了。

现在Xcode已经准备好可以使用Realm工作了,但是我们还将需要安装如下工具为的是让我们使用Realm更轻松,容易。

在Xcode中安装Realm插件(仅仅用于Xcode8以下版本)

Realm团队已经提供了非常有用的Xcode插件,它将被使用在生成Realm的模型。为了安装插件,我们使用Alcatraz.对于那些不了解什么是Alcatraz的人来说,可以自行去搜索下,Alcatraz真的非常好用。为了安装Alcatraz需要通过以下终端中的命令行并且重启你的Xcode。

curl -fsSL https://raw.githubusercontent.com/supermarin/Alcatraz/master/Scripts/install.sh | sh

之后在Xcode中,选择Window,就可以看到下拉列表中的Package Manager选项,就表明已经安装成功。

在Xcode弹出窗口中选择需要的插件或者模板,在搜索框中你可以搜索任何插件或者各种各样的模板去自定义你的Xcode。在搜索框中输入”Realm”和”RealmPlugin”插件将显示出来,点击进行安装。

Realm浏览器

除了以上的工具和插件之外,还有一个就是Realm浏览器。这个浏览器可以帮助你去阅读和编辑你的.realm数据库文件。这些文件是在你的应用程序中被创建出来的,它包含了关于数据库表中实体、属性和记录的信息。目前直接在Mac App Store中搜索Realm Browser进行下载即可。下载完成后,打开Realm浏览器选择Tools-> Generate demo database。它将为你生成测试数据库文件和你可以打开它看到里面的数据。当你打开你的demo database时你应该看到

正如你看到的Class RealmTestClass1,它有1000个记录和它展示了不同的列数据。接下来我们将讨论Realm模型支持的属性类型。

Realm的数据库创建

目前Realm提供了3种方式创建数据库对象,一种是存储在默认路径下的数据库,一种是我们可以指定自己指定数据库文件的存储路径和只读属性,还有一种可以使用内存数据库。

  • 默认Realm数据库

RLMRealm *realm = [RLMRealm defaultRealm];

  • 自定义数据库(名称、路径)

//注意:新版本中关于配置Relam的文件路径包括名称等等都是在RLMRealmConfiguration对象中完成。

RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];

// Use the default directory, but replace the filename with the username

config.fileURL = [[[config.fileURL URLByDeletingLastPathComponent]

URLByAppendingPathComponent:username]

URLByAppendingPathExtension:@"realm"];

// Set this as the configuration used for the default Realm

[RLMRealmConfiguration setDefaultConfiguration:config];

或者是

NSString *docPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];

NSString *dbPath = [docPath stringByAppendingPathComponent:@"guojie.realm"];

RLMRealm *realm1 = [RLMRealm realmWithURL:url];

当然了,RLMRealmConfiguration对象中还可以设置是否只读数据库

RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];

// Get the URL to the bundled file

config.fileURL = [[NSBundle mainBundle] URLForResource:@"MyBundledData" withExtension:@"realm"];

// Open the file in read-only mode as application bundles are not writeable

config.readOnly = YES;

  • 内存数据库

    正常的Realm数据库是存储在硬盘上的,但是我们可以通过在RLMRealmConfiguration中设置inMemoryIdentifier属性来创建一个内存数据库。

RLMRealmConfiguration *cfg = [RLMRealmConfiguration defaultConfiguration];

cfg.inMemoryIdentifier = @"test";

RLMRealm *realm = [RLMRealm realmWithConfiguration:cfg error:nil];

注意:内存数据库在每次程序退出时不会保存数据。如果某个内存Realm实例没有被引用,所有的数据在实例对象释放的适合也会被释放。建议你在app中用强引用来钳制所有新建的内存Realm数据库实例。

Realm的构建数据模型

Realm的数据模型是用传统的 Objective-C 接口(interface)和属性(@property)定义的。 只要定义 RLMObject的一个子类或者一个现成的模型类,你就能轻松创建一个Realm的数据模型对象。Realm模型对象和其他的Objective-C的功能很相似–你可以给它们添加你自己的方法和protocol然后和其他的对象一样使用。 唯一的限制就是从它们被创建开始,只能在一个进程中被使用。如果你已经安装了Xcode Plugin(Xcode版本

现在一起来使用Xcode中的Realmh插件去创建Realm类。打开Xcode和创建新文件。在右边框中选择Realm:

然后选择名称为Dog类名的Objective-C文件。现在你应该看到如下信息:

用一个Dog对象来表示一条小狗,紧接向类中添加属性。然后类在添加属性之后向如下这样:

  • Dog.h

@interface Dog : RLMObject

/** 名字 */

@property (nonatomic, copy) NSString *name;

/** 年龄 */

@property (nonatomic, assign) NSInteger age;

/** 品种 */

@property (nonatomic, copy) NSString *type;

RLM_ARRAY_TYPE(Dog)

@end

  • Dog.m

@implementation Dog

/**

设置主键

*/

+ (NSString *)primaryKey{

return @"numId";

}

/**

添加索引的属性

*/

+ (NSArray *)indexedProperties{

return @[@"name"];

}

/**

添加默认值

*/

+ (NSDictionary *)defaultPropertyValues{

return @{@"type":@"taidi"

};

}

@end

说明:

  1. Realm支持的属性类型如下:BOOL, bool, int, NSInteger, long, float, double, CGFloat, NSString, NSDate 和 NSData。
  2. 你可以使用RLMArray和RLMObject来模拟对一或对多的关系(Realm也支持RLMObject继承)
  3. Realm忽略了Objective-C的property attributes(如nonatomic, atomic, strong, copy, weak 等等)。 所以,推荐在创建模型的时候不要使用任何的property attributes。但是,假如你设置了,这些attributes会一直生效直到RLMObject被写入realm数据库。
  4. 定义了RLM_ARRAY_TYPE(Dog) 这个宏表示支持RLMArray该属性
  5. 另外Realm提供了以下几个方法供对属性进行自定义:
    • + (NSArray *)indexedProperties: 可以被重写来来提供特定属性(property)的属性值(attrbutes)例如某个属性值要添加索引。
    • + (nullable NSDictionary *)defaultPropertyValue: 为新建的对象属性提供默认值。
    • + (nullable NSString *)primaryKey: 可以被重写来设置模型的主键。定义主键可以提高效率并且确保唯一性。
    • + (nullable NSArray *)ignoredProperties:可以被重写来防止Realm存储模型属性。
    • - (void)transactionWithBlock:(__attribute__((noescape)) void(^)(void))block:自动更新对象数据。
    • + (NSArray *)requiredProperties:可选属性

Realm的数据增删改查

存储数据

(1).创建Dog对象,依次设置各个属性

Dog *myDog = [[Dog alloc]init];

myDog.numId = @"1";

myDog.name  = @"haha";

myDog.age   = 10;

myDog.type  = @"taidi";

(2).使用字典创建Dog对象

Dog *myDog2 = [[Dog alloc]initWithValue:@{@"numId":@"2",

@"name" :@"xiaoxiao",

@"age"  :@11,

@"type" :@"heibei"

}];

(3).使用数组创建Dog对象

Dog *myDog3 = [[Dog alloc]initWithValue:@[@"3",@"小小",@12,@"smy"]];

(4).除此之外,还支持嵌套的对象

如果在对象的属性中有RLMObjects对象或者RLMArrays对象,在这种情况下当你使用字典或者数组途径创建对象时,你就可以使用数组或者字典对象替换属性来表示它的属性。例如下面的嵌套对象例子:

// Instead of using already existing dogs...

Person *person1 = [[Person alloc] initWithValue:@[@"Jane", @30, @[aDog, anotherDog]]];

// ...we can create them inline

Person *person2 = [[Person alloc] initWithValue:@[@"Jane", @30, @[@[@"Buster", @5],

@[@"Buddy", @6]]]];

说明:

1. 最明显的是使用指定的初始化程序创建一个对象。注意被设置为必须的属性在被添加之前一定要被设置值。

2. 对象可以通过传入与属性名称一样的字典Key和Values来创建。

3. 最后,对象可以使用数组创建,需要注意的是在数组中值的顺序必须跟Model中相应属性顺序保持一致。

4. 需要注意的是: RLMArray仅仅只能包含RLMObject对象,而不包括基本数据类型例如NSString。

(5).存储数据到Realm中

RLMRealm *realm = [RLMRealm defaultRealm];

[realm beginWriteTransaction];

[realm addObject:myDog];

[realm commitWriteTransaction];

请注意:当你同时执行多个写入操作时,它们将会阻碍执行的所在线程。所以你应该考虑在单独的线程中处理而不是UI线程。另一个就是,当你在执行写入操作时,读取操作不会被阻塞。这一点是很有用的,因为你的App可以执行许多读取操作时在后台同一时间写入事务可能也会在后台执行中。

删除数据

  • 删除指定的数据:

- (void)deleteObject:(RLMObject *)object;

  • 删除一组数据:

- (void)deleteObjects:(id)array;

  • 删除全部数据:

- (void)deleteAllObjects;

修改数据

如果该条数据不存在则会新家一条数据。

  • 针对单条数据进行的修改或新增:

- (void)addOrUpdateObject:(RLMObject *)object;

  • 针对一组数据的修改或新增:

- (void)addOrUpdateObjectsFromArray:(id)array;

  • 针对带有主键的数据修改或新增

如果你的模型类中包含一个主键,Realm可以智能的以这个主键来更新或添加数据。

- (void)addOrUpdateObject:(RLMObject *)object;

  • 使用KVC修改数据

如果你是一个iOS开发者,你将很熟悉KVC,Realm类中例如对象、结果集、list也是兼容KVC的。这样可以帮助你利用runtime设置/更新属性。看看这个例子:

RLMResults *dogs = [Dog allObjects];

[[RLMRealm defaultRealm] transactionWithBlock:^{

[[Dog firstObject] setValue:@20 forKeyPath:@"age"];

// set each person‘s name property to "wangwu"

[dogs setValue:@"wangwu" forKeyPath:@"name"];

}];

说明:对于增加、删除、修改必须要在事务中进行操作。

查询数据

查询会返回RLMResults结果集,它里面包含了RLMObject对象的集合。RLMResults的接口方法非常类似于NSArray一样可以使用下标索引访问元素。与NSArray不同的是,RLMResults的元素类型只有单一的RLMObject的子类型。所有的查询都是懒查询,即只有当访问属性时,数据才会被读取出来。查询的结果不是拷贝本地磁盘中的数据而是直接原始数据,所以修改某一处的数据将会直接修改磁盘中的数据。在结果集被使用的过程中,查询的执行是会被延迟的。这意味着链接几个临时中间的RLMResults所进行的排序和过滤数据的操作不执行额外的工作去处理中间的状态。一旦查询已经被执行或者通知block已经被添加,RLMResult在可能的情况下在后台线程上执行查询以保证RLMResult的结果始终是Relam中最新的。

  • 查询全部数据

RLMResults *dogs = [Dog allObjects];

或者指定Realm数据库:

NSString *path = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];

NSString *realmPath = [path stringByAppendingPathComponent:@"guojie.realm"];

RLMRealm *realm = [RLMRealm realmWithPath:realmPath];

RLMResults *results = [Dog allObjectsInRealm:realm];

在条件查询中,如果你熟悉谓词,那么你已经知道该如何查询了。RLMObjects, RLMRealm, RLMArray, and RLMResults都提供了允许让你通过传递一个谓词实例、谓词字符串、谓词格式字符串来查询具体RLMObject实例的方法。

  • 条件查询

假设要查询名字是guojie和年龄是10的dog对象:

RLMResults *results = [Dog objectsWhere:@"name = ‘haha‘ AND age = 10"];

也可以使用谓词查询:

NSPredicate *pred = [NSPredicate predicateWithFormat:@"type = ‘%@‘ AND name = ‘%@‘", @"taidi", @"haha"];

RLMResults *results = [Dog objectsWithPredicate:pred]

  • 条件排序

假设已经查询出type是taidi,name是haha的数据结果集后,需要将结果按照num字段进行递减排序:

NSPredicate *pred = [NSPredicate predicateWithFormat:@"type = ‘%@‘ AND name = ‘%@‘", @"taidi", @"haha"];

RLMResults *results = [Dog objectsWithPredicate:pred];

results = [results sortedResultsUsingProperty:@"numId" ascending:NO];

请注意:结果集的顺序只能保证在查询排序时保持一致,出于性能的原因,查询顺序不保证被保存。如果你需要为何查询的顺序,则需要其他一些解决方案。

  • 链式查询(结果过滤)

假设要查询的还是type是taidi,name是haha的结果集,还可以这样处理:

RLMResults *results1 = [Dog objectsWhere:@"type = ‘taidi‘"];

RLMResults *results2 = [results1 objectsWhere:@"name = ‘haha‘"];

通知

每当一次写事务完成Realm实例都会向其他线程上的实例发出通知,可以通过注册一个block来响应通知:

self.token = [realm addNotificationBlock:^(NSString *note, RLMRealm * realm) {

[_listTableView reloadData];

}];

只要有任何的引用指向这个返回的notification token,它就会保持激活状态。在这个注册更新的类里,你需要有一个强引用来钳制这个token, 因为一旦notification token被释放,通知也会自动解除注册。

@property (nonatomic, strong) RLMNotificationToken *token;

另外可以使用下面的方式解除通知:

[realm removeNotification:self.token];

Realm版本迁移

当你和数据库打交道的时候,你需要改变数据模型(Model),但是因为Realm中的数据模型被定义为标准的Objective-C interfaces,要改变模型,就像改变其他Objective-C interface一样轻而易举。举个例子,假设有个数据模型Person:

@interface Person : RLMObject

@property NSString *firstName;

@property NSString *lastName;

@property int age;

@end

当我们想添加一个字段fullName属性而不是first和last names时,我们可以这样做:

@interface Person : RLMObject

@property NSString *fullName;

@property int age;

@end

接下来执行迁移:

// Inside your [AppDelegate didFinishLaunchingWithOptions:]

RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];

config.schemaVersion = 1;

config.migrationBlock = ^(RLMMigration *migration, uint64_t oldSchemaVersion) {

//如果从没迁移过,oldSchemaVersion == 0

if (oldSchemaVersion < 1) {

// The enumerateObjects:block: method iterates

// over every ‘Person‘ object stored in the Realm file

[migration enumerateObjects:Person.className

block:^(RLMObject *oldObject, RLMObject *newObject) {

// 设置新增属性的值

newObject[@"fullName"] = [NSString stringWithFormat:@"%@ %@",

oldObject[@"firstName"],

oldObject[@"lastName"]];

}];

}

};

[RLMRealmConfiguration setDefaultConfiguration:config];

在迁移的过程中重命名属性名称

// Inside your [AppDelegate didFinishLaunchingWithOptions:]

RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];

config.schemaVersion = 1;

config.migrationBlock = ^(RLMMigration *migration, uint64_t oldSchemaVersion) {

// We haven’t migrated anything yet, so oldSchemaVersion == 0

if (oldSchemaVersion < 1) {

// The renaming operation should be done outside of calls to `enumerateObjects:`.

[migration renamePropertyForClass:Person.className oldName:@"yearsSinceBirth" newName:@"age"];

}

};

[RLMRealmConfiguration setDefaultConfiguration:config];

JSON

Realm并没有直接的支持JSON,但是它可以使用[NSJSONSerialization JSONObjectWithData:options:error:]转化之后的结果。在结合标准的API中的createOrUpdateInRealm方法就可以解决。

// A Realm Object that represents a city

@interface City : RLMObject

@property NSString *name;

@property NSInteger cityId;

// other properties left out ...

@end

@implementation City

@end // None needed

NSData *data = [@"{\"name\": \"San Francisco\", \"cityId\": 123}" dataUsingEncoding: NSUTF8StringEncoding];

RLMRealm *realm = [RLMRealm defaultRealm];

// 插入包含JSON的NSData数据

[realm transactionWithBlock:^{

id json = [NSJSONSerialization JSONObjectWithData:data options:0 error:NULL];

[City createOrUpdateInRealm:realm withValue:json];

}];

说明:如果在JSON中包含有嵌套的对象或数组,那么会被自动被映射到一对多关系相关的嵌套对象中。

多线程访问Realm

当需要从多线程去访问同一个Realm时,你必须初始化一个新的Realm,去得到在App中每一个线程有一个不同的实例。只要你指定相同的Realm配置,那么所有的Realm实例将指向磁盘上的同一个文件。Realm是不支持在线程之间共享Relam实例的。当在一个单一事务中通过批量处理来写入非常大的数据,使用多线程是非常有用的。为了避免阻塞主线程,写入事务可以放在使用GCD在后台进行。Realm对象不是线程安全的,所有决定了不能线程间共享。因此你必须在你想要读取或者写入的每一个线程中获取到Realm的对象实例。如下是在后台队列中插入100万个对象的例子:

dispatch_async(queue, ^{

@autoreleasepool {

// Get realm and table instances for this thread

RLMRealm *realm = [RLMRealm defaultRealm];

// Break up the writing blocks into smaller portions

// by starting a new transaction

for (NSInteger idx1 = 0; idx1 < 1000; idx1++) {

[realm beginWriteTransaction];

// Add row via dictionary. Property order is ignored.

for (NSInteger idx2 = 0; idx2 < 1000; idx2++) {

[Person createInRealm:realm

withValue:@{@"name"      : randomString,

@"birthdate" : randomDate}];

}

// Commit the write transaction

// to make this data available to other threads

[realm commitWriteTransaction];

}

}

});

总结

Realm是非常适合去管理本地存储和数据库。Realm给了你代码层面非常强大的可扩展性和力量。对于大多数App甚至是游戏,我认为你是需要使用数据库,Realm值得你去使用。

参考资料

  • Building a ToDo App Using Realm and Swift

    https://www.appcoda.com/realm-database-swift/

  • iOS中Realm数据库的基本用法

    http://blog.devzeng.com/blog/simple-usage-of-realm-in-ios.html

  • Realm-在iOS中应用-全新的数据库思维模式

    http://blog.csdn.net/xiaoluodecai/article/details/50618445

  • Realm数据库基础教程

    http://www.cocoachina.com/ios/20150505/11756.html

  • 移动端数据库新王者:realm

    http://ios.jobbole.com/85041/

  • Realm Tutorial: Getting Started

    https://www.raywenderlich.com/112544/realm-tutorial-getting-started

时间: 2024-10-11 07:04:45

走进 Realm 的世界的相关文章

走进C++程序世界------异常处理

一. 概述 C++自身有着非常强的纠错能力,发展到如今,已经建立了比较完善的异常处理机制.C++的异常情况无非两种,一种是语法错误,即程序中出现了错误的语句,函数,结构和类,致使编译程序无法进行.另一种是运行时发生的错误,一般与算法有关. 关于语法错误,不必多说,写代码时心细一点就可以解决.C++编译器的报错机制可以让我们轻松地解决这些错误. 第二种是运行时的错误,常见的有文件打开失败.数组下标溢出.系统内存不足等等.而一旦出现这些问题,引发算法失效.程序运行时无故停止等故障也是常有的.这就要求

【密码学】一万字带您走进密码学的世界(下)

引文 密码学是研究编制密码和破译密码的技术科学.研究密码变化的客观规律,应用于编制密码以保守通信秘密的,称为编码学:应用于破译密码以获取通信情报的,称为破译学,总称密码学. 在<一万字带您走进密码学的世界(上)>的文章中我们探讨了对称密码体系,哈希函数等技术,本文继续探讨密码学剩余的部分,本文的主要内容包括,非对称密码体系,签名算法等,因为本部分是区块链技术的基石,所以我会讲的更加详细一点,虽然我已经尽最大努力使思想简化,但是其中的数学理论对于很多人还是很晦涩,建议读者开始之前先读下数论的有关

走进C++程序世界------IO标准库介绍

流概述 流是C++标准的组成部分,流的主要目标是,将从磁盘读取文件或将输入写入控制台屏幕的问题封装起来,创建流后程序员就可以使用它,流将负责处理所有的细节. IO类库 在C++输入?输出操作是通过C++系统提供的完成I/O操作的一组类实现的.主要包括: 标准流类:处理与标准输入设备(键盘)和输出设备(显示器)关联的数据流 文件流类:处理与磁盘文件关联的数据流 字符串流类:利用内存中的字符数组处理数据的输入输出 异常类等:处理异常错误. 标准IO对象: 包含iostream类的C++程序启动时,将

Docker学习笔记(四)走进docker的世界

Docker学习笔记(四)走进docker的世界 一个容器实际上是运行在宿主机上的一个进程. 只不过在启动这个进程之前进行了一些特殊处理,让这个容器进入了一个全新的虚拟环境,与宿主机的环境分开, 所以这个进程及其子进程认为自己运行在一个独立的世界里面. #查看进程 sudo docker run -d cyf:sshd /usr/sbin sshd -D ps axf 可以看到在宿主机里面的5948这个sshd进程 下面进入docker容器查看 sudo docker-enter.sh 6867

【SpringMVC学习02】走进SpringMVC的世界

上一篇博文主要介绍了springmvc的整个架构执行流程,对springmvc有了宏观上的把握,这一篇博文主要以案例作为驱动,带你走进springmvc的世界.案例中的需求很简单:对商品列表的查询.表的话还是使用我在学习mybatis时候用的表,具体可以参见这篇博文中的建表语句. 1. 环境的搭建 需要导入spring的jar包,单纯的入门springmvc的话不需要导入所有的spring jar包,但是核心包和spring-web/spring-webmvc是一定要导入的,考虑到后面还会和my

详解C++引用——带你走进引用的世界

 一.介绍引用 首先说引用是什么,大家可以记住,引用就是一个别名,比如小王有个外号叫小狗,他的妈妈喊小狗回家吃饭,那就是在喊小王回家吃饭. 接下来我们用两行代码来声明一个引用(就拿小王和小狗来说吧): int xiaoW; int &xiaoG=xiaoW; 上面就是一个引用,说明几点要注意的地方: 1.&不是取地址符,而是引用运算符: 2.xiaoG是xiaoW的别名,所以这两个变量的值和地址都是一样的: 3.引用只能初始化,而不能先声明再赋值,因为引用就相当于一个常量: 4.在声明

【密码学】一万字带您走进密码学的世界(上)

引文 密码学是研究编制密码和破译密码的技术科学.研究密码变化的客观规律,应用于编制密码以保守通信秘密的,称为编码学:应用于破译密码以获取通信情报的,称为破译学,总称密码学. 为了使读者对密码学有一个整体的认识,本文简述了常见的密码学的概念,其中本文包括对称密码,哈希函数.<一万字带您走进密码学的世界(下)>包括非对称密码,数字签名,数字认证等,需要指出的是文中并没有深入探讨加密算法原理,关于此部分内容,后续的文章会详细阐述.本文的主要内容如下图所示: 对称密码 在对称密码体系中,相同的密码用来

走进缓存的世界(三) - Memcache

系列文章 走进缓存的世界(一) - 开篇 走进缓存的世界(二) - 缓存设计 走进缓存的世界(三) - Memcache 简介 Memcache是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它基于一个存储key/value对的hashmap,通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态.数据库驱动网站的速度. 它的工作机制是在内存中开辟一块空间,然后建立一个HashTable并自己管理,使用非阻塞的网络IO. 更多详细的信息参阅Memcache官方网

带你走进rsync的世界

导读 Rsync(remote synchronize)是一个远程数据同步工具,可通过LAN/WAN快速同步多台主机间的文件,也可以使用 Rsync 同步本地硬盘中的不同目录.rsync共有3种使用方法,在配置rsync也是有6个步骤的.下面我们就从rsync的介绍,rsync的使用和rsync的配置带你走进rsync的世界 一.rsync简介 Rsync(remote synchronize)是一个远程数据同步工具,可通过LAN/WAN快速同步多台主机间的文件,也可以使用 Rsync 同步本地