SpringDataMongoDB是SpringData家族成员之一,底层封装了mongodb-driver。

创建一个SpringBoot工程, 引入SpringDataMongoDB依赖。

  • jdk14, SpringBoot2.4.5
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

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

一、简单CRUD操作

在配置文件中连接 MongoDB服务,这里有用户安全认证(下面两个用户都可用)。

spring:
  data:
    mongodb:
      # 超级管理员是必须指定?后面的固定写法
      uri: mongodb://mongoroot:密码@127.0.0.1:27017/m_db3?authSource=admin&authMechanism=SCRAM-SHA-1
      # 普通用户不能指定?后面的固定写法
      # uri: mongodb://luna1:密码@127.0.0.1:27017/m_db3

1、 实体类

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.index.CompoundIndex;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;

import java.io.Serializable;
import java.util.Date;

@Document("user")
@CompoundIndex(def = "{'id':1, 'age': -1}")
public class User implements Serializable {
    @Id
    private String id;
    
    @Field("name")
    @Indexed
    private String name;

    private Integer age;  
    
    private Integer sex;

	@Indexed(name = "index_createdTime", direction = IndexDirection.DESCENDING)
    private Date createdTime;

    private String address;

    private Integer state;

    /**
     * 关注者数量
     */
    private Integer followNum;
    
    ... getter/setter
}    

常用注解如下:

  • @Id - 用于字段级别,标记这个字段是一个主键,默认生成的名称是“_id”

  • @Document - 用于类,以表示这个类需要映射到数据库,您也可以指定映射到数据库的集合名称

  • @DBRef - 用于字段,以表示它将使用com.mongodb.DBRef进行存储

  • @Indexed - 用于字段,表示该字段需要如何创建索引

  • @CompoundIndex - 用于类,以声明复合索引

  • @GeoSpatialIndexed - 用于字段,进行地理位置索引

  • @TextIndexed - 用于字段,标记该字段要包含在文本索引中

  • @Language - 用于字段,以设置文本索引的语言覆盖属性。

  • @Transient - 默认情况下,所有私有字段都映射到文档,此注解将会去除此字段的映射

  • @PersistenceConstructor - 标记一个给定的构造函数,即使是一个protected修饰的,在从数据库实例化对象时使用。构造函数参数通过名称映射到检索的DBObject中的键值。

  • @Value - 这个注解是Spring框架的一部分。在映射框架内,它可以应用于构造函数参数。这允许您使用Spring表达式语言语句来转换在数据库中检索的键值,然后再用它来构造一个域对象。为了引用给定文档的属性,必须使用以下表达式:@Value("#root.myProperty"),root要指向给定文档的根。

  • @Field - 用于字段,并描述字段的名称,因为它将在MongoDB BSON文档中表示,允许名称与该类的字段名不同。

  • @Version - 用于字段锁定,保存操作时检查修改。初始值是0,每次更新时自动触发。

2、dao层

/**
 * 继承MongoRepository,指定实体和主键的类型作为泛型
 *
 */
public interface UserRepository extends MongoRepository<User, String> {
}

MongoRepository接口及其子类SimpleMongoRepository,提供了一些CRUD常用方法。

3、service层

@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    /**
     * 保存
     *
     * @param user
     */
    public void save(User user) {
        userRepository.save(user);
    }

    /**
     * 更新
     *
     * @param user
     */
    public void update(User user) {
        userRepository.save(user);
    }

    /**
     * 根据id删除
     *
     * @param id
     */
    public void deleteById(String id) {
        userRepository.deleteById(id);
    }

    /**
     * 查询所有
     *
     * @return
     */
    public List<User> findAll() {
        return userRepository.findAll();
    }

    /**
     * 根据id查询
     *
     * @param id
     * @return
     */
    public User findById(String id) {
        return userRepository.findById(id).get();
    }

}

4、单元测试

	@Autowired
	private UserService userService;


	@Test
	public void testSave() {
		User user = new User();
		user.setAge(10);
		user.setSex(1);
		user.setName("鲁班");
		user.setState(1);
		user.setFollowNum(0);
		user.setAddress("峡谷射手位");
		user.setCreatedTime(new Date());
		userService.save(user);
	}

	@Test
	public void testUpdate() {
		User user = new User();
		user.setId("60920480cbb9605ddb8408e6");
		user.setAge(18);
		user.setSex(1);
		user.setName("蔡文姬");
		user.setState(1);
		user.setFollowNum(0);
		user.setAddress("峡谷奶妈");
		user.setCreatedTime(new Date());
		userService.update(user);
	}

	@Test
	public void testFindAll() {
		List<User> userList = userService.findAll();
		System.out.println(userList);
	}

	@Test
	public void testFindById() {
		User user = userService.findById("60920480cbb9605ddb8408e6");
		System.out.println(user);
	}
	
	@Test
	public void testDelete() {
		userService.deleteById("60920489ae642306a39bc958");
	}

在这里插入图片描述

二、使用JPA规范查询

在这里插入图片描述
按照 JPA语法来写就ok。测试一个。

    /**
     * 根据 age和sex查询
     * @param age
     * @param sex
     * @return
     */
    List<User> findByAgeGreaterThanEqualAndSexEquals(Integer age, Integer sex);

在这里插入图片描述

三、使用MongoTemplate操作

1、字段自增一

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.data.mongodb.core.query.Update;

    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 将 followNum字段值加1
     * @param id
     */
    public void incrFollowNumCount(String id){
        // 创建 Query对象
        Query query = new Query(Criteria.where("_id").is(id));
        // 创建更新对象
        Update update = new Update();
        update.inc("followNum");
        // 执行update
        mongoTemplate.updateFirst(query, update, User.class);
    }

在这里插入图片描述

2、分页查询

分页涉及两个类:Page和Pageable

2.1 使用JPA分页

dao层

    /**
     * 根据年龄分页查询
     *
     * @param age
     * @param pageable
     * @return
     */
    Page<User> findByAge(Integer age, Pageable pageable);

service层

    /**
     * 根据名称分页查询
     *
     * @param age
     * @param page
     * @param size
     * @return
     */
    public Page<User> findByAgePage(Integer age, int page, int size) {
        // 构造分页对象
        PageRequest pageRequest = PageRequest.of(page - 1, size);
        return userRepository.findByAge(age, pageRequest);
    }

测试
在这里插入图片描述

2.2 使用MongoTemplate分页

MongoTemplate使用更丰富,可针对不同的需求。

service层

    /**
     * 使用MongoTemplate分页查询
     *
     * @param page
     * @param size
     * @param user
     * @return
     */
    public List<User> findPageByTemplate(int page, int size, User user) {
        // 构造一个查询对象
        Query query = new Query();
        long count = mongoTemplate.count(query, User.class);
        System.out.println("===总数===" + count);

        // 设置参数
        if (!StringUtils.isEmpty(user.getName())) {
            query.addCriteria(Criteria.where("name").regex(user.getName() + ".*"));
        }
        if (user.getAge() != null) {
            query.addCriteria(Criteria.where("age").gte(user.getAge()));
        }
        if (user.getSex() != null) {
            query.addCriteria(Criteria.where("sex").is(user.getSex()));
        }
        // 跳过多少条
        query.skip((page - 1) * size);
        // 取出多少条
        query.limit(size);
        // 构造排序对象
        Sort.Order order = new Sort.Order(Sort.Direction.DESC, "age");
        // 设置排序对象
        query.with(Sort.by(order));
        List<User> users = mongoTemplate.find(query, User.class);
        return users;
    }

测试
在这里插入图片描述

到此,使用 Java操作MongoDB就算入门了,更多操作在项目中灵活使用。

Stay Hungry, Stay Foolish. 求知若饥,虚心若愚。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐