实例化:


/*     * String  $host:MySQL ip;  

 * String  $port:handlersocket插件的监听端口,它有两个端口可选:一个用于读、一个用于写   

 */ 



$hs = new HandlerSocket($host, $port);

运用例子:

#9998为读取端口 详见上一篇handlersocket的安装

my $args = { host => 'localhost', port => 9998 };  
my $hs = new Net::HandlerSocket($args);





打开一个数据表:


*  

 * Int       $index:这个数字相当于文件操作里的句柄,HandlerSocket的所有其他方法都会依据这个数字来操作由这个 openIndex打开的表,  

 * String  $dbname:库名  

 * String  $table:表名  

 * String  $key:表的“主键”(HandlerSocket::PRIMARY)或“索引名”作为搜索关键字段,这就是说表必须有主键或索引  

 *                 个人理解:要被当做where条件的key字段,这样可以认为handlersocket只有一个where条件  

 * String  $column:'column1,column2' 所打开表的字段(以逗号隔开),就是说$table表的其他字段不会被操作  

 */  



$hs->openIndex($index, $dbname, $table, $key, $column);

运用例子:

my $res = $hs->open_index(0, 'test', 'user', 'PRIMARY', 'user_name,user_email,created');  
  die $hs->get_error() if $res != 0;  


 #打开test数据的user表 以主键为key
 #这个为查询的列数,这里为三列,分别为:user_name,user_email,created


其中'test'为schema名,'user'为表名,'PRIMARY'为索引名必须要有 为'PRIMARY'或者某个字段名,'user_name,user_email,created'为查询的列名。关于方法的open_index的第一个参数0,用来在每个Net::HandlerSocket对象中唯一标识一个表名。





查询:



/*  



 * Int     $index: openIndex()所用的$index 



 * String  $operation:openIndex方法中指定的$key字段所用的操作符,目前支持'=', '>=', '<=', '>',and '<';可以理解为where条件  



 * Array   $value  



 * Int       $number(默认是1):获取结果的最大条数;相当于SQL中limit的第二个参数  



 * Int     $skip(默认是0):跳过去几条;相当于SQL中limit的第一个参数  



 */  


$retval = $hs->executeSingle($index, $operation, $value, $number, $skip);

运用例子:

my $args = { host => 'localhost', port => 9998 };  
my $hs = new Net::HandlerSocket($args);  
    
my $res = $hs->open_index(0, 'test', 'user', 'PRIMARY', 'user_name,user_email,created'); 
die $hs->get_error() if $res != 0;   

$res = $hs->execute_single(0, '>=', [ 1 ], 2, 0);   # 此查询语句的意思是:查询主键大于或等于1,数据取2行

die $hs->get_error() if $res->[0] != 0;  
shift(@$res); 

# 这里我们要注意:execute_single方法的返回值类型为arrayref,其第一个元素为error code:如果为0,则为正常,否则不正常,数组从第

二元素开始即为返回的值,存储格式为 后面一行紧跟前面一行!
 

#下面为分行打印这个数组的所有值
for (my $row = 0; $row <2 ; ++$row) {  
    my $user_name= $res->[$row + 0];  
    my $user_email= $res->[$row+ 1];  
    my $created= $res->[$row + 2];  
if ($user_name || $user_email || $created)
{
    print "$user_name\t$user_email\t$created\n";  
}
else
{ last; 
}

}  
 
  $hs->close();








插入(注意:此处的openIndex要用$port_wr,即读写端口):



/*  



 * Int     $index: openIndex()所用的$index 



 * Array   $arr:数字元素数与openIndex的$column相同  



 */  



$retval = $hs->execute_single(3,'+', [5, 'zhongguo', 'zhogonguo@email.com','2011-01-08 13:51:33' ],1,0);

运用例子:

my $args = { host => 'localhost', port => 9999 };  
my $hs = new Net::HandlerSocket($args); 


my $res = $hs->open_index(3, 'test', 'user', 'PRIMARY', 'user_id,user_name,user_email,created');  
die $hs->get_error() if $res != 0;

$res = $hs->execute_single(3,'+', [5, 'zhongguo', 'zhogonguo@email.com','2011-01-08 13:51:33' ],1,0);  
die $hs->get_error() if $res->[0] != 0;  
 $hs->close();



删除(注意:此处的openIndex要用$port_wr,即读写端口):


/*  


 * Int     $index: openIndex()所用的$index 


 * String  $operation:openIndex方法中指定的$key字段所用的操作符,目前支持'=', '>=', '<=', '>',and '<';可以理解为where条件  


 * Array   $value  


 * Int     $number(默认是1):获取结果的最大条数;相当于SQL中limit的第二个参数  


 * Int     $skip(默认是0):跳过去几条;相当于SQL中limit的第一个参数  


 */  


$retval = $hs->executeDelete($index, $operation, $value, $number, $skip);

运用例子:


my $args = { host => 'localhost', port => 9999 };  
my $hs = new Net::HandlerSocket($args);  
my $res = $hs->open_index(3, 'test', 'user', 'PRIMARY', 'user_name');  
die $hs->get_error() if $res != 0; 
$res = $hs->execute_single(3,'=', [4],1,0,'D'); #DELETE user_id=4 的数据
print $res;
die $hs->get_error() if $res != 0;
$hs->close();



更新(注意:此处的openIndex要用$port_wr,即读写端口):


/*  


 * Int     $index: openIndex()所用的$index 


 * String  $operation:openIndex方法中指定的$key字段所用的操作符,目前支持'=', '>=', '<=', '>',and '<';可以理解为where条件  


 * Array   $value  


 * Int       $number(默认是1):获取结果的最大条数;相当于SQL中limit的第二个参数  


 * Int     $skip(默认是0):跳过去几条;相当于SQL中limit的第一个参数  


 */  



$retval = $hs->executeUpdate($index, $operation, $value, $number, $skip);


运用例子:


my $args = { host => 'localhost', port => 9999 };  
my $hs = new Net::HandlerSocket($args);  

my $res = $hs->open_index(3, 'test', 'user', 'PRIMARY', 'user_name');  
die $hs->get_error() if $res != 0;

$res = $hs->execute_single(3,'=', [5],1,0,'U',['woaini']);  #当user_id=5,更新'user_name'为woaini
die $hs->get_error() if $res->[0] != 0;
$hs->close();



可以用Multiple operations


可在一次调用中执行多个操作,这样速度更快


my $rarr = $hs->execute_multi([  
  [ 0, '>=', [ 'foo' ], 5, 0 ],  
  [ 2, '=', [ 'bar' ], 1, 0 ],  
  [ 4, '<', [ 'baz' ], 10, 5 ],  
]);  
for my $res (@$rarr) {  
  die $hs->get_error() if $res->[0] != 0;  
  shift(@$res);  
  # ...  
}





execute_single方法的第一个参数需要跟之前open_index方法的第一个参数一致。第二个参数'='指定了检索条件,目前支持'=', '>=', '<=', '>'和'<'。第三个参数[ 'foo' ]为一个arrayref,指定了检索的key,其长度必须小于或者等于对应索引的列数。第四个和第五个参数指定了查询的limit和offset跳过位移。

 

    execute_single方法的返回值类型为arrayref,其第一个元素为error code:

  • 0:正常。
  • 负数:I/O 错误,对应的Net::HandlerSocket对象需要被丢弃。
  • 正数:其它错误,但是与HandlerSocket Plugin的连接仍然正常可用,因此对应的Net::HandlerSocket对象可以继续使用。




参考资料:




http://whitesock.iteye.com/blog/811339




PS:

handlerscoket中有两个 重要的特性;

Write operations do not invalidate the query cache – Exactly what it sounds like, if you performed a write operation via HandlerSocket, you could potentially read stale data from the MySQL interface.

l 写操作并没有淘汰查询缓存 - 如果执行了写操作通过HandlerSocket,由于没有失效查询缓存, 那么你可能从MySQL读到旧的数据。  

No support for auto increment – Exactly as it sounds, you couldn’t have auto-incrementing columns get an auto increment value on insert.

l 不支持自动递增 - 插入时无法从自增列上自动获得增量值  




今天 我在测试把同一批数据插入一张数据表两次时  发现 插入第一次之后 不能插入第二次了  找了很久原因 看到第二个特性之后才想起  我们每次 openindex的时候都是要用到主键的  如果 这里 你要插入的数据的主键 已经存在数据库中了  就会报 121的错误。