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 perject3,直接点击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