Springboot集成Mongodb
1、安装Mongodb
参考链接:https://www.cnblogs.com/lveyHang/p/16866309.html2、进行配置
找到mongodb的安装位置、找到如下文件进行配置 Mongodb\bin\mongod.cfg
# 配置数据存储目录,没有则创建. storage: dbPath: D:\soft\Mongodb\data # 配置日志存储目录,没有则创建. systemLog: destination: file logAppend: true path: D:\soft\Mongodb\log\mongod.log # network interfaces net: port: 27017 bindIp: 127.0.0.1
3、springboot集成
①启动类增加注解 @EnableMongoRepositories
②pom.xml-添加依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency>
③application.yml-增加配置
spring: data: mongodb: # uri: mongodb://127.0.0.1:27017/myMongo database: myMongo host: 127.0.0.1 port: 27017 username: root password: abc@123456 authentication-database: myMongo
4、常用操作:
//1查询所有 db.test.find(); db.getCollection('test').find(); //2.条件查询 根据name, 范围, 根据ID db.test.find({'name':'zhansan'}); db.test.find({'age':{$gt:20}}); db.test.find({'_id':ObjectId('673c83fc1a64000077001666')}); db.test.find({'rag':'yes','up_time':{$gt:1718147733}}); //3.删除所有/根据条件删除 db.test.remove({'name':'lisi'}); db.test.remove({}); //4.新增数据/批量插入 方式1、2 db.test.save({'name':'wangwu'}); db.test.insert({'name':'mazi','age':15}); db.test.insert([{'name':'mazi2','age':16},{'name':'mazi3','age':18}]); //5.修改数据--将name=mazi的 sex修改为女 db.test.update({'name':'mazi'},{$set:{'sex':'女'}}); db.test.updateMany( {_id: { $in: [ObjectId('66eb856e48050000e6001d33'), ObjectId('66eb859848050000e6001d34')] } }, {$set: { score: 95 } } ); //6.联表查询--主表interface 条件match 从表 user db.interface.aggregate([ { $lookup: { from: 'user', localField: 'uid', foreignField: '_id', as: 'users' } }, { $unwind: { path: '$users', preserveNullAndEmptyArrays: true } }, { $match:{ rag:'yes', up_time:{$gt:1718144059} } } ]); //7.springboot使用示例 Query query = new Query(Criteria.where('sex').is('man').and('add_time').gt(lasySyncTime)); List<TestVO> interfaceList = mongoDBUtils.list(query, Test.class, 'test'); //联表查询 左关联 主集合test 从集合user test.uid=user._id Aggregation aggregation = Aggregation.newAggregation( Aggregation.lookup('user', 'uid', '_id', 'user'), //第二个user为别名 Aggregation.unwind('user', true), //主集合查询文档中可展开从集合文档 user为别名 Aggregation.match(Criteria.where('rag').is('yes').and('up_time').gt(lasySyncTime)) //主集合增加筛选条件 ); //TestVO里定义的user对象 字段名要和别名一致 List<TestVO> interfaceList = mongoDBUtils.list(aggregation,TestVO.class, 'test');
5、添加MongoDBConfig配置类
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.convert.converter.Converter; import org.springframework.data.convert.ReadingConverter; import org.springframework.data.convert.WritingConverter; import org.springframework.data.mongodb.MongoDatabaseFactory; import org.springframework.data.mongodb.core.convert.*; import org.springframework.data.mongodb.core.mapping.MongoMappingContext; import java.util.Date; @Configuration public class MongoDBConfig { // 注册转换器 @Bean public MongoCustomConversions customConversions() { return MongoCustomConversions.create(i -> { i.registerConverter(new DateToLongConverter()); i.registerConverter(new LongToDateConverter()); }); } /** * mongo映射转换器 * @param factory mongo工厂 * @param context 映射命名空间 * @param customConversions 自定义转换器 * @return org.springframework.data.mongodb.core.convert.MappingMongoConverter */ @Bean public MappingMongoConverter mappingMongoConverter(MongoDatabaseFactory factory, MongoMappingContext context, MongoCustomConversions customConversions) { DbRefResolver dbRefResolver = new DefaultDbRefResolver(factory); MappingMongoConverter mappingConverter = new MappingMongoConverter(dbRefResolver, context); //添加自定义的转换器 mappingConverter.setCustomConversions(customConversions); // 去掉默认mapper添加的_class mappingConverter.setTypeMapper(new DefaultMongoTypeMapper(null)); return mappingConverter; } /** * mongo时间转换器(Long转Date) **/ @ReadingConverter private static class LongToDateConverter implements Converter<Long, Date> { @Override public Date convert(Long source) { // 判断是否为毫秒,兼容之前存的毫秒级时间 if (source.toString().length() < 11) { return new Date(source * 1000); } else return new Date(source); } } /** * mongo时间转换器(Date转Long) **/ @WritingConverter private static class DateToLongConverter implements Converter<Date, Long> { @Override public Long convert(Date source) { return source.getTime() / 1000; } } }
6、封装MongoDB工具类
import cn.hutool.core.util.ReflectUtil; import com.alibaba.fastjson.JSONObject; import com.mongodb.BasicDBObject; import com.mongodb.DBObject; import com.mongodb.client.result.UpdateResult; import lombok.extern.slf4j.Slf4j; import org.bson.types.ObjectId; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Sort; import org.springframework.data.mongodb.core.MongoTemplate; import org.springframework.data.mongodb.core.index.Index; import org.springframework.data.mongodb.core.index.IndexInfo; import org.springframework.data.mongodb.core.index.IndexOperations; import org.springframework.data.mongodb.core.query.*; import org.springframework.stereotype.Component; import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; import java.util.stream.Collectors; import java.io.Serializable; import java.lang.reflect.Field; import java.util.*; @Component @Slf4j public class MongoDBUtils { @Autowired private MongoTemplate template; private final Query EMPTY_QUERY = new BasicQuery('{}'); /** * @description: 创建集合和索引 */ public MongoDBUtils createCollection(String collectionName, Index... index) { template.createCollection(collectionName); for (Index item : index) { template.indexOps(collectionName).ensureIndex(item); } return this; } /** * @description: 创建指定集合的索引 */ public MongoDBUtils createIndex(String collectionName, Index... index) { IndexOperations indexOperations = template.indexOps(collectionName); List<String> indexNames = indexOperations.getIndexInfo().stream().map(IndexInfo::getName).collect(Collectors.toList()); for (Index item : index) { if (!indexNames.contains(ReflectUtil.getFieldValue(item, 'name'))) { indexOperations.ensureIndex(item); } } return this; } /** * @description: 添加单条数据 */ public <T> void save(T entity) { template.save(entity); } /** * @description: 添加单条数据,指定集合 */ public <T> void save(T entity, String collectionName) { template.save(entity, collectionName); } /** * @description: 添加单条数据 */ public <T> void inset(T entity) { template.insert(entity); } /** * @description: 批量添加数据,指定集合 */ public <T> void insetAll(Collection<? extends T> batchToSave, String collectionName) { template.insert(batchToSave, collectionName); } /** * @description: 批量添加数据 */ public <T> void saveBatch(Collection<T> entityList) { template.insertAll(entityList); } /** * @description: 根据id删除某条数据 */ public void removeById(Serializable id, Class<?> clazz) { template.remove(idEqQuery(id.toString()), clazz); } /** * @description: 根据条件删除 */ public void removeByMap(Map<String, Object> columnMap, Class<?> clazz) { template.remove(eqQuery(columnMap), clazz); } /** * @description: 根据id集批量删除 */ public void removeByIds(Collection<? extends Serializable> idList, Class<?> clazz) { template.remove(idInQuery(idList), clazz); } /** * @description: 根据查询条件删除 */ public void remove(Query query, Class<?> clazz) { template.remove(query, clazz); } /** * @description: 根据查询条件删除,指定集合 */ public void remove(Query query, Class<?> clazz, String collectionName) { template.remove(query, clazz, collectionName); } /** * @description: 根据实体更新数据,需携带id */ public <T> boolean updateById(T entity) { Assert.notNull(entity, 'entity must not be null!'); JSONObject obj = (JSONObject) JSONObject.toJSON(entity); DBObject update = new BasicDBObject(); update.put('$set', obj); UpdateResult result = template.updateFirst(idEqQuery(getIdValue(entity)), new BasicUpdate(update.toString()), entity.getClass()); return result.getModifiedCount() == 1L; } /** * @description: 根据实体更新数据,需携带id,指定集合 */ public <T> boolean updateById(T entity, String collectionName) { Assert.notNull(entity, 'entity must not be null!'); JSONObject obj = (JSONObject) JSONObject.toJSON(entity); DBObject update = new BasicDBObject(); update.put('$set', obj); UpdateResult result = template.updateFirst(idEqQuery(getIdValue(entity)), new BasicUpdate(update.toString()), entity.getClass(), collectionName); return result.getModifiedCount() == 1L; } /** * @description: 批量更新数据,需携带id */ public <T> void updateBatchById(Collection<T> entityList) { entityList.forEach(e -> updateById(e)); } /** * @description: 根据条件更新多个数据 */ public void update(Query query, Update update, Class<?> clazz) { template.updateMulti(query, update, clazz); } /** * @description: 根据实体添加或更新数据 */ public <T> void saveOrUpdate(T entity) { Assert.notNull(entity, 'entity must not be null!'); String key = JSONObject.toJSONString(entity); Update inc = new Update().inc(key, 1); template.upsert(idEqQuery(getIdValue(entity)), inc, entity.getClass()); } /** * @description: 根据实体集合批量添加或更新数据 */ public <T> void saveOrUpdateBatch(Collection<T> entityList) { entityList.forEach(e->saveOrUpdate(e)); } /** * @description: 根据id查询数据 */ public <T> T getById(String id, Class<T> clazz) { ObjectId objectId = new ObjectId(id); return template.findById(objectId.toString(), clazz); } /** * @description: 根据id查询数据,指定集合 */ public <T> T getById(String id, Class<T> clazz, String collectionName) { ObjectId objectId = new ObjectId(id); return template.findById(objectId.toString(), clazz, collectionName); } /** * @description: 根据条件查询单条数据 */ public <T> T getOne(Query query, Class<T> clazz) { return template.findOne(query, clazz); } /** * @description: 根据条件查询单条数据,指定集合 */ public <T> T getOne(Query query, Class<T> clazz, String collectionName) { return template.findOne(query, clazz, collectionName); } /** * @description: 根据id集查询多条数据 */ public <T> List<T> listByIds(Collection<? extends Serializable> idList, Class<T> clazz) { return template.find(idInQuery(idList), clazz); } /** * @description: 根据map条件查询多条数据 */ public <T> List<T> listByMap(Map<String, Object> columnMap, Class<T> clazz) { return template.find(eqQuery(columnMap), clazz); } /** * @description: 查询某个集合所有数据 */ public <T> List<T> list(Class<T> clazz) { return template.findAll(clazz); } /** * @description: 根据条件查询某个集合所有数据 */ public <T> List<T> list(Query query, Class<T> clazz) { return template.find(query, clazz); } /** * @description: 根据条件查询某个集合所有数据,指定集合 */ public <T> List<T> list(Query query, Class<T> clazz, String collectionName) { return template.find(query, clazz, collectionName); }
/**
* @description: 根据条件多集合查询某个集合所有数据,指定集合
*/
public <T> List<T> list(Aggregation aggregation, Class<T> clazz, String collectionName) {return template.aggregate(aggregation, collectionName, clazz).getMappedResults();
}
/** * @description: 统计某个集合所有数据量 */ public <T> long count(Class<T> clazz) { return template.count(EMPTY_QUERY, clazz); } /** * @description: 根据查询条件统计某个集合所有数据量 */ public <T> long count(Query query, Class<T> clazz) { return template.count(query, clazz); } /** * @description: 根据查询条件统计某个集合所有数据量,指定集合 */ public <T> long count(Query query, Class<T> clazz, String collectionName) { return template.count(query, clazz, collectionName); } /** * @description: 去重查询 需要传入历史数据实体 */ public <T> List<T> findDistinct(Query query, String field, Class<?> entityClass, Class<T> resultClass) { return template.findDistinct(query, field, entityClass, resultClass); } public <T> List<T> findDistinct(Query query, String field, String collectionName, Class<?> entityClass, Class<T> resultClass) { return template.findDistinct(query, field, collectionName, entityClass, resultClass); } /** * @description: 分页查询(支持自定义查询条件) * @param page 当前页码 * @param pagesize 分页大小 * @param clazz 返回实体 * @param criteria 构建的查询条件 例:Criteria.where('score').gt(8)
*/ public <T> PageUtils page(int page,int pagesize,Class<T> clazz,Criteria criteria){ //构建查询 Query query = new Query(); //添加自定义条件 如:Criteria.where('score').gt(8) if(criteria != null){ query.addCriteria(criteria); } //根据条件统计总数 long count = template.count(query,clazz); int newPage = page <= 0 ? 0 : page - 1; int newPageSize = pagesize <= 0 ? 10 : pagesize; Pageable pageable = PageRequest.of(newPage,newPageSize); query.with(pageable); //根据条件查询数据 List<T> list = template.find(query, clazz); return new PageUtils(list,(int)count,newPageSize,page); } /** * @description: 分页查询(支持自定义查询条件) * @param page 当前页码 * @param pagesize 分页大小 * @param clazz 返回实体 * @param criteria 构建的查询条件 例:Criteria.where('score').gt(8) * @param collectionName 指定集合名称
*/ public <T> PageUtils page(int page,int pagesize,Class<T> clazz,Criteria criteria,String collectionName){ //构建查询 Query query = new Query(); //添加自定义条件 如:Criteria.where('score').gt(8) if(criteria != null){ query.addCriteria(criteria); } //根据条件统计总数 long count = template.count(query, collectionName); int newPage = page <= 0 ? 0 : page - 1; int newPageSize = pagesize <= 0 ? 10 : pagesize; Pageable pageable = PageRequest.of(newPage,newPageSize); query.with(pageable); query.with(Sort.by(Sort.Order.desc('age'))); //根据条件查询数据 List<T> list = template.find(query, clazz,collectionName); return new PageUtils(list,(int)count,newPageSize,page); } private Query idEqQuery(Serializable id) { Criteria criteria = Criteria.where('id').is(id); return Query.query(criteria); } private Query idInQuery(Collection<? extends Serializable> idList) { Criteria criteria = Criteria.where('id').in(idList); return Query.query(criteria); } private Query eqQuery(Map<String, Object> data) { if (CollectionUtils.isEmpty(data)) { return EMPTY_QUERY; } else { Criteria criteria = new Criteria(); data.forEach((k, v) -> criteria.and(k).is(v)); return Query.query(criteria); } } private <T> Serializable getIdValue(T entity) { try { Field field = entity.getClass().getDeclaredField('id'); field.setAccessible(true); return (Serializable) field.get(entity); } catch (NoSuchFieldException | IllegalAccessException e) { e.printStackTrace(); } return null; } private <T> Update getUpdate(T entity) { Field[] fields = entity.getClass().getDeclaredFields(); for (Field field : fields) { field.setAccessible(true); } return null; } }
7、分页工具类PageUtils
import com.google.common.collect.Lists; import java.io.Serializable; import java.util.List; import lombok.Data; @Data public class PageUtils<T> implements Serializable { private static final long serialVersionUID = 1L; /** * 总记录数 */ private int totalCount; /** * 每页记录数 */ private int pageSize; /** * 总页数 */ private int totalPage; /** * 当前页数 */ private int currPage; /** * 列表数据 */ private List<T> list = Lists.newArrayList(); /** * 分页 * @param list 列表数据 * @param totalCount 总记录数 * @param pageSize 每页记录数 * @param currPage 当前页数 */ public PageUtils(List<T> list, int totalCount, int pageSize, int currPage) { this.list = list; this.totalCount = totalCount; this.pageSize = pageSize; this.currPage = currPage; this.totalPage = (int)Math.ceil((double)totalCount/pageSize); } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了