简介
JRuby是纯java实现的ruby语言。JRuby使用ruby语法开发。不仅可以使用ruby类库,同时也可以使用java基础类库和第三方jar包。
hbase的交互式命令行是通过jruby实现的,当我们输入hbase shell时,实际上最终执行的是,并以bin/作为参数,注意是根目录下bin目录中的,而不是hbase-shell中的irb/; 这个类来自jruby的包,作用是把ruby编写的代码转换成java字节码,进而能够运行在JVM中;
JRuby中调用Java
在接触JRuby前我使用过RJB(Ruby Java Bridge,/),两者都提供在Ruby中调用Java的功能,仅在这点上来说,感觉它们差不多,其实JRuby的功能要强大的多。如果你只是想在Ruby中简单地调用一些Java代码,那可以考虑RJB。 要在JRuby中使用Java,先要声明程序中需要Java集成,有两种方法,一种用require 'java';另一种直接使用java::这样的语法。无论是何种方法,都要保证所用的Java类在CLASSPATH中。
require 'java'
java::
Java类的使用也有几种选择:
include_class已经标记为过时,使用最新的java_import
java_import ""
x =
("foo","bar")
调用:
("Hello, world")
值得一提的是这里的”Hello, world”是Ruby的字符串,而非,JRuby会自动对一些类型进行转换,开发者无需自己动手。在Java中,方法和变量都用fooBar这样的形式,而Ruby中则是foo_bar,显然在代码中同时出现这两种形式会很不协调,JRuby很聪明地将Java中的fooBar转为了foo_bar,而常见的getter和setter,也简化为了成员属性的名称,foo是getFoo(),而foo=是setFoo()。用to_java()能将一个Ruby的数组转换为Java中的Object[],如果想要指定数组的类型可以这样:
[1,2,3].to_java :float # new float[] {1,2,3}
["str", "str2"].to_java # new String[]{"str","str2"}
常用的symbol有以下几种::boolean、:byte、:char、:double、:float、:int、:long、:short、:object、:string、:big_decimal(:decimal)和:big_integer(:big_int)。
hbase shell 写入原生的数据类型
create 'tb2','f2'
put 'tb2','r1','f2',Bytes::toBytes(::valueOf(10).to_java:short)
put 'tb2','r2','f2',Bytes::toBytes(::valueOf(10).to_java:int)
put 'tb2','r3','f2',Bytes::toBytes(::valueOf(10).to_java:long)
put 'tb2','r4','f2',Bytes::toBytes(::valueOf(10).to_java:string)
put 'tb2','r3','f2',Bytes::toBytes(::valueOf(10).to_java:Short)
#put 'tb2','r3','f2',Bytes::toBytes(::valueOf(10).to_java:Short)
检查插入的数据
hbase(main):001:0> scan 'tb2'
ROW COLUMN+CELL
r1 column=f2:, timestamp=1642477231999, value=\x00\x0A
r2 column=f2:, timestamp=1642477232021, value=\x00\x00\x00\x0A
r3 column=f2:, timestamp=1642477232042, value=\x00\x00\x00\x00\x00\x00\x00\x0A
r4 column=f2:, timestamp=1642477284377, value=10
5 row(s)
Took 0.3607 seconds
hbase(main):002:0>
Jruby扩展Java代码
对Java的扩展主要是用Ruby来实现接口和继承类。先来看下如何实现接口:
class Compare
import
def compareTo o
this <=> o
end
end
如果要实现多个接口,import就可以了,对于未实现的方法,JRuby会把它交给method_missing。有一点要注意,compareTo在这里不能写成compare_to。 至于继承Java类就更容易了,几乎和继承Ruby类没什么区别:
class MyStringBuffer <
def append(v)
end
end
StringBuffer类的append方法有多个overload的版本,接收多个不同类型的参数,它们都会被统一到这个唯一的方法上,理由嘛很好理解,不是吗? 除此之外,JRuby还为Java的集合类提供了很多扩展,让你能用Ruby的方式来操作Java集合。比方说,多了each方法、 []方法和[]=方法;拥有了<=>方法;所有继承自的类有了each、<<、+、-和length方法;有了[]和[]=方法,还实现了sort和sort!方法。
Hbase shell扩展写法
import
import
import ;
conf = @
con = (conf)
tb2 = TableName::valueOf("tb2")
table = (tb2)
#short 类型的主键
row = Bytes::toBytes(::valueOf(10).to_java:short)
p = (row)
(Bytes::toBytes("f2"), Bytes::toBytes("v1"), Bytes::toBytes("v1"))
(Bytes::toBytes("f2"), Bytes::toBytes("v2"), Bytes::toBytes("v2"))
(p)
#查看类的所有方法
Shell 展示类型
默认情况下,通过hbase shell的scan或get等命令获取的中文内容都是16进制的,无法直观的查看数据。
其实hbase shell中是有方法将16进制中文转换成utf-8格式的中文的。
主要有两种方式:
使用FORMATTER => 'toString' 使用:toString
hbase(main):002:0> scan 'tb2',{FORMATTER => 'toString'}
ROW COLUMN+CELL
d column=f2:v1, timestamp=1642408469271, value=v1
d column=f2:v2, timestamp=1642408469271, value=v2
读取HDFS文件信息
module HDFS
require 'java'
def (conf=nil,uri= nil)
fs = ::get(uri,conf)
path = ("/tmp")
(path).each do |i|
puts i.to_s
end
end
end
conf = @
uri =("hdfs://example:8020/")
()