2019独角兽企业重金招聘Python工程师标准>>>

在去年工作中遇见一个较为复杂的模块:智能表单。智能表单其实就问卷星一样的东西,由客户来根据需求设计表单内容样式,然后发布出去收集大家所填写的数据,最后进行统计分析,生成图表。

智能表单一开始遇见的困扰时数据库的设计。表单字段的不确定,对数据库要求的灵活性很大,所思之后解决方案主要有三:

1.根据用户设计的表单内容动态生成数据库表

 2.使用一张非常多字段的,来容得下客户可能要求的最大字段个数。

3.内存数据库。

首先由于客户量不太小,第一种动态生成表的方式被否决了,怕数据库负担太大。第二种感觉有点太蠢了哈哈,然后就选择了第三种,由于需要进行统计分析,所有选择了mongDB来作为最终的解决方案。

接下来就总结工作中如何把mongoDB整合到spring mvc,因为这个模块其实做起来很多,只对与mongDB沾边的进行一些简单举例:

1.毋庸置疑,引坐标进pom.xml中,自行选择版本

<!-- mongoDB依赖包 -->
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-mongodb</artifactId>
            <version>1.10.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.mongodb</groupId>
            <artifactId>mongo-java-driver</artifactId>
            <version>3.2.2</version>
        </dependency>

2.配置mongoDB数据源

1.在applicationContext.xml中配置<context:property-placeholder  location="classpath:application.properties" ignore-unresolvable="true"/> 设置读取外部资源方便配置数据库信息  ignore-unresolvable="true"如果已经存在配置外部资源的则需要设置此属性,否则默认只读取一个。

2.引入mongoBD配置在applicationContext中引入<import resource="spring-mongo.xml"/>单独拿到一个文件中来。

3.编写spring-mongo.xml内容

<!-- 加载mongodb的属性配置文件 -->
    <context:property-placeholder location="classpath:mongo.properties" ignore-unresolvable="true"/>
    <!-- spring连接mongodb数据库的配置 -->
    <mongo:mongo-client replica-set="${mongo.hostport}"  credentials="${mongo.username}:${mongo.password}@${mongo.dbname}" id="mongo">
        <mongo:client-options connections-per-host="${mongo.connectionsPerHost}"
                              threads-allowed-to-block-for-connection-multiplier="${mongo.threadsAllowedToBlockForConnectionMultiplier}"
                              connect-timeout="${mongo.connectTimeout}" max-wait-time="${mongo.maxWaitTime}"
                              socket-timeout="${mongo.socketTimeout}"/>
    </mongo:mongo-client>
    <!-- mongo的工厂,通过它来取得mongo实例,dbname为mongodb的数据库名,没有的话会自动创建 -->
    <mongo:db-factory id="mongoDbFactory" dbname="${mongo.dbname}" mongo-ref="mongo"/>

<!-- 只要使用这个调用相应的方法操作 -->
    <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
        <constructor-arg name="mongoDbFactory" ref="mongoDbFactory"/>
    </bean>
    
    <!-- mongodb bean的仓库目录,会自动扫描扩展了MongoRepository接口的接口进行注入 -->
    <mongo:repositories base-package="com.dg.ptm.model.mongo"/>//其实在智能表单中并不需要数据库字段的映射,所以这边引入只是为了当时学习一下,没有真正用到。

3.书写dao层,以方便使用,因为比较多,只简单列举几个,以便日后想起

列举一:

接口方法:

/**
     * 根据某一字段条件进行模糊查询
     * @param field 字段名
     * @param param 参数值
     * @param cls 类型
     * @return
     */
    public List fuzzySearchByOneParam(String field, String param, Class cls);

实现方法:

@Override
    public List fuzzySearchByOneParam(String field, String param, Class cls) {
        return getMongoTemplate().find(new Query(Criteria.where(
                field).regex(".*?\\" +param+ ".*")), cls);
    }

列举二:

    接口方法:

/**
     * 向集合众插入json格式文档
     * @param jsonStr 要插入的json
     * @param collectionName 集合名称
     */
    public void insertJSONObject(String jsonStr, String collectionName) throws Exception;

实现方法:

@Override
    public void insertJSONObject(String jsonStr, String  collectionName) throws Exception{
        DBCollection collection = getMongoTemplate().getCollection(collectionName);
        BasicDBObject document = (BasicDBObject) JSON.parse(jsonStr);
        collection.insert(document);
    }

还有一个较为复杂的分组统计的方法,但是我个人的方法有点愚钝,希望有更好方式的大神能给予教导,提供更好的方法,在mongo管道这一块还有很多的欠缺。

列举三

   接口方法:

/**
     * 通过输入的检索条件分组并查询匹配数据
     * @param query 查询条件
     * @param groupKey 分组字段
     * @param operate 操作名称
     * @param selectName 显示字段
     * @param collectionName 文档名称
     * @return
     * @throws Exception
     */
    public String findJsonObjectAndGroupByQuery(BasicDBObject query, String groupKey, String                  operate, String selectName, String collectionName) throws Exception;

实现方法:

public String findJsonObjectAndGroupByQuery(BasicDBObject query, String groupKey, String operate, String selectName, String collectionName)
            throws Exception {
        DBCollection collection = getMongoTemplate().getCollection(collectionName);
        DBObject keys = new BasicDBObject(groupKey, 1);
        DBObject initial = new BasicDBObject("count", 0);
        initial.put("result", 0);
        String reduce = "";
        String finalize = "";
        if("avg".equals(operate)) {  // 求平均数
            reduce = "function(doc,out){out.count++; out.result = out.result  + Number(doc." + selectName + ");}";
            finalize = "function(out){out.result = out.result / out.count;  return out;}";
        } else if("sum".equals(operate)) { // 求总和
            reduce = "function(doc,out){out.count++; out.result = out.result  + Number(doc." + selectName + ");}";
            finalize = "function(out){return out;}";
        } else if("max".equals(operate)) { // 求最大
            reduce = "function(doc,out){out.count++; if(out.result < Number(doc." + selectName + "))out.result = Number(doc." + selectName + ");}";
            finalize = "function(out){return out;}";
        } else if("min".equals(operate)) { // 求最小
            initial.put("result", Long.MAX_VALUE);
            reduce = "function(doc,out){out.count++; if(out.result > Number(doc." + selectName + "))out.result = Number(doc." + selectName + ");}";
            finalize = "function(out){if(out.result==" + Long.MAX_VALUE + ") {out.result = 0} return out;}";
        } else if("count".equals(operate)) { // 求总数
            reduce = "function(doc,out){out.count++;}";
            finalize = "function(out){out.result = out.count; return out;}";
        } else {
            throw new Exception();
        }
        
        BasicDBList dbList = (BasicDBList) collection.group(keys, query, initial, reduce, finalize);
        ListIterator<Object> listIterator = dbList.listIterator();
        Gson gson = new Gson();
        
        List<Map> resultList = new ArrayList<>();
        while(listIterator.hasNext()) {
            Map resultMap = gson.fromJson(String.valueOf(listIterator.next()), new TypeToken<Map>() {}.getType());
            resultList.add(resultMap);
        }
        return gson.toJson(resultList);
    }

mongDB很多命令行实现方式与js极为相似,所以我在实现分组的时候其实采用的是类似于js语言的实现方式。现在已记不清为什么不使用Aggregation管道操作来实现了。。。也记不太清遇到了什么难题,让我转而用这种方式,好像当时是因为数据类型的问题,无法进行正确的统计。

补充:最后瞎扯一下,如果使用mongoDB需要进行映射的操作,需要在pojo上声明注解@Document,这样你类中id就会与mongoDB中默认主键_id对应上,否则会被认为是一个新的字段,就这样啦啦。

转载于:https://my.oschina.net/huaizhe/blog/1626573

智能表单之mongoDB的使用相关推荐

  1. html5下拉智能,HTML5新增标签 + 智能表单

    一.HTML5的新增语义标签 1. 全新语义化标签 :用来定义文档或应用程序中的区域或章节. :用来定义文档的主导航区域,其中的链接指向其他页面或当前页面的某些区域. 用来包裹独立的内容片段,通常用来 ...

  2. BootStrap 智能表单系列 五 表单依赖插件处理

    这一章比较简单哦,主要就是生产表单元素后的一些后续处理操作,比如日期插件的渲染.一些autocomplete的处理等,在回调里面处理就可以了, demo: $("input.date-pic ...

  3. html 表单自动数值,web前端学习技术之对HTML5 智能表单的理解

    原标题:web前端学习技术之对HTML5 智能表单的理解 Html5新增input的form属性,用于指向特定form表单的id,实现input无需放在form标签之中,即可通过表单进行提交. - t ...

  4. Silverlight智能表单(3)之XML存储

    智能表单的存储要么存到数据库中,要么存到Xml文件中,以我目前的知识水平就这么两种想法了. 我最初的想法是存储到xml文件中,OK,说一下我的大体构架,该构架挺失败的(至少我是这样认为),但是我也没有 ...

  5. 智能表单一键分发,快速收集信息

    功能概述 智能表单是爱用旗下的表单系统,满足企业各种表单场景的使用,支持分享到微信.公众号.小程序.微博.Qzone等多种渠道. 问卷调查:极速创建各类调研问卷,如产品满意度调查.市场调研等. 报名登 ...

  6. Python项目-Day32-HTML5-语义化标签-智能表单-选择器

    Python项目-Day32-HTML5-语义化标签-智能表单-选择器 HTML5是什么? HTML5是一个新的网络标准,目标是取代现有的HTML 4.01和XHTML 1.0 标准.它希望能够减少互 ...

  7. ABAP调试和智能表单

    DEBUG基本  F5键:以循序渐进的方式执行程序行.  F6键:逐块执行程序(例如:方法.功能模块和子程序),而不进入单个代码块.  F7键:一起执行块中的所有代码行(例如:方法.函数模块和子 ...

  8. 使用JavaScript创建智能表单

    使用javascript创建智能表单 2000-05-26· 吕晓波·CPCW 验证用户输入 在我们的网站中,经常会加入一些表单,要求用户输入类似姓名或邮件地址等的个人信息.为了确保用户输入的信息符合 ...

  9. Web小案例——智能表单

    一.完成效果  二.代码 <!DOCTYPE html> <html><head><meta charset="utf-8">< ...

最新文章

  1. docker run 或者 docker restart 启动镜像就自动退出
  2. 什么是虚拟专用网(×××)
  3. 区块链BaaS云服务(17)纸贵科技Z-BaaS“合约中心”
  4. disconf mysql_disconf-web安装
  5. UltraEdit常用快捷键
  6. 洛谷 - P3254 圆桌问题(最大流+路径打印)
  7. VS2022+.NET6 RC1+C#10,.NET开发起飞
  8. vue实现数字“滚动式增加”效果 【插件化封装】
  9. Lintcode68 Binary Tree Postorder Traversal solution 题解
  10. 【毕设狗】【单片机毕业设计】基于单片机的智能垃圾桶设计-实物设计
  11. 苏州真不能成为一线城市?
  12. pandas数据拼接
  13. HTML中的长度单位px、em、rem
  14. QNX虚拟环境三 (内存 设备 调度 )
  15. Gitlab+Docker构建流水线部署
  16. 怎么联系计算机管理员,自己家电脑怎么联系网络管理员啊~~!?
  17. 253:丛林中的路——最小生成树Prim
  18. 有xp系统的云服务器,哪个云服务器有xp系统
  19. jmeter之Json断言使用方法
  20. 汇总: pwn分析工具GDB + peda + objdump + readelf

热门文章

  1. Java基础知识之笔记总结分享(超详细)
  2. 《android多媒体api》之VideoView 视频播放控件
  3. JS实现简易观察者模式
  4. java跟python优势_当前Java与Python相比还有哪些优势
  5. Netty——ByteBuf的API
  6. Mimikatz2.2 如何抓取Win11登录明文密码
  7. maven中央仓库地址(支持db2,informix等)
  8. |平面设计|节日将近又要开始撸各种中秋海报找灵感
  9. ROS坐标系中base_link和base_footprint的区别
  10. 【学习分享】8 创龙TMS320C6748开发板 基于PRU的Demo例程演示