spring-data-mongoDB

devtools/2025/2/28 17:32:20/

目录

spring-data-mongoDB%E4%BD%BF%E7%94%A8-toc" name="tableOfContents" style="margin-left:0px">spring-data-mongoDB使用

1.导入mongoDB依赖

2.编写配置文件

3.编写实体类,与mongoDB中的文档相对应,使用@Document注解

4.编写service层方法

一.实现保存方法

 二.实现修改方法

三.实现删除方法

四.实现查询方法

项目使用mongoDB实现作业范围 

1.实体类

2.业务实现


这里介绍以下spring-data-mongoDB的用法

spring-data-mongoDB%E4%BD%BF%E7%94%A8" name="spring-data-mongoDB%E4%BD%BF%E7%94%A8">spring-data-mongoDB使用

1.导入mongoDB依赖

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

2.编写配置文件

spring:application:name: sl-express-mongodbdata:mongodb:host: 192.168.150.101port: 27017database: slauthentication-database: admin #认证数据库username: slpassword: "123321"auto-index-creation: true #自动创建索引

3.编写实体类,与mongoDB中的文档相对应,使用@Document注解

java">import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.bson.types.ObjectId;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
import org.springframework.data.mongodb.core.index.GeoSpatialIndexType;
import org.springframework.data.mongodb.core.index.GeoSpatialIndexed;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Document("sl_person") //指定表名,也就是指定集合的名字
public class Person {@Id // 标识为主键private ObjectId id;@Indexed //标识索引字段private String name;private int age;/*** 用户位置* x: 经度,y:纬度*/@GeoSpatialIndexed(type = GeoSpatialIndexType.GEO_2DSPHERE)private GeoJsonPoint location;//存储嵌套对象数据private Address address;
}
java">import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.mongodb.core.mapping.Document;
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Document("sl_address") //指定表名,也就是指定集合的名字
public class Address {private String street;private String city;private String zip;
}

4.编写service层方法

因为mongoDB没有向mysql,neo4j一样提供持久层的接口方法,但是和redis一样有一个MongoTemplate 的bean对象,可以直接对数据库进行CRUD操作

java">public interface PersonService {/*** 新增数据** @param person 数据*/void savePerson(Person person);/*** 更新数据** @param person 数据*/void update(Person person);/*** 根据名字查询用户列表** @param name 用户名字* @return 用户列表*/List<Person> queryPersonListByName(String name);/*** 分页查询用户列表** @param page     页数* @param pageSize 页面大小* @return 用户列表*/List<Person> queryPersonPageList(int page, int pageSize);/*** 根据id删除用户** @param id 主键*/void deleteById(String id);
}
java">import org.springframework.data.mongodb.core.MongoTemplate;import javax.annotation.Resource;
import java.util.List;public class PersonServiceImpl implements PersonService {@Resourceprivate MongoTemplate mongoTemplate;@Overridepublic void savePerson(Person person) {}@Overridepublic void update(Person person) {}@Overridepublic List<Person> queryPersonListByName(String name) {return null;}@Overridepublic List<Person> queryPersonPageList(int page, int pageSize) {return null;}@Overridepublic void deleteById(String id) {}
}

一.实现保存方法

可以使用insert方法和save方法,但是save方法会直接覆盖原来的值

java">  @Overridepublic void savePerson(Person person) {mongoTemplate.save(person);}

测试

java">import org.bson.types.ObjectId;@ResourcePersonService personService;@Testvoid savePerson() {Person person = Person.builder().id(ObjectId.get()) //使用mongoDB提供的ObjectId生成id值.name("张三").age(20).location(new GeoJsonPoint(116.343847, 40.060539)).address(new Address("人民路", "上海市", "666666")).build();this.personService.savePerson(person);}

不使用ObjectId获取id也可以,mongoDB也会自己生成

java">@Testvoid savePerson() {Person person = Person.builder()//.id(ObjectId.get()).name("张三").age(20).location(new GeoJsonPoint(116.343847, 40.060539)).address(new Address("人民路", "上海市", "666666")).build();this.personService.savePerson(person);}

 二.实现修改方法

java"> @Overridepublic void update(Person person) {//1.构建查询条件,定义要改哪些数据,这里定义了要改主键_id=person.getId的数据/*Query query = new Query();query.addCriteria(Criteria.where("_id").is(person.getId()));*///或者:Query query = Query.query(Criteria.where("_id").is(person.getId()));//2.设置要修改的值Update update = new Update();update.set("name",person.getName());update.set("age",person.getAge());update.set("location",person.getLocation());update.set("address",person.getAddress());//3.只修改一个mongoTemplate.updateFirst(query,update, Person.class);//根据Person.class提供的类型才能去操作哪一个集合}

测试

java">    @Testvoid update() {Person person = Person.builder().id(new ObjectId("67b7fb71ab81697aa2e8688e")).name("张三").age(22) //修改数据.location(new GeoJsonPoint(116.343847, 40.060539)).address(new Address("人民路", "上海市", "666666")).build();this.personService.update(person);}

三.实现删除方法

其实_id可以写出id,mongo也会当作主键去查

java">    @Overridepublic void deleteById(String id) {Query query = Query.query(Criteria.where("_id").is(id));mongoTemplate.remove(query, Person.class);}

测试

java">@Testvoid deleteById() {this.personService.deleteById("67b7fb71ab81697aa2e8688e");}

四.实现查询方法

java">    @Overridepublic List<Person> queryPersonListByName(String name) {Query query = Query.query(Criteria.where("name").regex(name));//根据正则表达式查询,类似模糊查询return mongoTemplate.find(query,Person.class);}

测试

java">    @Testvoid queryPersonListByName() {List<Person> personList = this.personService.queryPersonListByName("三");personList.forEach(System.out::println);}

五.实现分页查询

java">@Overridepublic List<Person> queryPersonPageList(int page, int pageSize) {//1.构建查询条件Query query = new Query();//根据age降序query.with(Sort.by(Sort.Direction.DESC,"age"));//构建分页条件,mongoDB默认页数从0开始,而一般前端都是从第一页,所以要减一query.with(PageRequest.of((page-1),pageSize));return mongoTemplate.find(query, Person.class);}

 测试

java">    @Testvoid queryPersonPageList() {List<Person> personList = this.personService.queryPersonPageList(1, 10);personList.forEach(System.out::println);}

项目使用mongoDB实现作业范围 

1.实体类

这里对id主键不进行json序列化,使用bid作为我们的业务id,并且对类型进行普通索引,使用type来区分快递机构和快递员,最后使用GeoJsonPolygon类型作为面积范围的闭合的多边形范围,并使用索引

java">@Data
@Document("sl_service_scope")
public class ServiceScopeEntity {@Id@JsonIgnoreprivate ObjectId id;/*** 业务id,可以是机构或快递员*/@Indexedprivate Long bid;/*** 类型 {@link com.sl.ms.scope.enums.ServiceTypeEnum}*/@Indexedprivate Integer type;/*** 多边形范围,是闭合的范围,开始经纬度与结束经纬度必须一样* x: 经度,y:纬度*/@GeoSpatialIndexed(type = GeoSpatialIndexType.GEO_2DSPHERE)private GeoJsonPolygon polygon;private Long created; //创建时间private Long updated; //更新时间
}
java">public enum ServiceTypeEnum {ORGAN(1, "机构"),COURIER(2, "快递员");/*** 类型编码*/private final Integer code;/*** 类型值*/private final String value;ServiceTypeEnum(Integer code, String value) {this.code = code;this.value = value;}public Integer getCode() {return code;}public String getValue() {return value;}public static ServiceTypeEnum codeOf(Integer code) {return EnumUtil.getBy(ServiceTypeEnum::getCode, code);}
}

2.业务实现

保存数据

java">/*** 保存或修改 作业范围* @param bid     业务id* @param type    类型* @param polygon 多边形坐标点* @return*/@Overridepublic Boolean saveOrUpdate(Long bid, ServiceTypeEnum type, GeoJsonPolygon polygon) {// TODO day08 新增作业范围// 1. 构建mongo查询条件  bid    typeQuery query = Query.query(Criteria.where("bid").is(bid).and("type").is(type.getCode()));// 2. 根据条件查询对应作业范围ServiceScopeEntity serviceScopeEntity = mongoTemplate.findOne(query, ServiceScopeEntity.class);// 3. 如果作业范围为空 ==> 新建作业范围保存if(ObjectUtil.isEmpty(serviceScopeEntity)){serviceScopeEntity=new ServiceScopeEntity();serviceScopeEntity.setBid(bid);serviceScopeEntity.setType(type.getCode());serviceScopeEntity.setPolygon(polygon);serviceScopeEntity.setCreated(System.currentTimeMillis());serviceScopeEntity.setUpdated(System.currentTimeMillis());}else{// 4. 如果作业范围存在 ==> 修改多边形字段 和 updated时间serviceScopeEntity.setPolygon(polygon);serviceScopeEntity.setUpdated(System.currentTimeMillis());}try {mongoTemplate.save(serviceScopeEntity);return true;} catch (Exception e) {log.error("新增或者修改数据失败,{}",serviceScopeEntity);}// 5. 返回结果return false;}

 GeoJsonPolygon类型的构造参数使用的是List<Point>,注意第一个节点数据需要与最后一个节点数据一样,因为要保持是闭合的多边形

java">   import org.springframework.data.geo.Point;@Testvoid saveOrUpdate() {List<Point> pointList = Arrays.asList(new Point(116.340064,40.061245),new Point(116.347081,40.061836),new Point(116.34751,40.05842),new Point(116.342446,40.058092),new Point(116.340064,40.061245));Boolean result = this.scopeService.saveOrUpdate(2L, ServiceTypeEnum.ORGAN, new GeoJsonPolygon(pointList));System.out.println(result);}

 根据传入的一个点的坐标来判断在哪一个机构或者快递员中的范围中,可能会查出来多个,所以用集合

java"> @Overridepublic List<ServiceScopeEntity> queryListByPoint(ServiceTypeEnum type, GeoJsonPoint point) {// TODO day08 根据类型 和 坐标点查询有交集的作业范围     tips: intersects 查询传入坐标点和mongo库中多边形相交的数据Query query = Query.query(Criteria.where("type").is(type.getCode()).and("polygon").intersects(point));return mongoTemplate.find(query, ServiceScopeEntity.class);}@Overridepublic List<ServiceScopeEntity> queryListByPoint(ServiceTypeEnum type, String address) {// TODO day08 根据类型 和 详细地址     tips: eagleMapTemplate 查询坐标点GeoResult geoResult = eagleMapTemplate.opsForBase().geoCode(address);Coordinate location = geoResult.getLocation();return queryListByPoint(type,new GeoJsonPoint(location.getLongitude(),location.getLatitude()));}
java">    @Testvoid testQueryListByPoint() {GeoJsonPoint point = new GeoJsonPoint(116.344828,40.05911);List<ServiceScopeEntity> serviceScopeEntities = this.scopeService.queryListByPoint(ServiceTypeEnum.ORGAN, point);serviceScopeEntities.forEach(serviceScopeEntity -> System.out.println(serviceScopeEntity));}@Testvoid testQueryListByPoint2() {String address = "北京市昌平区金燕龙办公楼";List<ServiceScopeEntity> serviceScopeEntities = this.scopeService.queryListByPoint(ServiceTypeEnum.ORGAN, address);serviceScopeEntities.forEach(serviceScopeEntity -> System.out.println(serviceScopeEntity));}

可以发现这个坐标点被这个闭合的多边形包围 

 根据bid和类型查询

java">    public ServiceScopeEntity queryByBidAndType(Long bid, ServiceTypeEnum type) {// TODO day08 根据bid和类型查询作业范围Query query = Query.query(Criteria.where("bid").is(bid).and("type").is(type.getCode()));return mongoTemplate.findOne(query,ServiceScopeEntity.class);}

查询附近的人

java">/*** 查询附近的人的所有用户id** @param userId 用户id,中心点用户* @param metre  距离,单位:米* @return 附近的人*/@Overridepublic List<Long> queryNearUser(Long userId, Double metre) {//1、根据用户id,查询用户的位置信息Query query = Query.query(Criteria.where("userId").is(userId));UserLocation location = mongoTemplate.findOne(query, UserLocation.class);if (location == null) {return null;}//2、以当前用户位置绘制原点GeoJsonPoint point = location.getLocation();//3、绘制半径Distance distance = new Distance(metre / 1000, Metrics.KILOMETERS);//5、构建查询对象NearQuery nearQuery = NearQuery.near(point).maxDistance(distance);//6、执行查询,由近到远排序GeoResults<UserLocation> geoResults = mongoTemplate.geoNear(nearQuery, UserLocation.class);//7、获取结果对象,其中userLocationGeoResult.getDistance()可以获取目标点与中心点的位置return geoResults.getContent().stream().map(userLocationGeoResult -> userLocationGeoResult.getContent().getUserId()).collect(Collectors.toList());}


http://www.ppmy.cn/devtools/163400.html

相关文章

Qt:布局管理器

目录 QVBoxLayout QHBoxLayout QGridLayout QFormLayout QSpacerItem 之前使用 Ot 在界面上创建的控件&#xff0c;都是通过 "手动" 的方式来设定的&#xff0c;也就是每个控件所在的位置&#xff0c;都需要计算坐标&#xff0c;最终通过 setGeometry 或者 move…

CSS处理内容溢出

<!DOCTYPE html> <html lang"zh-cn"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>处理内容溢出</title><style>#d1{wid…

DeepSeek集成IT技术开发方向全景解读:重构智能开发新范式

一、技术架构革命:支撑IT开发集成的三大引擎 1. 动态MoE架构(DeepSeekMoE-32B) 通过混合专家系统实现精准任务路由,在软件开发场景中展现出显著优势: 代码生成场景:激活Java/Python/C++等语言专家模块,单元测试覆盖率提升至85%硬件资源优化:FP16量化下推理显存需求低…

2025年软考报名费用是多少?全国费用汇总!

软考报名时间终于确定了&#xff01;想要参加2025年软考的同学们注意啦&#xff01;特别是那些一年只有一次考试机会的科目&#xff0c;千万不要错过哦&#xff01;这里为大家整理了各地的报名时间、科目、费用等信息&#xff0c;快来看看吧&#xff01; 一、2025年软考时间安…

git 国内源

git config --global url.“https://hub.fastgit.xyz/”.insteadOf “https://github.com/” git config --global url.“https://hub.fastgit.xyz/”.insteadOf “git://github.com/” 取消 FastGit 代理: git config --global --unset url.“https://hub.fastgit.xyz/”.in…

MySQL表约束的种类与应用

在MySQL数据库中&#xff0c;表约束是确保数据完整性的关键。约束限制了可以在表中插入或更新的数据类型&#xff0c;保证数据的准确性和可靠性。了解MySQL中的各种表约束对于数据库设计和数据维护至关重要。以下是MySQL支持的主要表约束类型及其应用的详细介绍。 1. 主键约束…

2025 IAST工具推荐 ︱IAST工具如何赋能企业开发安全?

IAST交互式应用程序安全测试&#xff08;Interactive Application Security Testing&#xff09;是Gartner 2012年提出的一种新型运行时应用安全测试方案&#xff0c;规避了黑盒安全扫描DAST和白盒代码审计技术的主要技术缺陷&#xff0c;通过代理/VPN、旁路流量镜像、透明流量…

Java I/O 与 NIO 核心区别及应用场景详解

一、核心概念对比 特性传统 I/O (BIO)NIO (New I/O)模型同步阻塞模型同步非阻塞模型数据流方向单向流&#xff08;InputStream/OutputStream&#xff09;双向通道&#xff08;Channel&#xff09;数据操作单元基于字节/字符流基于缓冲区&#xff08;Buffer&#xff09;线程模型…