• 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}}}}
        }
    
  • 相关阅读:
    git使用记录
    【转】话说我打算一天学完object c语法,系列1--------来自书Objective-c程序设计
    【转】看源代码那些事
    中英文对照 —— 数学定律定理(公式及其描述)
    CUDA+OpenGL混合编程
    简明欧洲史
    简明欧洲史
    CUDA一维纹理内存
    CUDA中的常量内存__constant__
    CUDA线程协作之共享存储器“__shared__”&&“__syncthreads()”
  • 原文地址:https://www.cnblogs.com/taopanfeng/p/11684880.html
Copyright © 2020-2023  润新知