JRuby是纯java实现的ruby语言。JRuby使用ruby语法开发。不仅可以使用ruby类库,同时也可以使用java基础类库和第三方jar包。
hbase的交互式命令行是通过jruby实现的,当我们输入hbase shell时,实际上最终执行的是org.jruby.Main,并以bin/hirb.rb作为参数,注意是根目录下bin目录中的hirb.rb,而不是hbase-shell中的irb/hirb.rb; 这个类来自jruby的包,作用是把ruby编写的代码转换成java字节码,进而能够运行在JVM中;
JRuby中调用Java在接触JRuby前我使用过RJB(Ruby Java Bridge,http://rjb.rubyforge.org/),两者都提供在Ruby中调用Java的功能,仅在这点上来说,感觉它们差不多,其实JRuby的功能要强大的多。如果你只是想在Ruby中简单地调用一些Java代码,那可以考虑RJB。 要在JRuby中使用Java,先要声明程序中需要Java集成,有两种方法,一种用require 'java';另一种直接使用java::java.util.ArrayList这样的语法。无论是何种方法,都要保证所用的Java类在CLASSPATH中。
require 'java' java::java.util.ArrayList
Java类的使用也有几种选择:
include_class已经标记为过时,使用最新的java_import
java_import "java.util.HashMap" x = HashMap.new x.put("foo","bar")
调用System.out.println:
java.lang.System.out.println("Hello, world")
值得一提的是这里的”Hello, world”是Ruby的字符串,而非java.lang.String,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 java.lang.String # 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(java.lang.Short::valueOf(10).to_java:short) put 'tb2','r2','f2',Bytes::toBytes(java.lang.Short::valueOf(10).to_java:int) put 'tb2','r3','f2',Bytes::toBytes(java.lang.Short::valueOf(10).to_java:long) put 'tb2','r4','f2',Bytes::toBytes(java.lang.Short::valueOf(10).to_java:string) put 'tb2','r3','f2',Bytes::toBytes(java.lang.Short::valueOf(10).to_java:Short) #put 'tb2','r3','f2',Bytes::toBytes(java.lang.Short::valueOf(10).to_java:Short)
检查插入的数据
hbase(main):001:0> scan 'tb2' ROW COLUMN+CELL r1 column=f2:, timestamp=1642477231999, value=x00x0A r2 column=f2:, timestamp=1642477232021, value=x00x00x00x0A r3 column=f2:, timestamp=1642477232042, value=x00x00x00x00x00x00x00x0A 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 java.lang.Comparable def compareTo o this <=> o end end
如果要实现多个接口,import就可以了,对于未实现的方法,JRuby会把它交给method_missing。有一点要注意,compareTo在这里不能写成compare_to。 至于继承Java类就更容易了,几乎和继承Ruby类没什么区别:
class MyStringBuffer < java.lang.StringBuffer def append(v) end end
StringBuffer类的append方法有多个overload的版本,接收多个不同类型的参数,它们都会被统一到这个唯一的方法上,理由嘛很好理解,不是吗? 除此之外,JRuby还为Java的集合类提供了很多扩展,让你能用Ruby的方式来 *** 作Java集合。比方说,java.util.Map多了each方法、 []方法和[]=方法;java.lang.Comparable拥有了<=>方法;所有继承自java.util.Collection的类有了each、<<、+、-和length方法;java.util.List有了[]和[]=方法,还实现了sort和sort!方法。
Hbase shell扩展写法import org.apache.hadoop.hbase.client.Connection import org.apache.hadoop.hbase.client.ConnectionFactory import org.apache.hadoop.hbase.client.Table; conf = @shell.hbase.configuration con = ConnectionFactory.createConnection(conf) tb2 = TableName::valueOf("tb2") table = con.getTable(tb2) #short 类型的主键 row = Bytes::toBytes(java.lang.Short::valueOf(10).to_java:short) p = org.apache.hadoop.hbase.client.Put.new(row) p.addColumn(Bytes::toBytes("f2"), Bytes::toBytes("v1"), Bytes::toBytes("v1")) p.addColumn(Bytes::toBytes("f2"), Bytes::toBytes("v2"), Bytes::toBytes("v2")) table.put(p) con.close #查看类的所有方法 java.lang.String.methodsShell 展示类型
默认情况下,通过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 self.list(conf=nil,uri= nil) fs = org.apache.hadoop.fs.FileSystem::get(uri,conf) path = org.apache.hadoop.fs.Path.new("/tmp") fs.listStatus(path).each do |i| puts i.to_s end end end conf = @shell.hbase.configuration uri =java.net.URI.new("hdfs://example:8020/") HDFS.list(conf.uri)
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)