Google protocol buffer can serialize objects, while redis is an excellent nosql database. Here I will introduce how to serialize C ++ objects and store them in the redis database!
For how to install and use Google protocol buffer, read the previous article.
For details about how to install and use redis, I will not describe it here. I use the official redis C client: hiredis.
Protobuf object model:
Package CN. vicky. model. seri; message user {required int32 id = 1; // primary key, unique required string username = 2; // account required string Password = 3; // password optional string email = 4; // mailbox (optional) repeated person = 5; // role owned by the account (repeated)} message person {required int32 id = 1; // primary key, unique required string name = 2; // role name repeated phonenumber phone = 3; // phone number (repeated)} // Enum phonetype {mobile = 0; home = 1; Work = 2;} message phonenumber {required string number = 1; optional phonetype type = 2 [default = Home];}
Create a project:
For more information about generating the corresponding model. Pb. H model. Pb. CC, see my previous article.
Introduce hiredis. h and dependent libraries into the project. Here, the static link library form/usr/lib/libhiredis.
Write main, CPP
/** File: Main. CPP * Author: Vicky. H * mail: eclipser@163.com */# include <iostream> # include <fstream> # include "model. pb. H "# include" hiredis. H "/***/INT main (void) {// create the user object CN: Vicky: Model: Seri: User U; U. set_id (1); U. set_username ("Jack"); U. set_password ("123456"); U. set_email ("289997171@qq.com"); // create a role in the user CN: Vicky: Model: Seri: person * _ person1 = u. add_person (); _ person1-> set_id (1 ); _ Person1-> set_name ("p1"); // create a phone number in the role: 1 CN: Vicky: Model: Seri :: phonenumber * _ phone1 = _ person1-> add_phone (); _ phone1-> set_number ("+ 8613618074943"); _ phone1-> set_type (CN: Vicky: Model :: seri: Mobile); // create a phone number in the role: 2 CN: Vicky: Model: Seri :: phonenumber * _ phone2 = _ person1-> add_phone (); _ phone2-> set_number ("02882334717"); _ phone2-> set_type (CN: Vicky: Model :: seri: work); // create a role in the user CN :: Vicky: Model: Seri: person * _ person2 = u. add_person (); _ person2-> set_id (2); _ person2-> set_name ("p2"); // create a phone number in the role: 1 CN: Vicky :: model: Seri: phonenumber * _ phone3 = _ person2-> add_phone (); _ phone3-> set_number ("+ 8613996398667"); _ phone3-> set_type (CN :: vicky: Model: Seri: Mobile); // create a phone number in the role: 2 CN: Vicky: Model: Seri :: phonenumber * _ phone4 = _ person2-> add_phone (); _ phone4-> set_number ("02882334717 "); _ Phone4-> set_type (CN: Vicky: Model: Seri: work); // Save the object in binary format. Const int bytesize = u. bytesize (); STD: cout <"bytesize =" <bytesize <STD: Endl; char Buf [bytesize]; bzero (BUF, bytesize); U. serializetoarray (BUF, bytesize); // create the redis link rediscontext * C; redisreply * reply; struct timeval timeout = {1, 500000 }; // 1.5 seconds c = redisconnectwithtimeout (char *) "127.0.0.1", 3307, timeout); If (C-> ERR) {printf ("connection error: % s \ n", C-> errstr); exit (1) ;}// the first execution: write the object to the redis database // reply = (redisreply *) rediscommand (C, "set % B", U. username (). c_str (), (INT) U. username (). length (), Buf, bytesize); // key !!! // Printf ("set (Binary API): % s \ n", reply-> Str); // freereplyobject (reply); // The second execution: read object data from redis database reply = (redisreply *) rediscommand (C, "Get Jack"); STD :: cout <"reply-> Len =" <reply-> Len <"\ nreply-> STR: \ n" <reply-> STR <STD :: endl; // STD: cout <"-----------------------------" <STD: Endl; CN: Vicky: Model: Seri: User U2; u2.parsefromarray (reply-> STR, reply-> Len); STD: cout <u2.id () <STD: Endl; STD: cout <u2.username () <STD: Endl; STD: cout <u2.password () <STD: Endl; STD: cout <u2.email () <STD: Endl; STD: cout <"-------------------------" <STD: Endl; For (INT I = 0; I <u2.person _ SIZE (); I ++) {CN :: vicky: Model: Seri: person * P = u2.mutable _ person (I); STD: cout <p-> ID () <STD: Endl; STD: cout <p-> name () <STD: Endl; For (Int J = 0; j <p-> phone_size (); j ++) {CN: Vicky: Model: Seri: phonenumber * phone = p-> mutable_phone (j); STD: cout <phone-> Number () <STD: Endl;} STD: cout <"-------------------------" <STD: Endl;} return 0 ;}
First:
[Root @ localhost ~] # Redis-cli-P 3307
Redis 127.0.0.1: 3307> Del Jack
(Integer) 1
Redis 127.0.0.1: 3307>
Run the first comment to write the object to redis:
Bytes size = 124
Set (Binary API): OK
0
The user U object has been successfully written to redis. You can view it through redis:
Redis 127.0.0.1: 3307> get Jack
"\ B \ x01 \ X12 \ x04jack \ x1a \ x06123456 \" \ x10289997171@qq.com * + \ B \ x01 \ X12 \ x02p1 \ x1a \ X12 \ n \ x0e + 8613618074943 \ x10 \ x00 \ x1a \ x0f \ n \ x0b02882338517 \ x10 \ x02 * + \ B \ x02 \ X12 \ x02p2 \ x1a \ X12 \ n \ x0e + 8613996398667 \ x10 \ x00 \ x1a \ x0f \ n \ x0b02882338517 \ x10 \ x02"
Run the second annotation, read Jack data from redis, and deserialize it to generate user U2;
Result:
Bytes size = 124
Reply-> Len = 124
Reply-> STR:
Jack123456 "289997171@qq.com * P1 directly print binary data is incorrect !!!
+ 8613618074943
---------------------------
1
Jack
123456
289997171@qq.com
---------------------------
1
P1
+ 8613618074943
02882334717
---------------------------
2
P2
+ 8613996398667
02882334717
---------------------------
Great... so, the combination of protobuf and redis is successful!
I personally think that this kind of object-oriented, cross-language, is very high performance on the basis of storing and reading redis memory databases!