1. 程式人生 > >Realm在iOS中的簡單使用

Realm在iOS中的簡單使用

一、Realm簡單介紹

1、Realm簡介

  • Realm是由美國YCombinator孵化的創業團隊歷時幾年打造,第一個專門針對移動平臺設計的資料庫
  • Realm是一個跨平臺的移動資料庫引擎,目前支援iOSAndroid平臺,同時支援Objective-CSwiftJavaReact NativeXamarin等多種程式語言
  • Realm並不是對SQLite或者CoreData的簡單封裝, 是由核心資料引擎C++打造,是擁有獨立的資料庫儲存引擎,可以方便、高效的完成資料庫的各種操作

2、Realm的優勢與亮點

  • 開源。Realm移動端資料庫相關程式碼已全部開源。數千開發者在GitHub
    上參與了相關工作。另外還有幾百個Realm資料庫相關的擴充套件。
  • 簡單易用:Core DataSQLite龐大的學習量和繁雜的程式碼足以嚇退絕大多數剛入門的開發者,而換用Realm,則可以極大地減少學習代價和學習時間,讓應用及早用上資料儲存功能
  • 跨平臺:現在絕大多數的應用開發並不僅僅只在iOS平臺上進行開發,還要兼顧到Android平臺的開發。為兩個平臺設計不同的資料庫是不明智的,而使用Realm資料庫,iOSAndroid無需考慮內部資料的架構,呼叫Realm提供的API就可以完成資料的交換
  • 執行緒安全。程式設計師無需對在不同執行緒中,對資料庫的讀取一致性做任何考慮,Realm會保證每次讀取都得到一致的資料

3、視覺化工具Realm Browser

為了配合Realm的使用,Realm還提供了一個輕量級的資料庫檢視工具Realm Browser,藉助這個工具,開發者可以檢視資料庫當中的內容,並執行簡單的插入和刪除操作。Realm Browser可以在App Store中下載安裝

Realm Browser

需要注意的是

如果需要除錯, 可以通過NSHomeDirectory()打印出Realm資料庫地址, 找到對應的Realm檔案, 然後用Realm Browser視覺化工具開啟即可

二、Realm的安裝

1、手動安裝

當使用手工方式安裝Realm時,可以按照如下步驟進行

  • Realm.framework
    ios/static/資料夾拖曳到您Xcode專案中的檔案導航器當中, 確保Copy items if needed選中然後單擊Finish
  • Xcode檔案導航器中選擇您的專案,然後選擇您的應用目標,進入到Build Phases選項卡中。在Link Binary with Libraries中單擊 + 號然後新增libc++.tbd以及libz.tbd

RealmResource

2、使用CocoaPods安裝

當使用CocoaPods方式安裝Realm時,以Objective-C為例

  • CocoaPods版本要求是1.1.0及以上版本
  • Podfile中,新增pod 'Realm',如有需要, 新增pod 'Realm/Headers'到測試專案中
  • 在終端執行pod install即可安裝
  • Swift中需要輸入pod 'RealmSwift'才可以安裝
  • 如果是混編專案,就需要安裝OC的Realm, 然後要把 Swift/RLMSupport.swift檔案一同編譯進去

`RLMSupport.swift`

RLMSupport.swift這個檔案為Objective-C版本的Realm集合型別中引入了Sequence一致性,並且重新暴露了一些不能夠從Swift中進行原生訪問的Objective-C方法,例如可變引數variadic arguments等, 更加詳細的說明見官方文件

3、Xcode外掛

  • Realm提供了一個Xcode外掛,來方便的建立RLMObject類,這需要我們首先安裝相關的外掛
  • 開啟Realm資料夾中的plugin/RealmPlugin.xcodeproj並進行編譯,重啟Xcode之後外掛即可生效
  • 當需要新建RLMObject類時,在新建類的選項中選擇Realm Model Object即可

Realm Model

三、Realm的類定義說明

Realm框架中,定義了二十個核心類、常量、列舉型別、協議等,常用的如:RLMRealm類、RLMObject類、RLMResults類等, 我們可以從Realm官方網站上檢視所有的定義以及使用說明

1、RLMRealm類

  • 一個RLMRealm類的物件可以認為是一個Realm的資料庫。Realm資料庫既可以儲存在硬碟上,同時也可以儲存在記憶體中
  • Realm是框架的核心所在,是我們構建資料庫的訪問點,就如同Core Data的管理物件上下文managed object context一樣
  • RLMRealm類中,常用的屬性或方法如下
// 獲取預設的Realm資料庫
+ (instancetype)defaultRealm;


//例項化一個RLMRealm類的物件
//根據配置引數獲得RLMRealm
+ (nullable instancetype)realmWithConfiguration:(RLMRealmConfiguration *)configuration error:(NSError **)error;

//根據指定持久化檔案路徑獲得RLMRealm
+ (instancetype)realmWithPath:(NSString *)path;


//對Realm資料庫進行讀寫操作
//在Realm上開始寫入事務, 每個Realm檔案一次只能開啟一個寫事務
- (void)beginWriteTransaction;

//在當前寫入事務中提交所有寫入操作,並結束事務
- (void)commitWriteTransaction;
//沒有足夠的磁碟空間來儲存寫入或由於意外的I / O錯誤,此方法可能會失敗, 並返回error資訊
- (BOOL)commitWriteTransaction:(NSError **)error;
// 在當前寫入事務中提交所有寫入操作,而不收到此寫入事件的特定通知
- (BOOL)commitWriteTransactionWithoutNotifying:(NSArray<RLMNotificationToken *> *)tokens error:(NSError **)error;

// 回滾在當前寫入事務期間進行的所有寫入並結束事務
- (void)cancelWriteTransaction;

//執行寫入事務內給定塊中包含的操作
- (void)transactionWithBlock:(__attribute__((noescape)) void(^)(void))block;
//執行寫入事務內給定塊中包含的操作, 如果發生錯誤,則返回時包含NSError描述問題的物件
- (BOOL)transactionWithBlock:(__attribute__((noescape)) void(^)(void))block error:(NSError **)error;


//新增或更新一個物件
- (void)addObject:(RLMObject *)object;
//將現有物件新增或更新到Realm中, 有則更新沒有則插入
- (void)addOrUpdateObject:(RLMObject *)object;
//新增或更新多個物件
- (void)addObjects:(id<NSFastEnumeration>)objects;
- (void)addOrUpdateObjects:(id<NSFastEnumeration>)objects;


//刪除物件
- (void)deleteObject:(RLMObject *)object;
- (void)deleteObjects:(id)array;
- (void)deleteAllObjects;

2、RLMObject類

  • Realm資料庫中儲存的都是RMObject物件,RLMObject類是所有可以儲存在Realm資料庫中的物件的根類
  • 凡是可以儲存在Realm資料庫中的物件都是RLMObject類或RLMObject類的子類
  • 要建立一個數據模型,我們只需要繼承RLMObject,然後設計我們想要儲存的屬性即可
  • RLMObject類中,我們可以新增屬性,新增的屬性型別可以支援如下型別:
    • NSString:字串
    • NSInteger, int, long, float, double:數字型,注意沒有CGFloat
    • BOOL/bool:布林型
    • NSDate:日期型
    • NSData:二進位制字元型
    • NSNumber<X>: 其中X必須RLMInt, RLMFloat, RLMDoubleRLMBool型別
    • RLMArray<X>: 其中X必須是RLMObject類的子類, 用於建模多對多關係
    • RLMObject的子類,用於建模多對一關係
  • RLMObject類中,比較常用如下方法:
//建立Realm物件, 傳入一個NSArray或NSDictionary例項來設定物件屬性的值
- (nonnull instancetype)initWithValue:(nonnull id)value;

//在Realm資料庫中,獲取該RLMObject類的所有物件
+ (RLMResults *)allObjects;

//根據查詢條件返回滿足條件的所有RLMObject類的物件
+ (RLMResults *)objectsWhere:(NSString *)predicateFormat, ...;

//使用預設Realm中的給定主鍵檢索此物件型別的單個例項
+ (nullable instancetype)objectForPrimaryKey:(nullable id)primaryKey;

//從指定的Realm返回此物件型別的所有物件
+ (nonnull RLMResults *)allObjectsInRealm:(nonnull RLMRealm *)realm;

//返回與指定Realm中給定謂詞匹配的此物件型別的所有物件
+ (nonnull RLMResults *)objectsInRealm:(nonnull RLMRealm *)realm where:(nonnull NSString *)predicateFormat, ...;

3、RLMResults類

  • 當我們執行一個查詢操作後,查詢出滿足條件的RLMObject物件會存放在一個RLMResults物件中
  • RLMResults類是一個數組型別的資料結構,因此在其類定義中,提供了很多與陣列類似的屬性和方法

相關屬性

//結果集合中的物件個數
@property (readonly, assign, nonatomic) NSUInteger count;

//結果集合中物件的型別
@property (readonly, assign, nonatomic) RLMPropertyType type;

//管理此結果集合的Realm物件
@property (readonly, nonatomic) RLMRealm *_Nonnull realm;

//結果集合中包含的物件的類名稱
@property (readonly, copy, nonatomic, nullable) NSString *objectClassName;

相關方法

//返回結果集合中的第一個物件
- (nullable RLMObjectType)firstObject;

//返回結果集合中的最後一個物件
- (nullable RLMObjectType)lastObject;

//根據索引index獲取其中的某個物件
- (RLMObjectType)objectAtIndex:(NSUInteger)index;

//根據物件返回其索引
- (NSUInteger)indexOfObject:(RLMObjectArgument)object;

//返回與謂詞匹配的結果集合中第一個物件的索引
- (NSUInteger)indexOfObjectWhere:(nonnull NSString *)predicateFormat, ...;

//返回與結果集合中給定謂詞匹配的所有物件
- (RLMResults<RLMObjectType> *)objectsWhere:(NSString *)predicateFormat, ...;

//返回RLMResults從現有結果集合中排序的內容
- (RLMResults<RLMObjectType> *)sortedResultsUsingKeyPath:(NSString *)keyPath ascending:(BOOL)ascending;

//返回RLMResults與現有結果集合不同的內容
- (nonnull RLMResults<RLMObjectType> *)distinctResultsUsingKeyPaths:(nonnull NSArray<NSString *> *)keyPaths;

更多相關類及其屬性和方法, 可參考官方文件

四、Realm的使用

Realm中一些常用的類及其類的屬性和方法上面已經介紹了, 下面我們就介紹Realm的使用方法

1、建立RLMObject類

我們首先建立一個Student類,該類是RLMObject類的一個子類, 下圖就是按照之前安裝的Xcode外掛建立的

image

  • Student新增兩個屬性, RLMObject官方建議在RLMObject類中新增的屬性,是不需要指定屬性關鍵字的,完全交由Realm處理
  • 假如設定了,這些attributes會一直生效直到RLMObject被寫入realm資料庫
  • RLM_ARRAY_TYPE巨集建立了一個協議,從而允許 RLMArray<Car>語法的使用
  • 如果RLM_ARRAY_TYPE巨集沒有放置在模型介面的底部的話,您或許需要提前宣告該模型類
@interface Student : RLMObject

@property int num;
@property NSString *name;

@end
RLM_ARRAY_TYPE(Student)

2、儲存操作

  • 對於RLMObject型別的物件,我們可以直接對建立的物件進行儲存
  • 第一步, 初始化物件
// 方式一: 接受一個數組物件
Student *stu1 = [[Student alloc]initWithValue:@[@1, @"jun"]];

//方式二: 接受一個字典物件
Student *stu2 = [[Student alloc]initWithValue:@{@"num": @2, @"name":@"titan"}];

//方式三: 屬性賦值
Student *stu3 = [[Student alloc]init];
stu3.num = 3;
stu3.name = @"titanjun";

第二步就是把RLMObject物件寫入Realm資料庫, 同樣有三種方式

//方式一: 提交事務處理
//獲取Realm物件
RLMRealm *realm = [RLMRealm defaultRealm];
//開始寫入事務
[realm beginWriteTransaction];
//新增模型物件
[realm addObject:stu1];
//提交寫入事務
[realm commitWriteTransaction];


//方式二: 在事務中呼叫addObject:方法
RLMRealm *realm = [RLMRealm defaultRealm];
[realm transactionWithBlock:^{
    [realm addObject:webSite1];
    [realm addObject:webSite2];
}];


//方式三: 在十五中建立新的物件並新增
[realm transactionWithBlock:^{
    //新增模型
    [Student createInRealm:realm withValue:@{@"num": @3, @"name":@"coder"}];
}];

一定要注意的是

  • 所有的必需屬性都必須在物件新增到Realm前被賦值
  • 如果在程序中存在多個寫入操作的話,那麼單個寫入操作將會阻塞其餘的寫入操作,並且還會鎖定該操作所在的當前執行緒
    • 建議常規的最佳做法:將寫入操作轉移到一個獨立的執行緒中執行
    • 官方給出的建議:由於Realm採用了MVCC設計架構,讀取操作並不會因為寫入事務正在進行而受到影響
    • 除非您需要立即使用多個執行緒來同時執行寫入操作,不然您應當採用批量化的寫入事務,而不是採用多次少量的寫入事務
    • 下面的程式碼就是把寫事務放到子執行緒中去處理
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    RLMRealm *realm = [RLMRealm defaultRealm];
    [realm transactionWithBlock:^{
        [realm addObject: stu4];
    }];
});

3、查詢操作

  • Realm中也提供了功能強大的資料查詢能力,如果會使用SQL語言的話,上手的難度更低
  • Realm的查詢功能中,也可以像SQL一樣使用各種條件查詢關鍵字,查詢的結果會儲存在一個RLMResults類的陣列中
  • 全量查詢, 通過呼叫allObjects方法, 得到該表中的所有資料
  • 條件查詢,設定一些查詢條件,從而查詢出符合條件的物件
    • Realm的查詢條件可以使用==、<=、<、>=、>、!=、BETWEEN、CONTAINS 以及 ENDSWITH等多種操作符

全量查詢

//1. 獲取所有資料
RLMResults *resArr = [Student allObjects];
NSLog(@"%@", resArr);

//2. 新增一條資料
RLMRealm *realm = [RLMRealm defaultRealm];
Student *stu = [[Student alloc]initWithValue:@[@10, @"coder"]];
[realm transactionWithBlock:^{
    [realm addObject:stu];
}];

//3. 一旦檢索執行之後, RLMResults 將隨時保持更新
NSLog(@"%@", resArr);

條件查詢

//條件查詢
RLMResults *stuArr = [Student objectsWhere:@"num > 7"];
NSLog(@"%@", stuArr);

//排序
//排序不會對原陣列進行操作, 會返回一個新的陣列
RLMResults *stuArr2 = [stuArr sortedResultsUsingKeyPath:@"name" ascending:YES];
NSLog(@"%@", stuArr2);


//鏈式查詢
RLMResults *stuArr3 = [stuArr2 objectsWhere:@"num > 8"];
//可以不斷的根據上一個查詢結果進行查詢
RLMResults *stuArr4 = [stuArr3 objectsWhere:@"num > 9"];
NSLog(@"%@", stuArr4);

4、更新操作

  • 需要修改的模型一定是被Realm所管理的模型, 而且已經和磁碟上的物件進行地址對映
  • 對新新增的模型進行更新
//獲取Realm物件
RLMRealm *realm = [RLMRealm defaultRealm];
Student *stu4 = [[Student alloc]initWithValue:@{@"num": @4, @"name":@"titan4"}];
//新增資料
// 這個模型stu, 已經被realm 所管理, 而且, 已經和磁碟上的物件, 進行的地址對映
[realm transactionWithBlock:^{
    //新增模型
    [realm addObject:stu4];
}];

// 這裡修改的模型, 一定是被realm所管理的模型
[realm transactionWithBlock:^{
    stu4.name = @"coder4";
}];
  • 根據查詢到的資料更新指定屬性的資料
//條件查詢
RLMResults *results = [Student objectsWhere:@"num = 4"];
Student *stu = results.firstObject;

//更新指定屬性的資料
[realm transactionWithBlock:^{
    stu.name = @"titanking";
}];
  • 當有主鍵的情況下, 使用Update方法
  • addOrUpdateObject會去先查詢有沒有傳入的Student相同的主鍵,如果有,就更新該條資料
  • 這裡需要注意,addOrUpdateObject這個方法不是增量更新,所有的值都必須有,如果有哪幾個值是null,那麼就會覆蓋原來已經有的值,這樣就會出現資料丟失的問題
  • createOrUpdateInRealm:withValue這個方法是增量更新的,後面傳一個字典,使用這個方法的前提是有主鍵
  • 方法會先去主鍵裡面找有沒有字典裡面傳入的主鍵的記錄,如果有,就只更新字典裡面的子集;如果沒有,就新建一條記錄
//獲取Realm物件
RLMRealm *realm = [RLMRealm defaultRealm];
Student *stu2 = [[Student alloc]initWithValue:@{@"num": @12, @"name":@"titan"}];

//addOrUpdateObject方式
[realm transactionWithBlock:^{
    [realm addOrUpdateObject:stu2];
}];

//createOrUpdateInRealm方式
[realm transactionWithBlock:^{
    [Student createOrUpdateInRealm:realm withValue:@{@"num": @11, @"name":@"titan11"}];
}];

5、刪除操作

  • 刪除的模型, 一定要求是被realm所管理的已經存在的模型
  • 當需要在Realm中刪除某些物件時,需要注意的是,該方法的執行需要在一個事務中進行
//獲取Realm物件
RLMRealm *realm = [RLMRealm defaultRealm];

//根據條件刪除一條資料 
RLMResults *results = [Student objectsWhere:@"name = 'titanking'"];
Student *titan1 = results.firstObject;

// 刪除單條記錄
[realm transactionWithBlock:^{
    [realm deleteObject:titan1];
}];



//刪除所有符合條件的資料
RLMResults *results = [Student objectsWhere:@"name = 'coder'"];
for (Student *stu in results) {
    [realm transactionWithBlock:^{
        [realm deleteObject:stu];
    }];
}



//刪除表中所有的資料
[realm transactionWithBlock:^{
    [realm deleteAllObjects];
}];



/*場景, 根據主鍵刪除一個模型*/
 // 1. 根據主鍵, 查詢到這個模型(這個模型, 就是被realm資料庫管理的模型)
Student *res = [Student objectInRealm:realm forPrimaryKey:@4];

//2. 刪除該模型
[realm transactionWithBlock:^{
    [realm deleteObject:res];
}];

6、Realm資料庫機制

  • 上面用到的獲取realm物件的方式都是通過defaultRealm來獲取預設配置的realm物件
  • 當我們需要建立不同的realm表格時又該如何操作呢?
  • 下面我們來看一下
- (void)setDefaultRealmForUser:(NSString *)username {
    //先獲取預設配置
    RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];

    //設定只讀資料庫
    //config.readOnly = YES;

    // 使用預設的目錄,但是使用使用者名稱來替換預設的檔名
    config.fileURL = [[[config.fileURL URLByDeletingLastPathComponent]
                       URLByAppendingPathComponent:username]
                      URLByAppendingPathExtension:@"realm"];
    // 將這個配置應用到預設的 Realm 資料庫當中
    [RLMRealmConfiguration setDefaultConfiguration:config];
}

做好上述配置之後, 便可建立不同的資料庫了

// 不同的使用者, 使用不同的資料庫
[self setDefaultRealmForUser:@"zhangsan"];

//這裡也只需要呼叫預設配置即可
RLMRealm *realm = [RLMRealm defaultRealm];

7、通知

  • Realm例項將會在每次寫入事務提交後,給其他執行緒上的Realm例項傳送通知
  • 一般控制器如果想一直持有這個通知,就需要申請一個屬性, 強引用該屬性,strong持有這個通知
  • 集合通知是非同步觸發的,首先它會在初始結果出現的時候觸發,隨後當某個寫入事務改變了集合中的所有或者某個物件的時候,通知都會再次觸發
//強引用屬性
@property (nonatomic, strong) RLMNotificationToken *token;


- (void)setUp {
    [super setUp];

    RLMRealm *realm = [RLMRealm defaultRealm];
    // 獲取 Realm 通知
    self.token = [realm addNotificationBlock:^(RLMNotification  _Nonnull notification, RLMRealm * _Nonnull realm) {
        NSLog(@"接收到變更通知--%@", notification);
    }];

    //結束該通知
    [self.token stop];
}


- (void)testExample {
    NoticeModel *noticeM = [[NoticeModel alloc] initWithValue:@{@"num": @1, @"name": @"sz"}];

    //新增資料, 資料操作之後便會通知上述通知中心執行相應操作
    RLMRealm *realm = [RLMRealm defaultRealm];
    [realm transactionWithBlock:^{
        [realm addObject:noticeM];
    }];
}

8、資料庫遷移

  • 資料庫儲存方面的增刪改查應該都沒有什麼大問題,比較蛋疼的應該就是資料遷移了
  • 在版本迭代過程中,很可能會發生表的新增,刪除,或者表結構的變化,如果新版本中不做資料遷移,使用者升級到新版,很可能就直接crash了
  • 資料遷移一直是困擾各型別資料庫的一大問題, 但是對於Realm來說, 卻方便很多, 這也是Realm的優點之一
    • 新增刪除表,Realm不需要做遷移
    • 新增刪除欄位,Realm不需要做遷移; Realm會自行檢測新增和需要移除的屬性,然後自動更新硬碟上的資料庫架構
//需要在以下方法中進行配置
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // 獲取預設配置, 遷移資料結構
    RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration];

    // 1. 設定新的架構版本。這個版本號必須高於之前所用的版本號(如果您之前從未設定過架構版本,那麼這個版本號設定為 0)
    int newVersion = 4;
    config.schemaVersion = newVersion;

    // 2. 設定閉包,這個閉包將會在開啟低於上面所設定版本號的 Realm 資料庫的時候被自動呼叫
    [config setMigrationBlock:^(RLMMigration *migration, uint64_t oldSchemaVersion){
        if (oldSchemaVersion < newVersion) {

            NSLog(@"資料結構會自動遷移");

            // enumerateObjects:block: 遍歷了儲存在 Realm 檔案中的每一個“Person”物件
            [migration enumerateObjects:@"DataMigration" block:^(RLMObject * _Nullable oldObject, RLMObject * _Nullable newObject) {
                // 只有當 Realm 資料庫的架構版本為 0 的時候,才新增 “fullName” 屬性
                if (oldSchemaVersion < 1) {
                    newObject[@"fullName"] = [NSString stringWithFormat:@"%@ %@", oldObject[@"firstName"], oldObject[@"lastName"]];
                }
                // 只有當 Realm 資料庫的架構版本為 0 或者 1 的時候,才新增“email”屬性
                if (oldSchemaVersion < 2) {
                    newObject[@"email"] = @"";
                }
                // 替換屬性名(原欄位重新命名)
                if (oldSchemaVersion < 3) { // 重新命名操作應該在呼叫 `enumerateObjects:` 之外完成
                    [migration renamePropertyForClass:Person.className oldName:@"yearsSinceBirth" newName:@"age"];
                }
            }];
        }
    }];

    // 3. 告訴 Realm 為預設的 Realm 資料庫使用這個新的配置物件
    [RLMRealmConfiguration setDefaultConfiguration:config];

    // 4. 現在我們已經告訴了 Realm 如何處理架構的變化,開啟檔案之後將會自動執行遷移
    [RLMRealm defaultRealm];


    return YES;
}

相關推薦

C#簡單的繼承和多態

補充 是個 main ase ide 初始化 子類 public 泛型 今天我們來聊一聊繼承,說實話今天也是我第一次接觸。 繼承的概念是什麽呢?就是一個類可以繼承另一個類的屬性和方法(成員) 繼承是面向對象編程中的一個非常重要的特性。 好了,廢話不多說,下面切入正題:

PHP簡單工廠模式”實例講解

超過 case 十個 ssa 技術 實例 not 強烈 .... 原創文章,轉載請註明出處:http://www.cnblogs.com/hongfei/archive/2012/07/07/2580776.html 簡單工廠模式: ①抽象基類:類中定義抽象一些方法,用

現實簡單配置路由器

協議 導致 路由器 工具 控制 運維人員 startup eset pad 今天我們實際操作了配制cisco路由器2811,具體的方法,下面我來告訴大家,給正在學網絡運維的大家分享一下:準備工具:cisco 路由器、console線、網線、電腦一臺將console線接上路由

CentOS6和CentOS7簡單web站點的配置步驟

簡單web站點搭建一、CentOS6中簡單的web站點的配置實例:1.安裝httpd:~]# yum install -y httpd httpd-manual httpd-tools //安裝httpd應用程序所需要的必要文檔文件2.確保SElinux和iptables防火墻不會幹擾httpd

Android簡單活動窗口的切換--Android

-a parent man .cn wrap reat tex created 窗口切換 本例實現Android中簡單Activity窗口切換:借助intent(意圖)對應用操作(這裏用按鈕監聽)等的描述,Android根據描述負責找對應的組件,完成組件的調用來實現活動的切

JAVA簡單的MD5加密類(MD5Utils)

com rgs api body md5 mex 可能 title 思路 MD5加密分析: JDK API: 獲取對象的API: 加密的API: 1 package cn.utils; 2 3 import java.security.M

Django簡單添加HTML、css、js等文件

htm djang .py 項目 移動 資源 默認 alt templates 首先申明下自己的環境, python版本3.65 Django版本1.11.15 創建默認Django項目後 首先說下添加Html 在urls.py文件中添加如圖代碼,照抄也

內網簡單部署samba服務

pass pat 系統登錄 table enforce 文件 可見 密碼 windows 環境準備:   關閉防火墻  暫時關閉:service iptables stop   禁止開機啟動:chkconfig iptables off   關閉seLinux  暫時關閉:

Vue js簡單的搜尋功能

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Document</title> <script src="https://

Android簡單實現DrawerLayout

<android.support.v4.widget.DrawerLayout xmlns:android=“http://schemas.android.com/apk/res/android” xmlns:app=“http://schemas.android.com/apk/re

pathon爬蟲簡單的請求頭fake_useragent庫,處理反爬問題

安裝 pip3 install fake_useragent 各瀏覽器User-Agent的值 from fake_useragent import UserAgent ua = UserAgent() # ie瀏覽器的user agent print(ua.ie) Mozill

Java簡單的註冊、登陸例項

1、功能: 實現使用者的註冊,並能根據註冊的資訊正常登陸。 2、分析:  a) 具體類   i. 使用者類    1. 使用者基本類    2. 使用者操作類   ii. 測試類  b) 每個具體類的內容   i. 使用者基本類    1. 成員變數:使用者名稱、密碼    2. 構造方法:

.net core 簡單封裝Dapper.Extensions 並使用sqlsuger自動生成實體類

引言 由公司需要使用dapper  同時支援多資料庫 又需要支援實體類 又需要支援sql 還需要支援事務 所以採用了 dapper + dapperExtensions  並配套 生成實體類小工具的方式     環境準備 dapper環境 nuget中

python簡單的遞迴

首先要先理解什麼是遞迴? 在函式內部,可以呼叫其他函式。如果一個函式在內部呼叫自身本身,這個函式就是遞迴函式。 下面講了一個很簡單的遞迴函式 def clac(n): print(n) if int(n/2) >0: return clac

#Linux和git簡單的小問題

linux中: 1. 進入資料夾的命令 cd 資料夾名 (當該資料夾名稱中帶有空格時,應該用雙引號將資料夾名稱括起來,不然系統會將其當成多個cd的引數而報錯,或按Tab鍵自動補全) 2.檢視本檔案下面的所有有檔案資訊 ls -al 即可 du常用的選項:   -h:以

C# TreeView 拖拽節點到另一個容器Panel簡單實現

C# TreeView 拖拽節點到另一個容器Panel中簡單實現 用了這麼久C#拖拽功能一直沒有用到也就沒用過,今天因為專案需要,領導特地給我簡單講解了下拖拽功能,真是的大師講解一點通啊。特地寫一篇部落格記錄下,分享給大家!也方便以後自己檢視。 1.拖拽功能分析 拖拽功能分析其實就三個字:選-->

ASP.NET Core 簡單Session登入校驗

ASP.NET Core 中簡單Session登入校驗:從Session的配置新增、到請求過濾、再到頁面操作。推薦相關閱讀:ASP.NET 會話狀態概述  ASP.NET Cookie 概述  ASP.NET 狀態管理建議 ASP.NET Core 中的會話和應用狀態 目

jni 簡單用法

java 呼叫c ,c回撥java #include <stdio.h> #include <android/log.h> #include <string.h> #include <stdlib.h> #inc

執行緒簡單的方法

start()和run() Start()方法:使執行緒開始執行,java虛擬機器中呼叫該執行緒的run()方法。 run()方法:如果該執行緒是使用獨立的Runnable()執行物件構造的,則執行Runnable物件的run方法;否則什麼都不執行,值得一提的是,一般我們

Android簡單的彈出選單

<resources> <array name="ItemArray"> <item>第一項</item> <item>第二項</item> <item>第