博客 > SequoiaDB Java 开发入门

SequoiaDB Java 开发入门

 2017-09-28  SequoiaDB 技术教程

背景

近年来,随着社会的进步和信息通信技术的发展,信息系统、互联网应用在各行业、各领域快速拓展。这些系统采集、处理、积累的数据越来越多,数据量增速越来越快。数据量每年以爆炸性的速度增长。在互联网出现之前,数据主要是人机会话方式产生的,以结构化数据为主。所以大家都需要传统的RDBMS来管理这些数据和应用系统。那时候的数据增长缓慢、系统都比较孤立,用传统数据库基本可以满足各类应用开发。但随着大数据时代的到来,数据逐渐地转变为以非结构、半结构化为主,人们对于数据的使用,不在仅仅局限于业务应用的需求。对信息时代所产生的海量数据进行数据挖掘和分析,已经成为了很多企业获取有价值信息常用手段。传统数据库对这类需求和应用无论在技术上还是功能上都几乎束手无策。传统数据库(OldSQL)一统天下变成了OldSQL+NewSQL+NoSQL+其他新技术(流、实时、内存等)共同支撑多类应用的局面。


产品介绍

SequoiaDB巨杉数据库,专注新一代大数据基础架构研发,是国内领先的新一代分布式数据库厂商。其产品SequoiaDB巨杉数据库是一款支持SQL、高并发、实时性、分布式、可扩展、灵活存储的NewSQL数据库。另外SequoiaDB支持spark、hive、hadoop、kafka、postgreSQL等多种大数据工具的对接。在应用开发方面,SequoiaDB除了提供原生的API,还提供了c驱动、c++驱动、CSharp驱动、java驱动、PHP驱动、REST接口等。开发者可以方便快速地使用SequoiaDB进行应用开发,本文将介绍如何使用javaAPI进行应用开发。

图片 1.png

使用SequoiaDB进行应用开发优势

存储方式灵活

SequoiaDB数据库是一款文档型数据库,使用了JSON这种格式存储数据,可以有效地提高开发效率。总所周知,在开发大型应用时,会涉及到好多的表,表与表之间的关联关系会特别多,特别是在银行,互联网金融等行业中,由于业务复杂繁多,表与表的关系会极其复杂,使用传统数据库进行开发时,首先需要对表进行关联设计,而复杂表的设计需要投入大量的人力,这不但浪费了金钱,还拖慢了开发的进度。另外在后期维护升级中,经过多次的迭代更新后,表中的字段通常会有所变化,如果需要对某些字段的值进行修改或者删除,很难确定改动后的结果会不会对其他业务系统有所影响,这就要求开发的人很懂业务,提高了开发的门槛。如果使用文档型数据库,由于采用的是JSON结构存储数据。用户可以采用对象的方式,把业务系统设计的字段存储在一个表中,在涉及表关联时,可以在BSON中采用嵌套的方式,把数据存储在其中。这就使得开发者不用花费大量的精力在表的设计中,降低了开发的成本。

另外SequoiaDB是一款双引擎数据库,支持JSON格式存储数据的同时,支持分布式对象存储,可以很好支撑非结构化数据管理。

 

低成本的部署

SequoiaDB可以安装在X86的机器上,相对于安装在高端存储的数据库,这无疑是一个成本的节约。SequoiaDB采用了三副本的存储方式,这有效地保证了数据的安全,另外由于使用分布式,数据被保存到多台服务器中,在查询数据时,查询任务会分发到多台机器上同时进行,最后汇总到同一台机器上汇总,这使得可以充分得利用多台服务器的资源,从而实现低成本的部署而又快速效应的效果。


支持复合索引

在传统的数据库中,很多产品都是只支持单一索引,而SequoiaDB还能支持复合索引。在复杂的业务系统中,数据量通常都很大,在查询数据时,通常需要带上多个查询条件,而且还要求快速响应。这就使得单一的索引查询很难满足业务的需求。SequoiaDB可以有效地解决这种问题,开发者可以根据业务的查询习惯,把一些经常需要带上的查询条件统计出来,从而把这些每次查询都必须带上的条件进行复合索引的创建。业务系统在查询时,SequoiaDB便会通过索引扫描的方式进行快速查询。


高安全性

SequoiaDB采用了多副本的存储方式,开发者通过规划,把数据散落在不同的数据组中,同一数据组的节点散落在不同的机器上,由于同一数据组的数据是一样的,这使得当服务器出现宕机等故障时,数据库可以快速地把主节点切换到其他的节点上,为业务系统提供服务,同时还能有效地防止数据的丢失。


环境搭建

软件配置

操作系统:windows 8

JDK:1.7.0_80 64位,下载地址为:http://www.oracle.com/technetwork/java/javase/downloads/java-archive-downloads-javase7-521261.html#jdk-7u80-oth-JPR

Myeclipse:12.0.0

SequoiaDB:2.8.1。安装部署参考:

Java驱动:2.6.3,下载地址为:

http://download.sequoiadb.com/cn/ index-cat_id-2


配置Eclipse环境

  • 将 SequoiaDB 驱动开发包中的 sequoiadb.jar 文件拷贝到工程文件目录下(建议将其放置在其他所有依赖库目录,如 lib 目录);

  • 在 Eclipse 主窗口左侧的“Package Explore”窗口中,选择开发工程,并点击鼠标右键;

  • 在菜单中选择“properties”菜单项;

  • 在弹出的“property for project …”窗口中,选择“Java Build Path”->“Libraries”,如下图所示:

  • 点击“Add External JARs..”按钮,选择添加 sequoiadb.jar 到工程中;

  • 点击“OK”完成环境配置。


SequoiaDB Java开发实例

示例一:列举collection

连接数据库,列举出数据库中的所有collection。

package   com.sequoiadb.demo;

import   com.sequoiadb.base.DBCursor;

import   com.sequoiadb.base.Sequoiadb;

import   com.sequoiadb.exception.BaseException;

public class Demo01 {

public static void   main(String[] args) {

      try{

           String connStr = "192.168.43.237";

           String userName = "";

           String password = "";

            //本例程连接到本地数据库的11810端口是协调节点的服务端口,使用的是空的用户名和

//密码。用户需要根据自己的实际情况配置参数。

           Sequoiadb sdb = new Sequoiadb(connStr,userName,password);

           DBCursor cursor =   sdb.listCollections();

           try{

                 while(cursor.hasNext()){

                      System.out.println(cursor.getNext().toString());

                 }                   

           }finally{

                 cursor.close();

           }

      }catch (BaseException e) {

           System.out.println("Sequoiadb   driver error, error description:" + e.getErrorType());

      }

}

}


示例二:增加查找操作

连接数据库,对数据库中的test表的记录进行增加查找的操作。

package   com.sequoiadb.demo;

import   org.bson.BSONObject;

import   org.bson.BasicBSONObject;

import   com.sequoiadb.base.CollectionSpace;

import   com.sequoiadb.base.DBCollection;

import   com.sequoiadb.base.DBCursor;

import   com.sequoiadb.base.Sequoiadb;

import   com.sequoiadb.exception.BaseException;

 

public   class Demo02 {

public static void main(String[] args) {

      String connStr =   "192.168.43.237:11810";

      String userName = "";

      String password = "";

      DBCursor cursor = null;

      try {

           Sequoiadb sdb = new   Sequoiadb(connStr,userName,password);

            CollectionSpace db = sdb.createCollectionSpace("space");

            DBCollection cl = db.createCollection("collection");

           //DBCollection cl =   sdb.getCollectionSpace("space")

.getCollection("collection");

          // 创建一个插入的 bson 对象

            BSONObject obj = new BasicBSONObject();

            obj.put("name", "xiaoming");

            obj.put("age", 24);

            //添加一条记录

            cl.insert(obj);

            //查询记录

            cursor = cl.query();

            try{

                 while (cursor.hasNext()) {

                   BSONObject record = cursor.getNext();

                   String name = (String)   record.get("name");

                   System.out.println("name="   +  name);

                 }

            }finally{

             cursor.close();

            }

      } catch (BaseException e) {

            System.out.println("Sequoiadb driver error, error   description:" + e.getErrorType());

      }

}

}

 

 


示例三:数据连接池的使用

数据库连接池的基本原理是在内部对象池中维护一定数量的数据库连接,并对外暴露数据库连接获取和返回方法。如:外部使用者可通过getConnection 方法获取连接,使用完毕后再通过releaseConnection 方法将连接返回,注意此时连接并没有关闭,而是由连接池管理器回收,并为下一次使用做好准备。

数据库连接池技术带来的优势: 

  • 资源复用:由于数据库连接得到重用,避免了频繁创建、释放连接引起的大量性能开销。在减少系统  消耗的基础上,另一方面也增进了系统运行环境的平稳性(减少内存碎片以及数据库临时进程/线程的数量)。

  • 更快的系统响应速度:数据库连接池在初始化过程中,往往已经创建了若干数据库连接至于池中备用。此时连接的初始化工作均已完成。对于业务请求处理而言,直接利用现有可用连接,避免了数据库连接  初始化和释放过程的时间,从而缩减了系统整体响应时间。

  • 统一的连接管理,避免数据库连接泄漏:在较为完备的数据库连接池实现中,可根据预先的连接占用超时设定,强制收回被占用连接。从而避免了常规数据库连接操作中可能出现的资源泄漏。

package   com.sequoiadb.demo;

import   java.util.ArrayList;

import   org.bson.BSONObject;

import   org.bson.BasicBSONObject;

import   com.sequoiadb.base.CollectionSpace;

import   com.sequoiadb.base.DBCollection;

import   com.sequoiadb.base.DBCursor;

import   com.sequoiadb.base.Sequoiadb;

import   com.sequoiadb.base.SequoiadbDatasource;

import   com.sequoiadb.datasource.ConnectStrategy;

import   com.sequoiadb.datasource.DatasourceOptions;

import   com.sequoiadb.exception.BaseException;

import   com.sequoiadb.net.ConfigOptions;

public   class Datasource {

    public static void main(String[] args)   throws InterruptedException {

        ArrayList<String> addrs = new   ArrayList<String>();

        String user = "";

        String password = "";

        ConfigOptions nwOpt = new   ConfigOptions();

        DatasourceOptions dsOpt = new   DatasourceOptions();

        SequoiadbDatasource ds = null;

        // 提供coord节点地址   

          addrs.add("192.168.43.237:11810");

        addrs.add("zxq3:11810");

        // 设置网络参数

        nwOpt.setConnectTimeout(500);          // 建连超时时间为500ms。

          nwOpt.setMaxAutoConnectRetryTime(0);     // 建连失败后重试时间为0ms。

        // 设置连接池参数

        dsOpt.setMaxCount(500);                 // 连接池最多能提供500个连接。

        dsOpt.setDeltaIncCount(20);             // 每次增加20个连接。

        dsOpt.setMaxIdleCount(20);              // 连接池空闲时,保留20个连接。

        dsOpt.setKeepAliveTimeout(0);          // 池中空闲连接存活时间。单位:毫秒。

        // 0表示不关心连接隔多长时间没有收发消息。

        dsOpt.setCheckInterval(60 *   1000);     // 每隔60秒将连接池中多于

        // MaxIdleCount限定的空闲连接关闭,

        // 并将存活时间过长(连接已停止收发

        // 超过keepAliveTimeout时间)的连接关闭。

// 向catalog同步coord地址的周期。单位:毫秒。       

        // 0表示不同步。

        dsOpt.setSyncCoordInterval(0); 

        // 连接出池时,是否检测连接的可用性,默认不检测。

          dsOpt.setValidateConnection(false);    

// 默认使用coord地址负载均衡的策略获取连接。

          dsOpt.setConnectStrategy(ConnectStrategy.BALANCE);

        // 建立连接池

        ds = new SequoiadbDatasource(addrs,   user, password, nwOpt, dsOpt);

        // 使用连接池运行任务

        runTask(ds);

        // 任务结束后,关闭连接池

        ds.close();

    }

    static void runTask(SequoiadbDatasource   ds) throws InterruptedException {

        String clFullName =   "mycs.mycl";

        // 准备任务

        Thread createCLTask = new Thread(new   CreateCLTask(ds, clFullName));

        Thread insertTask = new Thread(new   InsertTask(ds, clFullName));

        Thread queryTask = new Thread(new   QueryTask(ds, clFullName));

        // 创建集合

        createCLTask.start();

        createCLTask.join();

        // 往集合插记录

        insertTask.start();

        Thread.sleep(3000);

        // 从集合中查记录

        queryTask.start();

        // 等待任务结束

        insertTask.join();

        queryTask.join();

    }

}

class   CreateCLTask implements Runnable {

    private SequoiadbDatasource ds;

    private String csName;

    private String clName;

    public CreateCLTask(SequoiadbDatasource   ds, String clFullName) {

        this.ds = ds;

        this.csName = clFullName.split("\\.")[0];

        this.clName =   clFullName.split("\\.")[1];

    }

    @Override

    public void run() {

        Sequoiadb db = null;

        CollectionSpace cs = null;

        DBCollection cl = null;

        // 从连接池获取连接池

        try {

            db = ds.getConnection();

        } catch (BaseException e) {

            e.printStackTrace();

            System.exit(1);

        } catch (InterruptedException e) {

            e.printStackTrace();

            System.exit(1);

        }

        // 使用连接创建集合

        if   (db.isCollectionSpaceExist(csName))

            db.dropCollectionSpace(csName);

        cs =   db.createCollectionSpace(csName);

        cl = cs.createCollection(clName);

        // 将连接归还连接池

        ds.releaseConnection(db);

        System.out.println("Suceess to   create collection " + csName + "." + clName);

    }

}

class   InsertTask implements Runnable {

    private SequoiadbDatasource ds;

    private String csName;

    private String clName;

    public InsertTask(SequoiadbDatasource ds,   String clFullName) {

        this.ds = ds;

        this.csName =   clFullName.split("\\.")[0];

        this.clName =   clFullName.split("\\.")[1];

    }

    @Override

    public void run() {

        Sequoiadb db = null;

        CollectionSpace cs = null;

        DBCollection cl = null;

        BSONObject record = null;

        // 从连接池获取连接

        try {

            db = ds.getConnection();

        } catch (BaseException e) {

            e.printStackTrace();

            System.exit(1);

        } catch (InterruptedException e) {

            e.printStackTrace();

            System.exit(1);

        }

        // 使用连接获取集合对象

        cs = db.getCollectionSpace(csName);

        cl = cs.getCollection(clName);

        // 使用集合对象插入记录

        record = genRecord();

        cl.insert(record);

        // 将连接归还连接池

        ds.releaseConnection(db);

        System.out.println("Suceess to   insert record: " + record.toString());

    }

    private BSONObject genRecord() {

        BSONObject obj = new   BasicBSONObject();

        obj.put("name",   "James");

        obj.put("age", 30);

        return obj;

    }

}

class   QueryTask implements Runnable {

    private SequoiadbDatasource ds;

    private String csName;

    private String clName;

    public QueryTask(SequoiadbDatasource ds,   String clFullName) {

        this.ds = ds;

        this.csName =   clFullName.split("\\.")[0];

        this.clName =   clFullName.split("\\.")[1];

    }

    @Override

    public void run() {

        Sequoiadb db = null;

        CollectionSpace cs = null;

        DBCollection cl = null;

        DBCursor cursor = null;

        // 从连接池获取连接

        try {

            db = ds.getConnection();

        } catch (BaseException e) {

            e.printStackTrace();

            System.exit(1);

        } catch (InterruptedException e) {

            e.printStackTrace();

            System.exit(1);

        }

        // 使用连接获取集合对象

        cs = db.getCollectionSpace(csName);

        cl = cs.getCollection(clName);

        // 使用集合对象查询

        cursor = cl.query();

        try {

            while(cursor.hasNext()) {

            System.out.println("The   inserted record is: " + cursor.getNext());

            }

        } finally {

           cursor.close();

        }

        // 将连接对象归还连接池

        ds.releaseConnection(db);

    }

}

由于SequoiaDB的javaAPI涉及操作众多,在此不一一举例,其他的操作使用大同小异,具体可参考:

http://doc.sequoiadb.com/cn/index/Public/Home/document/208/api/java/html/index.html


SequoiaDB对持久层框架的支持

在软件开发中,基本所有的大型应用使用到了框架来进行开发,框架具有复用性,这使得一个应用开发速度得到了大大的提高。类似于Mybatis、Hibernate等等这些框架对jdbc操作数据库的过程进行封装,使得开发者只需要关注sql本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。SequoiaDB数据库的套件SequoiaSql是PostgreSQL功能的扩展。通过SequoiaSql,用户可以使用sql语句访问SequoiaDB数据库,完成对数据库的增删改查等操作。SequoiaSql集成持久层框架时,只需要使用到postgreSQL的jdbc连接驱动即可,其集成过程与其它框架集成postgreSQL的过程是一样的。


小结

随着数据以爆炸性的速度增长,集中式数据库越来越表现出了不足,分布式数据库越来越受到了开发者的青睐。SequoiaDB是一款支持SQL、高并发、实时性、分布式、可扩展、灵活存储的NewSQL数据库,支持Spark、Hadoop、hive、等大数据产品的连接同时提供了多种语言的驱动方便开发者的使用。在选择使用分布式数据库时,SequoiaDB无疑是一个很好的选择。

 



 公众号图片.png


准备开始体验 SequoiaDB 巨杉数据库?