springBoot2.3 使用mongoTemplate整合mongoDb

目标

SpringBoot2.3使用mongoTemplate整合mongoDb

前提:

读者需要了解maven, lombok,mongDb

1.pom依赖引入

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.3.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>11</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

2.配置mongodb的连接地址和数据库

本例以本地的test2数据库为例子,且不开启用户认证。mongodb默认是免认证的,可以去设置开启认证: application.properties如下

#最简单的配置就是直接配置mongdb的本地地址和端口号
spring.data.mongodb.host=127.0.0.1
spring.data.mongodb.port=27017
#如果不配置database,则默认使用test数据库
spring.data.mongodb.database=test2

3.创建一个Bean对象

待会会把这个Bean对象的信息存放到mongDb:

@Data
@Document("User")
public class User {
    @Id
    private String id;
    private String name;
    private Integer age;
    private String address;
    private String createDate;
}

4.Service接口

实际上这个接口的所有方法都可以直接放在dao层,看个人习惯,本例子在示例的时候直接加在Service就懒得改了。

/**
 * 使用MongoTemplate接口,基本能够完成增删改查操作,包括批量插入,批量修改,模糊查询,删除所有,删除满足条件的;
 * 查询满足任一条件的数据,查询满足所有条件的数据;分页查询;查询结果排序
 */
public interface UserService {

    /**
     * 新增,插入(不能插入相同id的数据)
     *
     * @param po
     * @return
     */
    User insertOne(User po);

    /**
     * 插入多条
     *
     * @param userList
     * @return
     */
    Collection<User> insertMany(List<User> userList);

    /**
     * 修改,如果id存在则修改,如果id不存在则新增
     *
     * @param po
     * @return
     */
    User update(User po);

    /**
     * 修改
     *
     * @param po
     * @return
     */
    UpdateResult update2(User po, User newPo);

    /**
     * 查询一条(即使是有多条数据也只是返回第一条)
     *
     * @param po
     * @return
     */
    User findOne(User po);

    /**
     * 模糊查询一条(即使是有多条数据也只是返回第一条)
     *
     * @param po
     * @return
     */
    User findOneLike(User po);

    /**
     * 查询多条数据
     *
     * @param po
     * @return
     */
    List<User> findListLike(User po);

    /**
     * 模糊查询2
     *
     * @param po
     * @return
     */
    List<User> findListLike2(User po);

    /**
     * 多查询条件模糊查询3
     *
     * @param po
     * @return
     */
    List<User> findListLike3(User po);
    /**
     * 查询结果排序
     *
     * @param po
     * @return
     */
    List<User> findListSort(User po);

    /**
     * 查询满足任意一个条件的多条数据
     *
     * @param po
     * @return
     */
    List<User> findListAny(User po);


    /**
     * 分页查询
     *
     * @param po
     * @return
     */
    List<User> findListByPage(User po, int page, int size);

    /**
     * 删除所有
     */
    void deleteAll();

    /**
     * 删除指定的对象
     */
    void delete(User po);

    /**
     * 根据id删除
     *
     * @param id
     */
    void deleteById(String id);

    /**
     * 判断是否存在
     *
     * @param po
     * @return
     */
    Boolean exists(User po);
}

5.Service实现类

@Slf4j
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private MongoTemplate mongoTemplate;


    @Override
    public User insertOne(User po) {
        return mongoTemplate.insert(po);
    }


    @Override
    public Collection<User> insertMany(List<User> userList) {
        Collection<User> insert = mongoTemplate.insert(userList, User.class);
        return insert;
    }

    @Override
    public User update(User po) {
        // 如果不存在则新增,存在则修改, 要求所有字段必须有值,且必须有id。否则只会新增
        return mongoTemplate.save(po);
    }

    @Override
    public UpdateResult update2(User po, User newPo) {
        // 如果不存在则新增,存在则修改, 要求所有字段必须有值
        Query query = Query.query(Criteria.byExample(Example.of(po)));
        // 修改address并且设置age字段加1; update还有一些常用的方法对集合进行增加或减少字段,例如增加字符串字段,减少字符字段,增加日期,数值类型的增减
        // 增加字段, 用得比较少,因为一个集合中的对象属性基本都是比较固定的,如果常常变更,则数据难以维护
        //update.addToSet(String key);
        // 删除字段, 用得比较少,因为一个集合中的对象属性基本都是比较固定的,如果常常变更,则数据难以维护
        //update.unset(String key);
        // 添加日期, 用得比较少,因为一个集合中的对象属性基本都是比较固定的,如果常常变更,则数据难以维护
        // update.currentDate(String key);
        // 用得比较多的是数值类型增减inc
        Update update = Update.update("address", newPo.getAddress()).inc("age", 1);
        // updateFirst方法只对匹配到的第一条数据进行修改
        //mongoTemplate.updateFirst(query, update, User.class)
        // updateMulti对匹配到的多条数据都进行修改
        UpdateResult updateResult = mongoTemplate.updateMulti(query, update, User.class);
        // 返回匹配的条数
        //updateResult.getMatchedCount();
        // 返回修改的条数
        ///updateResult.getModifiedCount();
        return updateResult;
    }

    @Override
    public User findOne(User po) {
        // 构造example对象
        Example<User> example = Example.of(po);
        // 构造Criteria对象
        Criteria criteria = Criteria.byExample(example);
        // 构造Query查询对象
        Query query = Query.query(criteria);
        // 查单条数据
        User user = mongoTemplate.findOne(query, User.class);
        return user;
    }

    @Override
    public User findOneLike(User po) {
        // 改变查询模式,改为模糊查询name为包含,address为以什么结尾,其他字段仍然是精确查询
        ExampleMatcher exampleMatcher = ExampleMatcher.matching().withMatcher("name", ExampleMatcher.GenericPropertyMatchers.contains())
                .withMatcher("address", ExampleMatcher.GenericPropertyMatchers.endsWith());
//        ExampleMatcher.matching().withMatcher()
        // 构造example对象
        Example<User> example = Example.of(po, exampleMatcher);
        // 构造Criteria对象
        Criteria criteria = Criteria.byExample(example);
        // 构造Query查询对象
        Query query = Query.query(criteria);
        // 查单条数据
        User user = mongoTemplate.findOne(query, User.class);
        return user;
    }

    @Override
    public List<User> findListLike(User po) {
        ExampleMatcher exampleMatcher = ExampleMatcher.matching().withMatcher("name", ExampleMatcher.GenericPropertyMatchers.contains())
                .withMatcher("address", ExampleMatcher.GenericPropertyMatchers.contains());
        // 构造example对象
        Example<User> example = Example.of(po, exampleMatcher);
        Query query = Query.query(Criteria.byExample(example));
        return mongoTemplate.find(query, User.class);
    }

    @Override
    public List<User> findListLike2(User po) {
        // 改变默认字符串匹配方式:直接把精确查询改为模糊查询
        // 必须是ExampleMatcher.matching().withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING);的方式写,
        // 不能分开写成ExampleMatcher matcher = ExampleMatcher.matching(); matcher.withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING);

        ExampleMatcher matcher = ExampleMatcher.matching()
                .withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING);

        Example<User> example = Example.of(po, matcher);
        Query query = Query.query(Criteria.byExample(example));
        return mongoTemplate.find(query, User.class);
    }

    @Override
    public List<User> findListLike3(User po) {
        // 改变默认字符串匹配方式:直接把精确查询改为模糊查询
        // 必须是ExampleMatcher.matching().withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING);的方式写,
        // 不能分开写成ExampleMatcher matcher = ExampleMatcher.matching(); matcher.withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING);

        ExampleMatcher matcher = ExampleMatcher.matching()
                .withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING);

        Example<User> example = Example.of(po, matcher);
        //构造多查询条件
        /**
         * 说明byExample 生成的Criteria如果再接了where和and之后,查询结果则无法查询出example的过滤数据
         * 如Criteria criteria = Criteria.byExample(example).where("age").gt(39) 只能查询出age大于39的数据,而其他字段的过滤则不再生效
         */
        //Criteria criteria = Criteria.byExample(example);
//                .where("age").gt(39);
        // 例子1:查询age大于39且name = po.getName的数据 ,这个写法可以
       // Criteria criteria = Criteria.where("age").gt(39).and("name").is(po.getName());
        // 例子2: 查询age大于39且name = po.getName的数据 ,这个写法可以
        Criteria criteria = new Criteria().andOperator(Criteria.where("age").gt(39), Criteria.where("name").is(po.getName()));
        // 例子3:查询age大于39或name = po.getName的数据 , 这个写法不行
        //Criteria criteria = Criteria.where("age").gt(39).orOperator(Criteria.where("name").is(po.getName()));
        // 例子4:查询age大于39或name = po.getName的数据 , 这个写法可以
        //Criteria criteria = new Criteria().orOperator(Criteria.where("age").gt(39), Criteria.where("name").is(po.getName()));

        // 例子5:查询姓名为张三并且年龄为18岁或者姓名为李四年龄为20的用户
        /*Criteria and1 = new Criteria();
        and1.andOperator(Criteria.where("name").is("张三"),Criteria.where("age").is(18));
        Criteria and2 = new Criteria();
        and2.andOperator(Criteria.where("name").is("李四"),Criteria.where("age").is(20));

        Criteria c = new Criteria();
        c.orOperator(and1,and2);*/

        Query query = Query.query(criteria);
        return mongoTemplate.find(query, User.class);
    }

    @Override
    public List<User> findListSort(User po) {
        // 设置为模糊查询
        ExampleMatcher matcher = ExampleMatcher.matching()
                .withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING);
        Example<User> example = Example.of(po, matcher);
        // 设置排序规则
        Sort sort = Sort.by(Sort.Direction.DESC, "address");
        Query query = Query.query(Criteria.byExample(example)).with(sort);
        return mongoTemplate.find(query, User.class);
    }

    @Override
    public List<User> findListAny(User po) {
        // 设置为或模式,默认是且模式,或表示查询条件中的任意一个条件满足都返回。是指不同的查询字段,而不是同一个字段的不同值
        ExampleMatcher matcher = ExampleMatcher.matchingAny()
                .withMatcher("address", ExampleMatcher.GenericPropertyMatchers.contains());
        Example<User> example = Example.of(po, matcher);
        Query query = Query.query(Criteria.byExample(example));
        return mongoTemplate.find(query, User.class);
    }


    @Override
    public List<User> findListByPage(User po, int page, int size) {
        // 改为模糊查询
        ExampleMatcher matcher = ExampleMatcher.matching()
                .withMatcher("name", ExampleMatcher.GenericPropertyMatchers.contains())
                .withMatcher("address", ExampleMatcher.GenericPropertyMatchers.contains());

        // 测试2: 不写name时,默认应该是精确查询的
        /*ExampleMatcher matcher = ExampleMatcher.matching()
                .withMatcher("address", ExampleMatcher.GenericPropertyMatchers.endsWith());*/
        Example<User> example = Example.of(po, matcher);
        Criteria criteria = Criteria.byExample(example);
        // 构造分页对象
        Pageable pageable = PageRequest.of(page, size);
        // 构造分页对象,带排序规则
//        Pageable pageable = PageRequest.of(page, size, Sort.Direction.DESC, "title");
//        Sort sort = Sort.by(Sort.Direction.DESC, "address");
        // 不带排序规则
        Query query = Query.query(criteria).with(pageable);
        // 分页查询
        List<User> users = mongoTemplate.find(query, User.class);
        return users;

    }

    @Override
    public void deleteAll() {
        mongoTemplate.remove(User.class);

    }

    @Override
    public void delete(User po) {
        // 构建query对象
        Query query = Query.query(Criteria.byExample(Example.of(po)));
        // 根据query查询条件进行删除
        mongoTemplate.remove(query, User.class);
    }

    @Override
    public void deleteById(String id) {
        Query query = Query.query(Criteria.where("id").is(id));
        mongoTemplate.remove(query, User.class);
    }

    @Override
    public Boolean exists(User po) {
        Example<User> of = Example.of(po);
        Query query = Query.query(Criteria.byExample(of));
        return mongoTemplate.exists(query, User.class);
    }
}

6.测试

使用SpringBootTest进行测试,lombok记录日志

@Slf4j
@SpringBootTest
public class UserTest {
    @Autowired
    private UserService userService;

    @Test
    public void testInsert() {
        User po = new User();
        po.setName("张三");
        po.setAddress("广州");
        po.setAge(39);
        po.setCreateDate("1991-06-22");
        User user = userService.insertOne(po);
        log.info("【新增用户】user:{}", user);
    }

    @Test
    public void testInsertMany() {
        List<User> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            User po = new User();
            po.setName("李四" + i);
            po.setAddress("广州" + i);
            po.setAge(33 + i);
            po.setCreateDate("1991-06-22");
            list.add(po);
        }
        Collection<User> users = userService.insertMany(list);
        log.info("【新增用户】user:{}", users);
    }
    
    @Test
    public void testUpdate() {
        User po = new User();
        po.setName("李四0");
        User one = userService.findOne(po);
        one.setAddress("李四的深圳住所22");
        User update = userService.update(one);
        log.info("【修改用户】修改用户: {}", update);
    }
    
    @Test
    public void testUpdate2() {
        User po = new User();
        po.setName("李四4");
        User newPo = new User();
        newPo.setAddress("李四的深圳住所4");
        UpdateResult updateResult = userService.update2(po, newPo);
        log.info("【修改用户】匹配用户数:{},修改用户数: {}", updateResult.getMatchedCount(), updateResult.getModifiedCount());
    }

    @Test
    public void testIFindOne() {
        User po = new User();
        po.setName("李四0");
        //po.setAge(34);
            /*po.setAddress("广州");
            po.setAge(33);
            po.setCreateDate("1991-06-22");*/
        User user = userService.findOne(po);
        log.info("【查询用户】user:{}", user);
    }

    @Test
    public void testIFindOneLike() {
        User po = new User();
        // 模糊查询
        po.setAddress("广州");
        User user = userService.findOneLike(po);
        log.info("【查询用户】user:{}", user);
    }

    @Test
    public void testFindListLike() {
        User po = new User();
        // 模糊查询地址包含广州的数据
        po.setAddress("广州");
        List<User> list = userService.findListLike(po);
        log.info("【查询用户】user:{}", list);
    }

    @Test
    public void testFindListLike2() {
        User po = new User();
        // 模糊查询地址包含广州的数据
        po.setName("李");
        List<User> list = userService.findListLike2(po);
        log.info("【查询用户】user:{}", list);
    }

    @Test
    public void testFindListLike3() {
        User po = new User();
        // 模糊查询地址包含广州的数据
        po.setName("李四8");
        List<User> list = userService.findListLike3(po);
        log.info("【查询用户】user:{}", list);
    }

    @Test
    public void testFindListSort() {
        User po = new User();
        // 模糊查询地址包含广州的数据
        po.setName("李");
        List<User> list = userService.findListSort(po);
        log.info("【查询用户】user:{}", list);
    }

    @Test
    public void testFindListAny() {
        User po = new User();
        // 模糊查询地址包含广州的数据
        po.setAddress("广州");
        po.setName("李四0");
        List<User> list = userService.findListAny(po);
        log.info("【查询用户】user:{}", list);
    }
    
    @Test
    public void testFindListByPage() {
        User po = new User();
        // 模糊查询地址包含广州的数据
        po.setAddress("广州");
        po.setName("李");
        int page = 0;
        int size = 3;
        List<User> list = userService.findListByPage(po,page, size);
        log.info("【查询用户】user:{}", list);
    }

    @Test
    public void testDelete() {
        User po = new User();
        // 模糊查询地址包含广州的数据
        po.setName("李四0");
        userService.delete(po);
        log.info("【查询用户】user:{}", po);
    }

    @Test
    public void testDeleteById() {
        User po = new User();
        // 模糊查询地址包含广州的数据
        po.setName("张三");
        User one = userService.findOne(po);
        userService.deleteById(one.getId());
        log.info("【查询用户】user:{}", po);
    }

    @Test
    public void testExists() {
        User po = new User();
        // 模糊查询地址包含广州的数据
        po.setName("李四0");
        Boolean exists = userService.exists(po);
        log.info("【查询用户是否存在】user:{}", exists);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值