分佈式NoSQL數據庫的Spring整合實踐

背景

Spring在J2EE應用程序開發框架中佔據重要的做用,它實現了輕量級的IoC(控制反轉)和AOP(面向切面)容器框架,可以對JavaBean的生命週期進行管理,能夠單獨使用也能夠和其餘框架進行整合,如Struts、MyBatis、Hibernate等主流框架。html

Spring的IoC技術促進了低耦合,可以將一個對象依賴的其它對象經過被動的方式傳遞進來,而不是這個對象本身建立或者查找依賴對象。面向切面的特性,容許經過分離應用的業務邏輯與系統級服務(例如審計和事務管理)進行開發,業務邏輯主要完成業務的各類功能,系統級服務負責其它的關注點,例如日誌或事務支持。Spring包含並管理應用對象的配置和生命週期,作爲一種容器能夠根據業務特性建立一個單獨的實例或者每次須要時都生成一個新的實例。Spring能夠將簡單的組件配置組合成爲複雜的應用,所以能很好的與其餘J2EE應用開發框架進行集成。前端

NoSQL數據庫目前在技術界正在成爲主流,所以巨杉數據庫SequoiaDB支持海量分佈式數據存儲,提供常見開發語言驅動程序便於開發人員直接操做數據庫中的數據。在大部分企業級應用程序開發過程當中,大部分開發人員或者客戶傾向於使用標準的SQL語句作爲數據操做的標準接口。巨杉數據庫利用巨杉SequoiaDB SSQL套件支持標準的SQL語句對數據庫中的數據進行各類操做,本文主要講解巨杉SequoiaDB SSQL套件與常見的J2EE開發框架進行集成以及開發過程當中遇到問題的解決思路。java

產品介紹

巨杉數據庫SequoiaDB是一款分佈式非關係型文檔數據庫,能夠被用來存取海量非關係型的數據,其底層主要基於分佈式,高可用,高性能與動態數據類型設計,它兼顧了關係型數據庫中衆多的優秀設計:如索引、動態查詢和更新等,同時以文檔記錄爲基礎更好地處理了動態靈活的數據類型。PostgreSQL支持標準SQL,巨杉SequoiaDB SSQL套件經過擴展 PostgreSQL功能可使用標準SQL 語句訪問 SequoiaDB 數據庫,完成對SequoiaDB 數據庫的各類操做。常見J2EE應用持久層開發框架,如Mybatis、Hibernate等支持PostgreSQL數據庫,而這些框架能很好的與Spring進行集成。所以巨杉SequoiaDB SSQL套件與Spring集成和PostgreSQL與Spring集成流程相同。node

環境搭建

3.1 軟件配置

操做系統:windows 7
JDK:1.7.0_80 64位,下載地址爲:linux

http://www.oracle.com/technetwork/java/javase/downloads/java-archive-downloads-javase7-521261.html#jdk-7u80-oth-JPR git

Myeclipse:12.0.0
SequoiaDB:1.12.5或以上版本
SequoiaDB SSQL:9.3.4
依賴包:Spring 3.2.四、mybatis 3.3.0、mybatis-spring 1.1.一、mybatis-paginator 1.2.五、postgresql-9.3.jdbc4-20131010.203348-4github

本項目主要實現從SequoiaDB中查詢數據並分頁來展現Spring整合SequoiaDB SSQL整合的整個過程。web

建立項目工程如圖:spring

圖片描述

說明:sql

  1. Spring整合SequoiaDB的時候建議選擇DBCP鏈接池管理數據庫鏈接

  2. SequoiaDB以及SequoiaDB SSQL安裝可參考SequoiaDB官網上面的安裝和鏈接器章節

3.2 集合空間和集合建立及數據準備

1. 以sdbadmin用戶登陸,進入到/opt/sequoiadb/bin目錄中,進入到SDB Shell控制檯建立集合空間和集合

建立集合空間腳本以下:

var db = new Sdb();
db.dropCS('CS');

建立集合腳本以下:

db.CS.createCL('account_tx');

執行結果以下圖:

圖片描述

2. 退出SDB Shell腳本,在linux控制檯執行下面命令導入數據:

./sdbimprt --hosts=node03:11810,node02:11810 --type=csv --file=cs.csv -c CS -l account_tx --fields='account_id long,tx_id long,customer_name string,tx_time string,tx_value int,account_overage long,tx_type int,other_side_account long,tx_site string,summary string' -j 3

執行結果以下圖:

圖片描述

3. 利用PostgreSQL鏈接器建立數據庫和外部表

建立數據庫的腳本以下:

bin/createdb -p 5432 cs

建立外部表的腳本以下:

create foreign table account_tx(account_id bigint,tx_id bigint,customer_name text,tx_time text,tx_value integer,account_overage bigint,tx_type integer,other_side_account bigint,tx_site text,summary text
) server sdb_server options ( collectionspace 'CS', collection 'account_tx' ) ;

執行結果以下圖:

圖片描述

4. 在PostgreSQL驗證測試數據

驗證測試數據腳本以下:

select * from account_tx limit 5;

執行結果以下圖:

圖片描述

代碼展現

4.1 框架搭建代碼展現

1.在web.xml文件初始化配置信息,如Spring listener和Dispatcher以及加載Spring相關配置文件。

具體配置信息以下:

<?xml version="1.0" encoding="UTF-8"?>
    <web-app xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web=http://java.sun.com/xml/ns/javaee xsi:schemaLocation=http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd id="WebApp_ID" version="2.5">
        <display-name>csWeb</display-name>
        <welcome-file-list>
            <welcome-file>index.jsp</welcome-file>
        </welcome-file-list>
        <context-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:applicationContext-*.xml</param-value>
        </context-param>
        <listener>
            <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
        </listener>
        <servlet>
            <servlet-name>springmvc</servlet-name>
            <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
            <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:springmvc.xml</param-value>
            </init-param>
        </servlet>
        <servlet-mapping>
            <servlet-name>springmvc</servlet-name>
            <url-pattern>*.do</url-pattern>
        </servlet-mapping>
    </web-app>

2. 數據庫鏈接信息在jdbc.properties中配置,具體信息以下:

jdbc.driver=org.postgresql.Driver
    jdbc.url=jdbc:postgresql://192.168.1.48:5432/cs
    jdbc.username=sdbadmin
    jdbc.password=

3. 數據操做以及事務控制配置信息在applicationContext-dao.xml和applicationContext-transaction.xml中。

applicationContext-dao.xml具體信息以下:

<beans xmlns=http://www.springframework.org/schema/beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc=http://www.springframework.org/schema/mvc xmlns:context=http://www.springframework.org/schema/context xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx=http://www.springframework.org/schema/tx xsi:schemaLocation="http://www.springframework.org/schema/beans  http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd ">
        <context:property-placeholder location="classpath:jdbc.properties" />
        <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="${jdbc.driver}" />
    <property name="url" value="${jdbc.url}" />
    <property name="username" value="${jdbc.username}" />
    <property name="password" value="${jdbc.password}" />
    <property name="maxActive" value="30" />
    <property name="maxIdle" value="5" />
    </bean>
        <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <property name="dataSource" ref="dataSource" />
            <property name="mapperLocations">
                <array>
                    <value>classpath:mapper/*.xml</value>
                </array>
            </property>
            <property name="configLocation" value="classpath:mybatic-config.xml" />
        </bean>
        <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
            <property name="basePackage" value="com/sequoiadb/cs/mapper"></property>
            <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
        </bean>
    </beans>

applicationContext-transaction.xml具體信息以下:

<beans xmlns=http://www.springframework.org/schema/beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc=http://www.springframework.org/schema/mvc xmlns:context=http://www.springframework.org/schema/context xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx=http://www.springframework.org/schema/tx xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd ">
        <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate" scope="prototype">
        <constructor-arg index="0" ref="sqlSessionFactory" />
        </bean>
        <aop:aspectj-autoproxy />
        <aop:config>
            <aop:pointcut id="appService" expression="execution(* com.sequoiadb.cs.service..*Service*.*(..))" />
            <aop:advisor advice-ref="txAdvice" pointcut-ref="appService" />
        </aop:config>
        <tx:advice id="txAdvice" transaction-manager="transactionManager">
            <tx:attributes>
                <tx:method name="select*" read-only="true" />
                <tx:method name="find*" read-only="true" />
                <tx:method name="get*" read-only="true" />
                <tx:method name="*" />
            </tx:attributes>
        </tx:advice>
        <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
            <property name="dataSource" ref="dataSource" />
        </bean>
    </beans>

4. spring MVC配置信息在springmvc.xml,具體信息以下:

<?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns=http://www.springframework.org/schema/beans xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
        xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans  http://www.springframework.org/schema/beans/spring-beans-3.2.xsd  http://www.springframework.org/schema/context  http://www.springframework.org/schema/context/spring-context.xsd  http://www.springframework.org/schema/mvc  http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd">
        <context:component-scan base-package="com.sequoiadb.cs.service" />
        <context:component-scan base-package="com.sequoiadb.cs.controller" />
        <mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <property name="prefix" value="/jsp/" />
            <property name="suffix" value=".jsp" />
        </bean>
        <bean id="conversionService"    class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
            <property name="converters">
                <list>
                    <bean class="com.sequoiadb.cs.controller.converter.CustomDateConverter" />
                </list>
            </property>
        </bean>
    </beans>

5. 數據操做採用的是MyBatis框架,MyBatis框架與Spring整合信息在mybatic-config.xml中,具體信息以下:

<?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configuration
    PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
        <typeAliases>
            <typeAlias type="com.sequoiadb.cs.entity.AccountTx" alias="AccountTx" />
        </typeAliases>
        <plugins>
            <plugin interceptor="com.github.pagehelper.PageHelper">
                <property name="dialect" value="postgresql" />
    <property name="offsetAsPageNum" value="true" />
                <property name="rowBoundsWithCount" value="true" />
                <property name="pageSizeZero" value="true" />
                <property name="reasonable" value="true" />
                <property name="params" value="pageNum=start;pageSize=limit;" />
                <property name="supportMethodsArguments" value="true" />
                <property name="returnPageInfo" value="check" />
            </plugin>
        </plugins>
    </configuration>

4.2 業務實現代碼展現

Spring整合SequoiaDB SSQL採用MVC設計模式,在Model層將外部表account_tx信息封裝到實體類,dao層採用MyBatis框架操做,Service層完成具體的業務邏輯,Controller層完成視圖的響應以及各類用戶動做業務的實現。

1. Model層account_tx對應實體類在AccountTx類中,具體信息以下:

package com.sequoiadb.cs.entity;
    
    import java.io.Serializable;
    
    public class AccountTx implements Serializable {
    
        private String account_id;
        private String tx_id;
        private String customer_name;
        private String tx_time;
        private int tx_value;
        private long account_overage;
        private int tx_type;
        private String other_side_account;
        private String tx_site;
        private String summary;
    
        public String getAccount_id() {
            return account_id;
        }
    
        public void setAccount_id(String account_id) {
            this.account_id = account_id;
        }
    
        public String getTx_id() {
            return tx_id;
        }
    
        public void setTx_id(String tx_id) {
            this.tx_id = tx_id;
        }
    
        public String getCustomer_name() {
            return customer_name;
        }
    
        public void setCustomer_name(String customer_name) {
            this.customer_name = customer_name;
        }
    
        public String getTx_time() {
            return tx_time;
        }
    
        public void setTx_time(String tx_time) {
            this.tx_time = tx_time;
        }
    
        public int getTx_value() {
            return tx_value;
        }
    
        public void setTx_value(int tx_value) {
            this.tx_value = tx_value;
        }
    
        public long getAccount_overage() {
            return account_overage;
        }
    
        public void setAccount_overage(long account_overage) {
            this.account_overage = account_overage;
        }
    
        public int getTx_type() {
            return tx_type;
        }
    
        public void setTx_type(int tx_type) {
            this.tx_type = tx_type;
        }
    
        public String getOther_side_account() {
            return other_side_account;
        }
    
        public void setOther_side_account(String other_side_account) {
            this.other_side_account = other_side_account;
        }
    
        public String getTx_site() {
            return tx_site;
        }
    
        public void setTx_site(String tx_site) {
            this.tx_site = tx_site;
        }
    
        public String getSummary() {
            return summary;
        }
    
        public void setSummary(String summary) {
            this.summary = summary;
        }
    }

2. 數據操做在AccountTxMapper類中,配置信息在AccountTxMapper.xml中

AccountTxMapper類具體信息以下:

package com.sequoiadb.cs.mapper;
    import java.util.List;
    import java.util.Map;
    
    import com.sequoiadb.cs.entity.AccountTx;
    
    public interface AccountTxMapper {
        public List<AccountTx> queryAll(Map map) throws Exception;// 查詢全部
    }

AccountTxMapper.xml具體信息以下:

<?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.sequoiadb.cs.mapper.AccountTxMapper">
        <resultMap id="BaseResultMap" type="com.sequoiadb.cs.entity.AccountTx">
            <id column="tx_id" property="tx_id" jdbcType="BIGINT" />
            <result column="account_id" property="account_id" jdbcType="BIGINT" />
            <result column="customer_name" property="customer_name" jdbcType="VARCHAR" />
            <result column="tx_time" property="tx_time" jdbcType="VARCHAR" />
            <result column="tx_value" property="tx_value" jdbcType="INTEGER" />
            <result column="account_overage" property="account_overage" jdbcType="BIGINT" />
            <result column="tx_type" property="tx_type" jdbcType="INTEGER" />
            <result column="other_side_account" property="other_side_account" jdbcType="BIGINT" />
            <result column="tx_site" property="tx_site" jdbcType="VARCHAR" />
            <result column="summary" property="summary" jdbcType="VARCHAR" />
        </resultMap>
        <select id="queryAll" resultType="com.sequoiadb.cs.entity.AccountTx" parameterType="java.util.Map"> 
            select * from account_tx where 1=1
            <if test="tx_id != null" >
                and tx_id = #{tx_id,jdbcType=BIGINT}
              </if>
              <if test="account_id != null" >
                and account_id = #{account_id,jdbcType=BIGINT} order by tx_time desc
              </if>
        </select>
    </mapper>

3. Service完成具體的業務邏輯,AccountTxService類定義具體需完成的業務接口,AccountTxServiceImpl類繼承AccountTxService完成具體的業務操做。

AccountTxService接口具體信息以下:

package com.sequoiadb.cs.service;
    
    import java.util.List;
    import java.util.Map;
    
    import com.sequoiadb.cs.entity.AccountTx;
    
    public interface AccountTxService {
        public List<AccountTx> queryAll(Map map) throws Exception;// 查詢全部
    }

AccountTxServiceImpl具體實現以下:

package com.sequoiadb.cs.service.impl;
    
    import java.util.List;
    import java.util.Map;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import com.sequoiadb.cs.entity.AccountTx;
    import com.sequoiadb.cs.mapper.AccountTxMapper;
    import com.sequoiadb.cs.service.AccountTxService;
    
    @Service("accountTxService")
    public class AccountTxServiceImpl implements AccountTxService {
    
        @Autowired
        private AccountTxMapper accountTxMapper;
    
        @Override
        public List<AccountTx> queryAll(Map map) throws Exception {
            return accountTxMapper.queryAll(map);
        }
    }

4. Controller完成視圖的響應以及各類用戶動做業務的實現,具體實如今AccountTxController類中,具體信息以下:

package com.sequoiadb.cs.controller;
    
    import java.io.IOException;
    import java.io.PrintWriter;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import net.sf.json.JSONArray;
    import net.sf.json.JSONObject;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.ResponseBody;
    
    import com.github.pagehelper.PageHelper;
    import com.github.pagehelper.PageInfo;
    import com.sequoiadb.cs.entity.AccountTx;
    import com.sequoiadb.cs.service.AccountTxService;
    import com.sequoiadb.cs.utils.JSONUtils;
    
    @Controller
    @RequestMapping("/accountTx")
    public class AccountTxController {
        @Autowired
        private AccountTxService accountTxService;
        
        @RequestMapping(value = "/query", method = { RequestMethod.POST})
        @ResponseBody
        public String queryAll(HttpServletRequest request,HttpServletResponse response) throws Exception {
            String tx_id = request.getParameter("tx_id");
            String account_id = request.getParameter("account_id");
            String sEcho = null;
            int pageNum = 0; // 起始索引
            int pageSize = 0; // 每頁顯示的行數
            JSONArray jsonarray = JSONArray.fromObject(request.getParameter("aoData"));
            for (int i = 0; i < jsonarray.size(); i++) {
                JSONObject obj = (JSONObject) jsonarray.get(i);
                if (obj.get("name").equals("sEcho"))
                    sEcho = obj.get("value").toString();
         
                if (obj.get("name").equals("iDisplayStart"))
                    pageNum = obj.getInt("value");
         
                if (obj.get("name").equals("iDisplayLength"))
                    pageSize = obj.getInt("value");
            }
            PageHelper.startPage(pageNum, pageSize);
            Map map = new HashMap();
            if(tx_id != null && tx_id.length() > 0){
                map.put("tx_id", Long.parseLong(tx_id));
            }
            if(account_id != null && account_id.length() > 0){
                map.put("account_id", Long.parseLong(account_id));
            }
            List<AccountTx> accountTxList = accountTxService.queryAll(map);
    
            PageInfo<AccountTx> pagehelper = new PageInfo<AccountTx>(accountTxList);
    
            int  initEcho = Integer.parseInt(sEcho)+1;
            Map dataMap = new HashMap();    
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("iTotalRecords", pagehelper.getTotal());
            jsonObject.put("sEcho",initEcho);
            jsonObject.put("iTotalDisplayRecords", pagehelper.getTotal());
            jsonObject.put("aaData", pagehelper.getList());
            JSONUtils.toJSONString(dataMap);
            return jsonObject.toString();
        }
        private void sendJsonData(HttpServletResponse response, String data)throws IOException {
            response.setContentType("text/html;charset=UTF-8");
            PrintWriter out;
            out = response.getWriter();
            out.println(data);
            out.flush();
            out.close();
        }
    }

5. 本項目主要演示從SequoiaDB數據庫中,經過SequoiaDB SSQL查詢數據而且分頁,因爲篇幅較大具體前端頁面代碼不在此展現,可參考附件中index.jsp文件中的源碼。具體查詢功能結果展現以下圖:

圖片描述

總結

從上述整合過程能夠看出,Spring整合SequoiaDB SSQL套件和Spring整合其餘數據庫如PostgreSQL數據庫流程一致。整合過程當中主要是根據持久層框架的選擇如MyBatis、Hibernate來肯定Spring的配置信息,而且在持久層框架肯定後需將SequoiaDB的Java驅動jar包添加到項目中。

相關文章
相關標籤/搜索