智能表单之mongoDB的使用
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的使用相关推荐
- html5下拉智能,HTML5新增标签 + 智能表单
一.HTML5的新增语义标签 1. 全新语义化标签 :用来定义文档或应用程序中的区域或章节. :用来定义文档的主导航区域,其中的链接指向其他页面或当前页面的某些区域. 用来包裹独立的内容片段,通常用来 ...
- BootStrap 智能表单系列 五 表单依赖插件处理
这一章比较简单哦,主要就是生产表单元素后的一些后续处理操作,比如日期插件的渲染.一些autocomplete的处理等,在回调里面处理就可以了, demo: $("input.date-pic ...
- html 表单自动数值,web前端学习技术之对HTML5 智能表单的理解
原标题:web前端学习技术之对HTML5 智能表单的理解 Html5新增input的form属性,用于指向特定form表单的id,实现input无需放在form标签之中,即可通过表单进行提交. - t ...
- Silverlight智能表单(3)之XML存储
智能表单的存储要么存到数据库中,要么存到Xml文件中,以我目前的知识水平就这么两种想法了. 我最初的想法是存储到xml文件中,OK,说一下我的大体构架,该构架挺失败的(至少我是这样认为),但是我也没有 ...
- 智能表单一键分发,快速收集信息
功能概述 智能表单是爱用旗下的表单系统,满足企业各种表单场景的使用,支持分享到微信.公众号.小程序.微博.Qzone等多种渠道. 问卷调查:极速创建各类调研问卷,如产品满意度调查.市场调研等. 报名登 ...
- Python项目-Day32-HTML5-语义化标签-智能表单-选择器
Python项目-Day32-HTML5-语义化标签-智能表单-选择器 HTML5是什么? HTML5是一个新的网络标准,目标是取代现有的HTML 4.01和XHTML 1.0 标准.它希望能够减少互 ...
- ABAP调试和智能表单
DEBUG基本 F5键:以循序渐进的方式执行程序行. F6键:逐块执行程序(例如:方法.功能模块和子程序),而不进入单个代码块. F7键:一起执行块中的所有代码行(例如:方法.函数模块和子 ...
- 使用JavaScript创建智能表单
使用javascript创建智能表单 2000-05-26· 吕晓波·CPCW 验证用户输入 在我们的网站中,经常会加入一些表单,要求用户输入类似姓名或邮件地址等的个人信息.为了确保用户输入的信息符合 ...
- Web小案例——智能表单
一.完成效果 二.代码 <!DOCTYPE html> <html><head><meta charset="utf-8">< ...
最新文章
- docker run 或者 docker restart 启动镜像就自动退出
- 什么是虚拟专用网(×××)
- 区块链BaaS云服务(17)纸贵科技Z-BaaS“合约中心”
- disconf mysql_disconf-web安装
- UltraEdit常用快捷键
- 洛谷 - P3254 圆桌问题(最大流+路径打印)
- VS2022+.NET6 RC1+C#10,.NET开发起飞
- vue实现数字“滚动式增加”效果 【插件化封装】
- Lintcode68 Binary Tree Postorder Traversal solution 题解
- 【毕设狗】【单片机毕业设计】基于单片机的智能垃圾桶设计-实物设计
- 苏州真不能成为一线城市?
- pandas数据拼接
- HTML中的长度单位px、em、rem
- QNX虚拟环境三 (内存 设备 调度 )
- Gitlab+Docker构建流水线部署
- 怎么联系计算机管理员,自己家电脑怎么联系网络管理员啊~~!?
- 253:丛林中的路——最小生成树Prim
- 有xp系统的云服务器,哪个云服务器有xp系统
- jmeter之Json断言使用方法
- 汇总: pwn分析工具GDB + peda + objdump + readelf
热门文章
- Java基础知识之笔记总结分享(超详细)
- 《android多媒体api》之VideoView 视频播放控件
- JS实现简易观察者模式
- java跟python优势_当前Java与Python相比还有哪些优势
- Netty——ByteBuf的API
- Mimikatz2.2 如何抓取Win11登录明文密码
- maven中央仓库地址(支持db2,informix等)
- |平面设计|节日将近又要开始撸各种中秋海报找灵感
- ROS坐标系中base_link和base_footprint的区别
- 【学习分享】8 创龙TMS320C6748开发板 基于PRU的Demo例程演示