1、docker 安装

  docker run -d -p 27017:27017 --name mongo mongo:latest

2、自定义数据库并创建用户

  进入操作界面

docker exec -it mongo mongo xiufengd

  查看现有角色

show roles;

  创建相应角色用户

db.createUser({user:'admin',pwd:'admin',roles:[{role:"dbAdmin",db:"xiufengd"}]});

  也可以用其他库例如admin的角色来创建用户

db.createUser({user:'admin',pwd:'admin',roles:[{role:"userAdminAnyDatabase",db:"admin"}]});

3、springboot集成测试

  3.1 引包

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
            <version>2.7.1</version>
        </dependency>

        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-all</artifactId>
            <version>5.8.4</version>
        </dependency>

  3.2 yml文件

spring:
  data:
    mongodb:
    #uri: mongodb://xiufengd:xiufengd@152.136.15.119:27017/test
    host: 152.136.15.119
    port: 27017
    database: test
    authentication-database: xiufengd
    username: xiufengd
    password: xiufengd

  3.3 新建实体类

package com.example.mongodbtest.dao;

import cn.hutool.core.date.DateTime;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

import java.util.Date;

/**
 * @author xiufengd
 * @date 2022/7/5 17:07
 * 未来可期
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
// 用Document 表明库中存储的集合名 若缺失则集合名=类名
@Document("test_bean")
public class TestBean {
    /**
     * 文章id
     */
    @Id
    private Long id;

    /**
     * 用户ID
     */
    private Long userId;

    /**
     * 文章标题
     */
    private String title;

    /**
     * 文章内容
     */
    private String content;

    /**
     * 创建时间
     */
    private Date createTime;

    /**
     * 更新时间
     */
    private Date updateTime;

    /**
     * 点赞数量
     */
    private Long thumbUp;

    /**
     * 访客数量
     */
    private Long visits;

    public TestBean(long id, long userId, String title, String content, DateTime createTime, DateTime updateTime, long thumbUp, long visits) {
        this.id=id;
        this.userId = userId;
        this.title=title;
        this.content=content;
        this.createTime = createTime;
        this.updateTime = updateTime;
        this.thumbUp = thumbUp;
        this.visits = visits;
    }
}

  3.4 持久层 

package com.example.mongodbtest.service;


import com.example.mongodbtest.dao.TestBean;
import org.springframework.data.mongodb.repository.MongoRepository;

/**
 * @author xiufengd
 * @date 2022/7/5 17:50
 * 未来可期
 */
public interface ArticleRepository extends MongoRepository<TestBean, Long> {
}

  3.5 测试类

package com.example.mongodbtest;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.json.JSONUtil;
import com.example.mongodbtest.dao.TestBean;
import com.example.mongodbtest.service.ArticleRepository;
import lombok.extern.slf4j.Slf4j;
import org.assertj.core.util.Lists;
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.*;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.test.context.junit4.SpringRunner;

import java.text.ParseException;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author xiufengd
 * @date 2022/7/5 18:09
 * 未来可期
 */
@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class ArticleRepositoryTest {
    @Autowired
    private ArticleRepository articleRepo;

    @Autowired
    private MongoTemplate mongoTemplate;

    private static Snowflake snowflake = IdUtil.createSnowflake(2, 1);


    /**
     * 测试新增
     */
    @Test
    public void testSave() {
        TestBean article = new TestBean(1L,2L, RandomUtil.randomString(20), RandomUtil.randomString(150), DateUtil.date(), DateUtil.date(), 0L, 0L);
        articleRepo.save(article);
        // 根据ID属性进行新增或更新
        mongoTemplate.save(article);
        log.info("【article】= {}", JSONUtil.toJsonStr(article));
    }

    /**
     * 测试批量新增列表
     */
    @Test
    public void testSaveList() {
        List<TestBean> articles = Lists.newArrayList();
        for (int i = 0; i < 10; i++) {
            articles.add(new TestBean(i+1,snowflake.nextId(), RandomUtil.randomString(20), RandomUtil.randomString(150), DateUtil.date(), DateUtil.date(), 0L, 0L));
        }
        articleRepo.saveAll(articles);

        log.info("【articles】= {}", JSONUtil.toJsonStr(articles.stream().map(TestBean->TestBean.getId()).collect(Collectors.toList())));
    }

    /**
     * 测试更新
     */
    @Test
    public void testUpdate() {
        articleRepo.findById(1L).ifPresent(article -> {
            article.setTitle(article.getTitle() + "更新之后的标题");
            article.setUpdateTime(DateUtil.date());
            articleRepo.save(article);
            log.info("【article】= {}", JSONUtil.toJsonStr(article));
        });
    }

    /**
     * 测试删除
     */
    @Test
    public void testDelete() {
        // 根据主键删除
        articleRepo.deleteById(1L);

        // 全部删除
        articleRepo.deleteAll();
    }

    /**
     * 测试分页排序查询
     */
    @Test
    public void testQuery() throws ParseException {
        Pageable pageable = Pageable.ofSize(2).withPage(0);
        Sort sort = Sort.by("thumbUp", "updateTime").descending().and(Sort.by("title").ascending());
        PageRequest pageRequest = PageRequest.of(0, 5, sort);
        Page<TestBean> page = articleRepo.findAll(pageable);
        List<String> collect = page.getContent().stream().map(e -> JSONUtil.toJsonStr(e)).collect(Collectors.toList());
        collect.forEach(e-> System.out.println("------------------"+e));
    }

    @Test
    public void update(){
        articleRepo.findById(1L).ifPresent(e->{
            e.setTitle("test11111");
            articleRepo.save(e);
        });
    }
  @Test
public void otherUpdate(){
Query query = new Query();
query.addCriteria(Criteria.where("_id").is(1L));
Update update = new Update();
update.inc("thumbUp",1L);
mongoTemplate.updateFirst(query,update,"test_bean");
}

@Test
public void query(){
TestBean testBean = TestBean.builder()
.title("kfbumyywyfjjx484nj8i")
.content("auich2ajagflg")
.build();
ExampleMatcher withMatcher = ExampleMatcher.matching()
// 忽略大小写
.withIgnoreCase()
// 指定"title"为精确匹配
.withMatcher("title", ExampleMatcher.GenericPropertyMatcher::exact)
// 指定"content"为模糊匹配
.withMatcher("content", ExampleMatcher.GenericPropertyMatcher::contains);
Example<TestBean> example = Example.of(testBean,withMatcher);

/**
* 排序规则
*/
Sort sort = Sort.by("updateTime").descending();

/**
* 分页
*/
PageRequest pageRequest = PageRequest.of(0, 5, sort);

/**
* 分页查询
*/
Page<TestBean> articleRepoAll = articleRepo.findAll(example, pageRequest);

/**
* 打印
*/
log.info("-------------------------"+JSONUtil.toJsonStr(articleRepoAll.getContent()));
}

@Test
public void templateQuery(){
Criteria criteria = Criteria
/**
* 精确匹配
* 等同于 where title = "e0pekgbb6r7ugtz81pxb"
*/
.where("title").is("e0pekgbb6r7ugtz81pxb")
/**
* 模糊匹配, 用正则: .*[xxx].*
* 等同于 and content like "%l1moc1%"
*/
.and("content").regex(".*l1moc1.*")
/**
* 匹配明细里的字段
* 当字段值为数组时(必须是数组,不能是数组字符串),匹配数组元素的值
* e.g. content值为 {"name":"11", "age":27}, {"name":"12", "age":23}, {"name":"13", "age":21}]的数组时
* 等同于 and content.name="111" 注意 content的类型必须是数组 list
*/
.and("content").elemMatch(Criteria.where("name").is("111"))
/**
* 匹配多个并行
* 等同于 and ( ((visits = null) or (visits = 1))and ((thumbUp = null) or (thumbUp = 1)))
* andOperator 或者 orOperator 只得都是内部条件之间的关系,最外层都是and关系
*/
.andOperator(
new Criteria().orOperator(
Criteria.where("visits").exists(false),
Criteria.where("visits").is(1)
),
new Criteria().orOperator(
Criteria.where("thumbUp").exists(false),
Criteria.where("thumbUp").is(1)
)
);
/**
* 排序规则
* Sort 遵循从左到右的排序顺序
* e.g. .sort({"updateTime":-1},{"thumbUp":-1});
* 等同于 order by updateTime desc , thumbUp desc
*/
Sort sort = Sort.by("updateTime","thumbUp").descending();
/**
* 分页 page从0开始 每页5个
* 等同于 limit 0,5
*/
PageRequest pageRequest = PageRequest.of(0, 5, sort);

Query query = Query.query(criteria).with(sort).with(pageRequest);

List<TestBean> articles = mongoTemplate.find(query, TestBean.class);
PageImpl<TestBean> page = (PageImpl<TestBean>) PageableExecutionUtils.getPage(articles,
pageRequest,()-> mongoTemplate.count(Query.query(criteria),TestBean.class));

// 打印
Optional.of(page.getContent()).ifPresent(testBean -> {
articles.forEach(testBean1 -> {
log.info("打印数据:{}",JSONUtil.toJsonStr(testBean1));
});
});
}
}

 4、遇到问题

  4.1 字段内容过长,超过16M,此时要用文件形式单独存储,用gridFsTemplate

public boolean updateMongo(MongoBean mongoBean) {
        Boolean isSuccess = Boolean.FALSE;
        Query query = Query.query(Criteria.where("id").is(mongoBean.getId()).and("code").is(mongoBean.getCode()));
        Update update = Update.update("utime", mongoBean.getUtime());
        if (StringUtils.isNotBlank(mongoBean.getJson())) {
            gridFsTemplate.delete(Query.query(Criteria.where("filename").is(mongoBean.getId() + "_" + mongoBean.getCode())));
            ObjectId objectId = gridFsTemplate.store(new ByteArrayInputStream(mongoBean.getJson().getBytes(StandardCharsets.UTF_8)), mongoBean.getId() + "_" + mongoBean.getCode()); //自定义文件名
            update.set("json", objectId.toString());
        }
        UpdateResult updateResult = mongoTemplate.updateMulti(query, update, MongoBean.class);
        if (updateResult.getModifiedCount() > 0) {
            isSuccess = Boolean.TRUE;
        }
        return isSuccess;
    }

   4.2 查询文件存储的信息

public String queryMongoWithResult(String id, String code) {
        if (id == null || code == null) {
            return null;
        }
        try {
            Criteria criteria = Criteria.where("filename").is(id + "_" + code); //自定义的文件名
            Query query = Query.query(criteria);
            GridFSFile gridfsFile = gridFsTemplate.findOne(query);
            GridFsResource resource = gridFsTemplate.getResource(gridfsFile);
            String result = new BufferedReader(new InputStreamReader(resource.getInputStream())).lines().collect(Collectors.joining());
            return result;
        } catch (Exception e) {
            log.info("获取数异常"+e);
        }

        return null;
    }

 

 

  

  

posted on 2022-07-06 18:07  程序员丁先生  阅读(58)  评论(0编辑  收藏  举报