springBoot整和mongodb
一,springboot整合mongodb
如需转载,请标明出处:https://zhenghuisheng.blog.csdn.net/article/details/139704356
此篇主要讲解在java中,如何通过springboot项目去操作mongodb,如何创建springboot项目此处省略
1,依赖加入
在pom文件中,加入对应的依赖,版本需要于springboot的版本对应
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
<version>2.3.9.RELEASE</version>
</dependency>
2,yml文件配置
首先进入配置阶段,在yml配置文件中加入以下配置,如果在安装之后的auth设置为false,那么不需要账号密码也能直接访问
spring:
data:
mongodb:
host: xxx.xxx.xxx.xxx
port: 27017
username: zhs
password: 'zhs123456'
database: archive
authentication-database: admin
也可以用下面这种方式,uri方式和上面的参数不要重复,只能只使用一种,推荐使用上面这种,可读性强
spring:
data:
mongodb:
uri: "mongodb://zhs:zhs123456@xxx.xxx.xxx.xxx:27017/archive"
3,_class 字段过滤(可选)
在实体类数据存入到mongodb时,会将这个 _class 实体类对应的类全路径也存到mongodb中,我这边不需要这个数据,几亿条数据都加一个这个实体类对象,除了占磁盘之外毫无意义,因此我这边选择将这个字段去掉,定义一个MongoConfig实体类,再注入到容器中即可
@Configuration
public class MongoConfig implements ApplicationListener<ContextRefreshedEvent> {
@Resource
MongoTemplate oneMongoTemplate;
private static final String TYPEKEY = "_class";
@Override
public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
MongoConverter converter = oneMongoTemplate.getConverter();
if (converter.getTypeMapper().isTypeKey(TYPEKEY)) {
((MappingMongoConverter) converter).setTypeMapper(new DefaultMongoTypeMapper(null));
}
}
}
4,实体类定义
接下来定义一个User实体类作为测试用,通过这个Field注解实现实体类字段和mongodb的字段相关联,mongodb不需要像mysql一样需要提前建表,建好实体类就可以对mongodb中的集合进行操作了,User实体类就会对应Mongodb中的一个集合,相当于mysql的一张表,每条数据就是一个文档,每个文档大小限制16m
@Data
public class User {
@Field("_id")
private String id;
@Field("username")
private String username;
@Field("password")
private String password;
//更新时间
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Field("updatedTime")
private Date updatedTime;
//创建时间
@Field("createdTime")
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
private Date createdTime;
}
5,索引创建
都使用mongodb了,后期数据量肯定是非常大的,不然也不可能考虑使用这个玩意儿。因此在文档建好之后,最好提前把索引建上。这里直接选择使用username 和 password作为唯一的联合索引。索引的建立根据实际业务考虑,不能确定是唯一就建普通索引
//user表示哪个集合
db.user.createIndex({username: 1,password:1}, {unique: true})
6,数据插入
mongodb有两种方法实现数据插入,一种是直接使用insert或者insertAll的方式插入,另一种是通过save的方式插入数据
6.1,insert方式
如果直接选择insert的方式插入数据,那么他会判断数据库中是否有这条数据,如通过id判断,如果已经有id为1的用户,再次插入id为1的用户数据时,那么就会直接抛一个异常出来,并且会让整个操作失败。代码如下,如果没有设置id,那么mongodb会自动设置一个唯一的uuid作为id,我这边直接使用一个雪花算法生成的id
User user = new User();
user.setId(SnowflakeUtils.nextId()); //该工具类需要自行生成,可百度
user.setUsername("zhs");
user.setPassword("123456");
user.setCreatedTime(new Date());
user.setUpdatedTime(new Date());
mongoTemplate.insert(user);
也可以直接使用一个批量插入的方式将数据插入,这样将多次io直接转换成1次io,效率更高
List<User> list = new ArrayList<>();
User user = new User();
...
list.add(user);
mongoTemplate.insertAll(list);
6.2,使用save的方式实现
整体操作和insert的一样,在数据插入时使用save方法。使用save方法可以让整体变得更加灵活,insert在集合中已经存在的文档id再插入时会直接抛出异常,但是save不会,会直接进行更新的操作,如果数据不存在则会插入操作。但是在此期间,每次save时需要遍历全部数据,判断数据是否存在,在效率上是远远不及这个insert的
User user = new User();
user.setId(SnowflakeUtils.nextId()); //该工具类需要自行生成,可百度
user.setUsername("zhs");
user.setPassword("123456");
user.setCreatedTime(new Date());
user.setUpdatedTime(new Date());
mongoTemplate.save(user);
综上所述,最好就是每次自定义的生成一个唯一id,然后使用insert去操作数据
7,数据更新
7.1,update普通方式更新
数据更新的方式如下,如果只需要更新一条数据,如下面代码。上面我根据username和password建立了唯一索引,因此只需要updateFirst更新一条数据即可
Query query = new Query();
query.addCriteria(Criteria.where("username").is("zhs"));
query.addCriteria(Criteria.where("password").is("zhs123456"));
Update update = new Update().set("password","zhs12345678");
mongoTemplate.updateFirst(query,update, User.class);
也可以通过这个updateMulti实现多条数据的更新,如下面将所有用户名为zhs的更新时间修改
Query query = new Query();
query.addCriteria(Criteria.where("username").is("zhs"));
Update update = new Update().set("updatedTime",new Date());
mongoTemplate.updateMulti(query,update,User.class);
7.2,BulkOperations 方式更新
上面这些事针对同一个where条件的,也可以针对不同更新文档实现批量更新,这里可以使用 BulkOperations 操作。如更新名为 zhs的密码为 zhs12345678,更新名为 zhsqaq 的密码为 zhsqaq12345678 ,总而言之就是将多条毫无关联的的更新语句一次更新完成
//创建一个BulkOperations实例
BulkOperations updateBulkOps = mongoTemplate.bulkOps(BulkOperations.BulkMode.UNORDERED, "User");
创建完这个 BulkOperations 实例之后,接下来就是可以去创建多条更新语句,随后在构建完的查询与句话中,调用这个updateBulkOps.updateOne方法,再最后调用这个excute方法,将这些全部聚合的更新操作全部执行
//构建查询条件1
Query query1 = new Query();
query1.addCriteria(Criteria.where("username").is("zhs"));
query1.addCriteria(Criteria.where("password").is("zhs123456"));
Update update1 = new Update().set("password","zhs12345678");
updateBulkOps.updateOne(query1,update1);
//构建查询条件2
Query query2 = new Query();
query2.addCriteria(Criteria.where("username").is("zhsqaq"));
query2.addCriteria(Criteria.where("password").is("zhsqaq123456"));
Update update2 = new Update().set("password","zhsqaq12345678");
updateBulkOps.updateOne(query2,update2);
...
//执行这个操作
updateBulkOps.execute();
8,数据查询
查询这块方式比较多也比较简单,接下来讲解集中简单的查询方式,如下直接查询全部文档
List<User> userList = mongoTemplate.findAll(User.class);
也可以通过Query构造条件查询,并通过这 Criteria 条件构造条件去筛选数据
Query query2 = new Query();
query2.addCriteria(Criteria.where("username").is("zhsqaq"));
query2.addCriteria(Criteria.where("password").is("zhsqaq123456"));
mongoTemplate.find(query, User.class)
除了上面的is,还有可多api都是可用的,如一些基本操作ne,lt ,lte ,gt , gte 等等,基本操作运算符和比较运算符里面都有的
还支持在查询条件中增加排序功能,支持升序和降序,如下面这条根据创建时间升序排序
query.with(Sort.by(Sort.Order.asc("createdTime")));
同时支持分页功能,如继续给查询条件中返回前100条数据
query.skip(0).limit(100);
获取某个集合总文档的个数如下
mongoTemplate.count(query,User.class);
9,数据删除
数据删除就比较简单,只需要构造查询的条件,调用remove方法就可以直接将数据删除,如删除用户名为zhs的用户的数据
Query query = new Query();
query.addCriteria(Criteria.where("username").is("zhs"));
mongoTemplate.remove(query,User.class); //删除符合的数据
到此为止spring Boot整合mongodb算是入门成功
除就比较简单,只需要构造查询的条件,调用remove方法就可以直接将数据删除,如删除用户名为zhs的用户的数据
Query query = new Query();
query.addCriteria(Criteria.where("username").is("zhs"));
mongoTemplate.remove(query,User.class); //删除符合的数据
到此为止spring Boot整合mongodb算是入门成功