SpringBoot整合MongoDB JPA,测试MongoRepository与MongoTemplate用法,简单增删改查+高级聚合
源码
地址
-> https://github.com/TaoPanfeng/case/tree/master/04-mongo/springboot-mongo
一 引入依赖
<dependencies>
<!--mongo操作mongo-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
<version>2.1.8.RELEASE</version>
</dependency>
<!--lombok简化实体类-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.10</version>
</dependency>
<!--test测试-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>2.1.8.RELEASE</version>
</dependency>
</dependencies>
二 配置MongoDB信息
#mongo01是数据库
spring.data.mongodb.uri=mongodb://192.168.1.3:27018/mongo01
#账号密码配置
#spring.data.mongodb.uri=mongodb://user:pwd@ip:port/db
#多节点配置
#spring.data.mongodb.uri=mongodb://user:pwd@ip1:port1,ip2:port2/db
三 添加SpringBoot主配置类
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringbootMongoApplication
{
public static void main(String[] args)
{
SpringApplication.run(SpringbootMongoApplication.class);
}
}
四 创建实体类
Grade
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import java.util.List;
@Document(collection = "grade")//对应表名
@Data//setter getter toString
@NoArgsConstructor//无参构造
@AllArgsConstructor//全参构造
public class Grade
{
@Id//主键
private String id;
private Integer grade_id;
private String grade_name;
private List<Student> student_list;
}
Student
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;
@Document(collection = "student")//对应表名
@Data//setter getter toString
@NoArgsConstructor//无参构造
@AllArgsConstructor//全参构造
public class Student
{
@Id//主键
private String id;
@Field("stu_name")//对应列名
private String stu_name;
private Integer age;
private Integer grade_id;
private Grade grade;
}
五 注意
-> 数据不保证全对,主要是对方法的理解
六 MongoRepository
这个方便对实体类映射进行简单的
增删改查
以及分页
查询支持@Query注解,增删改不支持注解,只有自带的方法
不支持多表(Lookup)+聚合(Aggregation)+分布式计算(MapReduce)
这里我只演示查询就行了,其他的没什么好说的...
主要讲MongoTemplate
...
1 StudentRepository
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.mongodb.repository.Query;
import panfeng.pojo.Student;
import java.util.List;
public interface StudentRepository extends MongoRepository<Student, String>
{
@Query("{'stu_name':?0}}")
List<Student> findStudentsByStu_name(String stu_name);
@Query("{'stu_name':{$regex:'?0'}}")
List<Student> findStudentsByStu_nameBetween(String stu_name);
@Query("{'stu_name':{$regex:'^?0'}}")
List<Student> findStudentsByStu_nameStartingWith(String stu_name);
@Query("{$and:[{'stu_name':?0},{'age':?1}]}")
List<Student> findStudentsByStu_nameaAndAge(String stu_name,Integer age);
}
2 MongoRepositoryTest
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.test.context.junit4.SpringRunner;
import panfeng.repository.StudentRepository;
@RunWith(SpringRunner.class)
@SpringBootTest
public class MongoRepositoryTest
{
@Autowired
private StudentRepository studentRepository;
/**
* 总体来说不太方便,没有 MongoTemplate 方便
*/
/*测试数据 表名 student
{"stu_name":"大牛哥哥","age":15,"grade_id":1}
{"stu_name":"二蛋","age":11,"grade_id":2}
{"stu_name":"三驴","age":18,"grade_id":3}
{"stu_name":"四毛","age":18,"grade_id":1}
{"stu_name":"五虎","age":20,"grade_id":2}
{"stu_name":"六豹子","age":13,"grade_id":3}
{"stu_name":"六豹子","age":17,"grade_id":3}
{"stu_name":"豹","age":11,"grade_id":3}
*/
@Test
public void select()
{
//查询所有 *
// studentRepository.findAll().forEach(System.out::println);
//查询所有并按照年龄排序
// Sort sort = new Sort(Sort.Direction.ASC, "age");
// studentRepository.findAll(sort).forEach(System.out::println);
//分页 每页2条 查询第二页
// PageRequest pageRequest = new PageRequest(1, 2);//page 0第一页 1第二页
// studentRepository.findAll(pageRequest).forEach(System.out::println);
//根据名称查询 stu_name='六豹子'
// studentRepository.findStudentsByStu_name("六豹子").forEach(System.out::println);
//模糊查询 stu_name like '%豹%'
// studentRepository.findStudentsByStu_nameBetween("豹").forEach(System.out::println);
//模糊查询以什么开头 stu_name like '豹%'
// studentRepository.findStudentsByStu_nameStartingWith("豹").forEach(System.out::println);
//查询 stu_name=六豹子 and age=13
// studentRepository.findStudentsByStu_nameaAndAge("六豹子",13).forEach(System.out::println);
}
}
七 MongoTemplate
注意
每个方法最后一项配合Document的使用
先把大致内容写出来,再逐个写方法
MongoTemplateTest
package panfeng;
import com.mongodb.BasicDBList;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
import com.mongodb.MapReduceCommand;
import com.mongodb.client.result.DeleteResult;
import com.mongodb.client.result.UpdateResult;
import com.sun.beans.decoder.ValueObject;
import org.bson.BsonDocument;
import org.bson.Document;
import org.json.JSONArray;
import org.json.JSONObject;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.*;
import org.springframework.data.mongodb.core.mapreduce.MapReduceOptions;
import org.springframework.data.mongodb.core.mapreduce.MapReduceResults;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.test.context.junit4.SpringRunner;
import panfeng.pojo.Grade;
import panfeng.pojo.Student;
import panfeng.repository.StudentRepository;
import java.util.Iterator;
import java.util.List;
@RunWith(SpringRunner.class)
@SpringBootTest
public class MongoTemplateTest
{
@Autowired
private MongoTemplate mongoTemplate;
@Test
public void insert() throws Exception
{
}
@Test
public void delete() throws Exception
{
}
@Test
public void update() throws Exception
{
}
@Test
public void select() throws Exception
{
}
@Test
public void aggregation() throws Exception
{
}
@Test
public void mapReduce() throws Exception
{
}
}
1 insert()
@Test
public void insert() throws Exception
{
//插入学生数据
// mongoTemplate.save(new Student(null, "大牛哥哥", 15, 1, null));
// mongoTemplate.save(new Student(null, "二蛋", 11, 2, null));
// mongoTemplate.save(new Student(null, "三驴", 18, 3, null));
// mongoTemplate.save(new Student(null, "四毛", 18, 1, null));
// mongoTemplate.save(new Student(null, "五虎", 20, 2, null));
// mongoTemplate.save(new Student(null, "六豹子", 13, 3, null));
// mongoTemplate.save(new Student(null, "六豹子", 17, 3, null));
// mongoTemplate.save(new Student(null, "豹", 11, 3, null));
//插入年级数据
// mongoTemplate.save(new Grade(null,1,"一年级"));
// mongoTemplate.save(new Grade(null,2,"二年级"));
// mongoTemplate.save(new Grade(null,3,"三年级"));
//插入学生 -> Document模式
// Document document=new Document()
// .append("stu_name","陶攀峰")
// .append("age",26)
// .append("grade_id",4);
// mongoTemplate.save(document,"student");
}
2 delete()
@Test
public void delete() throws Exception
{
//删除所有grade_id=3
// Query query = Query.query(Criteria.where("grade_id").is(3));
// DeleteResult deleteResult = mongoTemplate.remove(query, Student.class);
// System.out.println(deleteResult.getDeletedCount());//删除的数量
//删除全部
// DeleteResult deleteResult = mongoTemplate.remove(new Query(), Student.class);
// System.out.println(deleteResult.getDeletedCount());//删除的数量
//删除所有 age=4 -> 表 student
// Query query = Query.query(Criteria.where("age").is(4));
// DeleteResult deleteResult = mongoTemplate.remove(query, "student");
// System.out.println(deleteResult.getDeletedCount());//删除的数量
}
3 update()
@Test
public void update() throws Exception
{
//修改stu_name="三驴" and age!=18的第一条记录 -> stu_name="三驴弟弟",age=18
// Query query=Query.query(Criteria.where("stu_name").is("三驴").and("age").ne(18));
// Update update = new Update().set("stu_name", "三驴弟弟").set("age", 19);
// UpdateResult updateResult = mongoTemplate.updateFirst(query, update, Student.class);
// System.out.println(updateResult.getModifiedCount());//修改多少条
//修改所有的address="9527" 如果不存在就插入字段,如果存在则修改,也会改变字段类型
// Update update = new Update().set("address", "9527");
// UpdateResult updateResult = mongoTemplate.updateMulti(new Query(), update, Student.class);
// System.out.println(updateResult.getModifiedCount());//修改多少条
//修改表 student 所有的stu_name="陶攀峰" -> stu_name="陶攀峰1",age=27
// Query query = Query.query(Criteria.where("stu_name").is("陶攀峰"));
// Update update = new Update().set("stu_name", "陶攀峰1").set("age", 27);
// UpdateResult updateResult = mongoTemplate.updateMulti(query, update, "student");
// System.out.println(updateResult.getModifiedCount());//修改多少条
}
4 select()
@Test
public void select() throws Exception
{
//查询对应Document
// mongoTemplate.findAll(Document.class, "student").forEach(System.out::println);
//查询所有的数据 -> 循环打印数据
// mongoTemplate.findAll(Student.class).forEach(System.out::println);
// System.out.println("共计" + mongoTemplate.findAll(Student.class).size() + "条...");
//查询stu_name="三驴"
// Query query=Query.query(Criteria.where("stu_name").is("三驴"));
// mongoTemplate.find(query, Student.class).forEach(System.out::println);
//查询age>18
// Query query=Query.query(Criteria.where("age").gt(18));
// mongoTemplate.find(query,Student.class).forEach(System.out::println);
//查询stu_name="三驴" and age>16
// Query query=Query.query(Criteria.where("stu_name").is("三驴").and("age").gt(16));
// mongoTemplate.find(query,Student.class).forEach(System.out::println);
//查询stu_name like '%牛%'
// Query query = Query.query(Criteria.where("stu_name").regex("牛"));
// mongoTemplate.find(query, Student.class).forEach(System.out::println);
//查询stu_name like '五%'
// Query query = Query.query(Criteria.where("stu_name").regex("^五"));
// mongoTemplate.find(query, Student.class).forEach(System.out::println);
//查询age>15 并且按照age 降序
// Query query = Query.query(Criteria.where("age").gt(15)).with(new Sort(Sort.Direction.DESC, "age"));
// mongoTemplate.find(query,Student.class).forEach(System.out::println);
//查询排序并分页
// Query query=new Query();
// query.with(new Sort(Sort.Direction.ASC,"age"));//按照age升序
// query.with(new PageRequest(1,3));//page 0第一页 1第二页 -> 3每页三条记录
// mongoTemplate.find(query,Student.class).forEach(System.out::println);
//查询去除前2条,再取前三条 -> 取第3 4 5 条记录
// Query query=new Query();
// query.skip(2);
// query.limit(3);
// mongoTemplate.find(query,Student.class).forEach(System.out::println);
//查询去除前2条,再取前三条 -> 取第3 4 5 条记录 -> 返回 Document
// Query query=new Query().skip(2).limit(3);
// mongoTemplate.find(query,Document.class,"student").forEach(System.out::println);
}
5 aggregation()
@Test
public void aggregation() throws Exception
{
//查询所有学生,并关联到对应的年级 -> 从表.主表字段.从表字段.添加主表字段名称
// LookupOperation lookupOperation = Aggregation.lookup("grade", "grade_id", "grade_id", "grade");
// Aggregation aggregation = Aggregation.newAggregation(lookupOperation);
// //如果collection=主表名称
// //Student.class是对应主表的类,输出类型
// List<Student> student_list = mongoTemplate.aggregate(aggregation, "student", Student.class).getMappedResults();
// student_list.forEach(System.out::println);
//查询所有年级,并关联到对应的学生 -> 从表.主表字段.从表字段.添加主表字段名称
// LookupOperation lookupOperation = Aggregation.lookup("student", "grade_id", "grade_id", "student_list");
// Aggregation aggregation = Aggregation.newAggregation(lookupOperation);
// //如果collection=主表名称
// //Grade.class是对应主表的类,输出类型
// List<Grade> grade_list = mongoTemplate.aggregate(aggregation, "grade", Grade.class).getMappedResults();
// grade_list.forEach(System.out::println);
//查询所有学生,并关联到对应的年级,输出Document -> 从表.主表字段.从表字段.添加主表字段名称
// LookupOperation lookupOperation = Aggregation.lookup("grade", "grade_id", "grade_id", "grade");
// Aggregation aggregation = Aggregation.newAggregation(lookupOperation);
// List<Document> document_list = mongoTemplate.aggregate(aggregation, "student", Document.class).getMappedResults();
// document_list.forEach(System.out::println);
// document_list.forEach(document ->
// {
// System.out.println(document.get("age"));//输出age字段
// });
//管道过滤
// //1,查询age>11
// MatchOperation matchOperation = Aggregation.match(Criteria.where("age").gt(11));
// //2,使student与grade匹配,将匹配到的grade添加到grade字段 -> 从表.主表字段.从表字段.添加主表字段名称
// LookupOperation lookupOperation = Aggregation.lookup("grade", "grade_id", "grade_id", "grade");
// //3,按照age升序
// SortOperation sortOperation = Aggregation.sort(Sort.Direction.ASC, "age");
// //4,去除前2个值
// SkipOperation skipOperation = Aggregation.skip(2);
// //5,查询前3个值
// LimitOperation limitOperation = Aggregation.limit(3);
// //6,按照age分组,取个别名age_group记录按age分组的数量
// GroupOperation groupOperation = Aggregation.group("age").count().as("age_group");
// //7,获取总记录数,取个别名count
// CountOperation countOperation = Aggregation.count().as("count");
// //Aggregation aggregation = Aggregation.newAggregation(groupOperation);
// //Aggregation aggregation = Aggregation.newAggregation(countOperation);
// Aggregation aggregation = Aggregation.newAggregation(matchOperation, lookupOperation, sortOperation, skipOperation, limitOperation);
// //如果collection=主表名称
// //Document.class是对应输出类型
// List<Document> document_list = mongoTemplate.aggregate(aggregation, "student", Document.class).getMappedResults();
// document_list.forEach(System.out::println);
}
6 mapReduce()
@Test
public void mapReduce() throws Exception
{
/*测试数据 表名 a
{_id:1,sku_id:"a",stock:11}
{_id:2,sku_id:"b",stock:22}
{_id:3,sku_id:"c",stock:33}
{_id:4,sku_id:"d",stock:44}
{_id:5,sku_id:"e",stock:55}
{_id:6,sku_id:"a",stock:66}
{_id:7,sku_id:"b",stock:77}
{_id:8,sku_id:"c",stock:88}
{_id:9,sku_id:"d",stock:99}
*/
// mongoTemplate.mapReduce("article_info", "classpath:map.js",
// "classpath:reduce.js", options, ValueObject.class);
//方式1
// String map = "function(){" +
// "emit(this.sku_id,this.stock);" +
// "};";
// String reduce = "function(k,v){" +
// "return Array.sum(v);" +
// "};";
// mongoTemplate.mapReduce("a", map, reduce, Document.class).forEach(System.out::println);
//输出
// Document{{_id=a, value=77.0}}
// Document{{_id=b, value=99.0}}
// Document{{_id=c, value=121.0}}
// Document{{_id=d, value=143.0}}
// Document{{_id=e, value=55.0}}
//方式2
// String map = "function(){" +
// "emit(this.sku_id,this.stock);" +
// "};";
// String reduce = "function(k,v){" +
// "return {'k1':k,'v1':v,'sum':Array.sum(v)};" +
// "};";
// mongoTemplate.mapReduce("a", map, reduce, Document.class).forEach(System.out::println);
//输出
// Document{{_id=a, value=Document{{k1=a, v1=[11.0, 66.0], sum=77.0}}}}
// Document{{_id=b, value=Document{{k1=b, v1=[22.0, 77.0], sum=99.0}}}}
// Document{{_id=c, value=Document{{k1=c, v1=[33.0, 88.0], sum=121.0}}}}
// Document{{_id=d, value=Document{{k1=d, v1=[44.0, 99.0], sum=143.0}}}}
// Document{{_id=e, value=55.0}}
//方式3 -> query map reduce finalize
// String map = "function(){" +//this对应传入的表
// "emit(this.sku_id,this.stock);" +
// "};";
// String reduce = "function(k1,v1){" +//function(k1,v1) 对应 map的emit(k,v) -> k1=sku_id v1=stock
// "return {'k1':k1,'v1':v1,'sum':Array.sum(v1)};" +//添加sum字段记录总数
// "};";
// Query query=Query.query(Criteria.where("stock").ne(55));
// String finalize="function(k2,v2){" +// k2=k1 v2=reduce的ruturn
// "v2.avg=v.sum/v2.v1.length;" +//添加字段计算平均值
// "return v2;}";
// MapReduceOptions mapReduceOptions=new MapReduceOptions().finalizeFunction(finalize);
// mongoTemplate.mapReduce(query,"a",map,reduce,mapReduceOptions,Document.class).forEach(System.out::println);
//输出
// Document{{_id=a, value=Document{{k1=a, v1=[11.0, 66.0], sum=77.0, avg=38.5}}}}
// Document{{_id=b, value=Document{{k1=b, v1=[22.0, 77.0], sum=99.0, avg=49.5}}}}
// Document{{_id=c, value=Document{{k1=c, v1=[33.0, 88.0], sum=121.0, avg=60.5}}}}
// Document{{_id=d, value=Document{{k1=d, v1=[44.0, 99.0], sum=143.0, avg=71.5}}}}
}
SpringBoot整合MongoDB JPA,测试MongoRepository与MongoTemplate用法,简单增删改查+高级聚合的更多相关文章
- mongoDB 学习笔记纯干货(mongoose、增删改查、聚合、索引、连接、备份与恢复、监控等等)
最后更新时间:2017-07-13 11:10:49 原始文章链接:http://www.lovebxm.com/2017/07/13/mongodb_primer/ MongoDB - 简介 官网: ...
- 【转】mongoDB 学习笔记纯干货(mongoose、增删改查、聚合、索引、连接、备份与恢复、监控等等)
mongoDB 学习笔记纯干货(mongoose.增删改查.聚合.索引.连接.备份与恢复.监控等等) http://www.cnblogs.com/bxm0927/p/7159556.html
- mongoDB (mongoose、增删改查、聚合、索引、连接、备份与恢复、监控等等)
MongoDB - 简介 官网:https://www.mongodb.com/ MongoDB 是一个基于分布式文件存储的数据库,由 C++ 语言编写,旨在为 WEB 应用提供可扩展的高性能数据存储 ...
- MongoDB - 增删改查及聚合操作
目录 MongoDB - 增删改查及聚合操作 一. 数据库操作(database) 1. 创建及查看库 2. 删除库 二. 集合collectionc=操作(相当于SQL数据库中的表table) 1. ...
- MongoDB学习笔记,基础+增删改查+索引+聚合...
一 基础了解 对应关系 -> https://docs.mongodb.com/manual/reference/sql-comparison/ database -> database ...
- mongodb数据库学习【安装及简单增删改查】
//@desn:mongodb数据库学习 //@desn:码字不宜,转载请注明出处 //@author:张慧源 <turing_zhy@163.com> //@date:2018/08/ ...
- 04-springboot整合elasticsearch初识-简单增删改查及复杂排序,分页,聚合操作
前面大概了解了一下elasticsearch的数据存储和数据的查询.现在学习一下,es的复杂操作. 官网相关文档地址:https://www.elastic.co/guide/en/e ...
- MongoDB下载安装与简单增删改查
Windows下MongoDB的安装和配置.启动和停止 下载地址:MongoDB的官方下载网址是:https://www.mongodb.org/downloads 安装步骤1. 点击下载的mongo ...
- mongoTemplate简单用法(增删改查)
分页时查找数量: public long countSample(String id) { Query query = new Query(); if (StringUtil.hasText(id)) ...
随机推荐
- Python之网络模型与图形绘制工具networkx
笔记 # https://www.jianshu.com/p/e543dc63454f import networkx as nx import matplotlib.pyplot as plt ## ...
- c++空类为什么占用1个字符
在C++中空类会占一个字节,这是为了让对象的实例能够相互区别.具体来说,空类同样可以被实例化,并且每个实例在内存中都有独一无二的地址,因此,编译器会给空类隐含加上一个字节,这样空类实例化之后就会拥有独 ...
- Swift的if let和guard let的使用 <一看就懂哟>
// // ViewController.swift // 可选项的判断 // // Created by 思 彭 on 16/9/16. // Copyright © 2016年 思 彭. All ...
- 【052-week 预习周】学习总结
目录 学习手册 学习理念 学员精选 课前准备 概览 数据结构思维导图 算法思维导图 学习手册 学习理念 让优秀的人一起学习 师傅领进门,修行靠个人 学员精选 稻盛和夫"六项精进" ...
- day18 time、datetime、calendar、sys、os、os.path模块
今日内容 时间模块 time模块 datetime模块 calendar模块 系统模块 sys模块 os模块 os.path模块 time模块: 在 time 模块中使用最多的方法有: time() ...
- Linux正则表达式结合三剑客企业级实战
1.取系统ip 解答: 1)ifconfig ens33 |sed -n '2p'|sed "s#inet##g"|sed 's#n.*$##g' 2)ifconfig ens3 ...
- Min swaps to sort array
Given an array with distinct numbers, return an integer indicating the minimum number of swap operat ...
- _variant_t 与其他数据类型的转换
在COM中使用的标准类Class如下所示: _bstr_t:对BSTR类型进行打包,并提供有用的操作方法: _com_error:定义抛出的error对象; _com_ptr_t:封装COM接口指针 ...
- CF 666C & 牛客 36D
给定字符串S, 求有多少长为$n$的字符串T, 使得S为T的子序列. 可以得到转移矩阵为 $\begin{equation}A=\begin{bmatrix}25 & 0 & 0 &a ...
- 开发过程遇到的css样式问题记录
一.移动端 1.部分安卓机圆角border-radius失效,显示为方形状? background-clip: padding-box; 2.部分安卓机字体图标出现锯齿? 使用iconfont图标 ...