1,介绍什么是Kundera 和JPA
1,kundera是一个兼容jpa接口的对象映射器。当前kundera支持的数据库有:
Cassandra,MongoDB,HBase,Redis,OracleNoSQL,Neo4j,CouchDB,Dudu,Relational databases,Apache Spark
2, JPA是Java Persistence API的简称,也叫java持久层api,是jdk5.0注释或者xml描述对象关系·表的映射关系,并将运行期的实体对象持久化到数据库中。
2,为什么使用kundera操作hbase api
hbase虽然提供丰富的api,但使用起来很少不方便,过多的创建hbase封装对象,导致使用者使用起来很是不方便,但有了kundera我们就会感到什么是幸福,他的语法有点像hibernate的hql语句,完全面向对象的操作
3,kundera的特性
1,一个健壮的查询系统
2,简单的对象/关系映射
3,支持二级缓存和基于事件的数据处理
4,优化数据存储
5,持久化连接池和基于Lucene的索引
4,环境搭建
eclipse + maven + jdk1.8+hadoop2.7.4+hbase1.2.6
1,创建maven项目
2,在maven的pom文件中添加依赖
1,简单配置,他会自动下载他所依赖的jar包,包括hbase和hadoop的,但版本一般不会和你下载的,但不会影响你操作,但如果你想麻烦点配置自己的依赖版本看下面配置
<dependencies>
<dependency>
<groupId>com.impetus.kundera.client</groupId>
<artifactId>kundera-hbase</artifactId>
<version>3.9</version>
</dependency>
</dependencies>
2,配置自己的依赖版本(大家可根据自己版本相对的改一下)
<dependencies>
<dependency>
<groupId>com.impetus.kundera.client</groupId>
<artifactId>kundera-hbase</artifactId>
<version>3.9</version>
<exclusions>
<exclusion>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-client</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-server</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-common</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-client</artifactId>
<version>1.2.6</version>
</dependency>
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-server</artifactId>
<version>1.2.6</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.7.4</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.10</version>
</dependency>
</dependencies>
3,接下来就是关键一步把maven项目改成jpa项目
1,右键点击项目找到configure选项
2,他会列出很多选项点击 convert to jpa perject
3,直接点击finish就行了
4,创建后他会在src目录下创建一个META-INF目录生成一个persistence.xml文件
配置一下内容
<!--指定供应商地址,固定的使用kundera -->
<provider>com.impetus.kundera.KunderaPersistence</provider>
<!-- 指定映射的类的全路径 -->
<class>com.zxz.entity.Person</class>
<properties>
<!-- 配置zookeeper节点服务器ip -->
<property name="kundera.nodes" value="192.168.14.125"/>
<!-- 配置zookeeper rpc连接端口 -->
<property name="kundera.port" value="2181"/>
<!-- 配置hbase名字空间和表内容 -->
<property name="kundera.keyspace" value="zxz:testZ"/>
<!-- 配置hbase方言 -->
<property name="kundera.dialect" value="hbase"/>
<!-- 配置hbase依赖类 -->
<property name="kundera.client.lookup.class" value="com.impetus.client.hbase.HBaseClientFactory"/>
</properties>
5,编写实体类也就是上面的配置映射的类
我这里创建一个person类,里面简单的写入几个属性加上相应的注解,他是和hbase的表一一对应的
package com.zxz.entity;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
//jpa规范
//使用entity注解表示他是hbase映射的类
@Entity
//指定hbase表中的列族
@Table(name="zxz")
public class Person {
//指定rowkey
@Id
private int id;
//指定列
@Column
private String name;
@Column
private int age;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String toString() {
return "Person [age=" + age + ", id=" + id + ", name=" + name + "]";
}
}
6,实战编程
前面的配置都是为这里打基础,虽然看上去有点多,但是这都是一次编程多次使用,不像hbase api每次操作都有创建一堆他封装的类。
首先在代码前介绍1个类和两个接口,他们就是来衔接hbase表和实体类进行底层实现的
1,Persistence(持久)类
引导类,用于在Java SE环境中获取EntityManagerFactory接口。
2,EntityManagerFactory(实体管理工厂)接口
用于与持久单元的实体管理器工厂交互的接口。
3,ManagerFactory(实体管理)接口
用于与持久上下文交互的接口EntityManager实例与持久化上下文关联。持久性上下文是一组实体类实例,其
中对于任何持久实体标识,都有一个惟一的实体类实例。在持久化上下文中,管理实体实例及其生命周期。
EntityManager API用于创建和删除持久实体实例,通过其主键查找实体,并查询实体。前面两个都是为这
接口铺垫的。
以上都是从源码摘下来的
我们创建一个类来操作就不多说了,不多说,咱们上代码,以下都是些简单操作,都是可以批量处理的
package com.zxz.app;
import java.util.List;
import java.util.Map;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import javax.persistence.Query;
import org.apache.hadoop.hbase.filter.BinaryComparator;
import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
import org.apache.hadoop.hbase.filter.ValueFilter;
import org.apache.hadoop.hbase.util.Bytes;
import org.junit.Test;
import com.impetus.client.hbase.HBaseClient;
import com.impetus.kundera.client.Client;
import com.zxz.entity.Person;
public class hbaseJpa {
//CRUD(增C删D改U查R)
//1,C 增加
@Test
public void insert() {
// 创建出实体管理对象进行对对象的操作来实现前两行是固定写法
// persistence类调用抽象方法createEntityManagerFactory("参数为当前项目名")方法来获取EntityManagerFactory接口
EntityManagerFactory emf = Persistence.createEntityManagerFactory("mykundera");
// 大家可能会有疑惑说接口能调用方法呢,有空的同学可以看一下他其实返回的是EntityManagerFactoryImpl这个实现类,
// 只不过利用了多态的方式返回了实现类的接口,其实和List<> list=new ArrayList<>();差不多
// EntityManger接口其实和EntityManagerFactory一样的实现方式都是利用多态方式调用createEntityManager()方法获取来的
EntityManager em = emf.createEntityManager();
// 创建person实体类对象,下面的操作打家都很熟悉了,给属性赋值,反过来想就是设置rowkey,列,值
Person p = new Person();
p.setId(2);
p.setName("cat");
p.setAge(20);
// persist方法就是传入一个对象,他会判断是否存在,如果存在抛异常,否则创建对象实例,也就是把值添加到hbase相应的表中
em.persist(p);
// 关闭实体管理接口
em.close();
}
//2,D 删除
@Test
public void delete() {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("mykundera");
EntityManager em = emf.createEntityManager();
Person p = new Person();
// 如果不指定属性值,他会把这个整个实体上指定的列族数据全删掉
// em.remove(p);
p.setId(2);
p.setAge(19);
p.setName("cat");
em.close();
}
//3,U 修改
@Test
public void update() {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("mykundera");
EntityManager em = emf.createEntityManager();
Person p = new Person();
p.setId(2);
p.setAge(50);
// 必须指定rowkey和列,调用merge("实体类.class")
em.merge(Person.class);
em.close();
}
//4,R 查
@Test
public void select() {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("mykundera");
EntityManager em = emf.createEntityManager();
// 调用find(实体类.class,rowkey)方法返回实体类对象,直接打印对象就行了,因为我重写过toString了
Person p = em.find(Person.class, 1);
System.out.println(p);
em.close();
}
//使用querysql方式高级查询,面向对象的sql语言
@Test
public void selectSql() {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("mykundera");
EntityManager cm = emf.createEntityManager();
// 调用createQuery("面向对象的sql表名是对象名,列是属性")
Query query = cm.createQuery("select p from Person p where p.id=2");
List<Person> re = query.getResultList();
for (Person person : re) {
System.out.println(person);
}
}
//使用过滤器实现querysql
@Test
public void filterselectSql() {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("mykundera");
EntityManager cm = emf.createEntityManager();
// 使用filter过滤器步骤
// 1。创建EntityManager实例并使用getDelegate方法来获取客户机的映射
Map<String, Client> clli = (Map<String, Client>) cm.getDelegate();
// 2。从hbase持久化单元的客户机映射中获取客户机。
HBaseClient hc = (HBaseClient) clli.get("mykundera");
// 3。最后,想要使用的任何过滤器创建一个过滤器对象,并将其设置为HbaseClient对象:
// 值过滤,使用小于比较符,使用的字节比较器过滤小于2下的数据,之前博客有专门讲过过滤器使用
ValueFilter vf = new ValueFilter(CompareOp.LESS, new BinaryComparator(Bytes.toBytes("10")));
hc.setFilter(vf);
Query query = cm.createQuery("select p from Person p ");
List<Person> re = query.getResultList();
for (Person person : re) {
System.out.println(person);
}
}
}
如果想了解过滤器操作api可以看 : https://blog.csdn.net/weixin_41122339/article/details/82054595