🍓 简介:java系列技术分享(👉持续更新中…🔥)
🍓 初衷:一起学习、一起进步、坚持不懈
🍓 如果文章内容有误与您的想法不一致,欢迎大家在评论区指正🙏
🍓 希望这篇文章对你有所帮助,欢迎点赞 👍 收藏 ⭐留言 📝🍓 更多文章请点击
文章目录
- 一、 MongoDB简介
- 二 、MongoDB特点
- 2.1 数据特点
- 2.2 数据存储
- 2.3 扩展性
- 2.4 MongoDB与Mysql对比
- 三、命令简单介绍
- 3.1 数据库以及表的操作
- 3.2 新增数据
- 3.3 更新数据
- 3.4 删除数据
- 3.5 查询数据
- 3.6 索引
- 四、MongoDB常用注解
- 五、Spring Boot整合MongoDB
- 5.1 引入依赖
- 5.2 yml配置
- 5.3 实体类
- 5.4 新增数据
- 5.5 条件查询
- 5.6 分页查询
- 5.7 更新数据
- 5.8 删除数据
- 5.9 地理位置搜索
- 实体类
- 第一种(不推荐)
- 第二种(推荐)
一、 MongoDB简介
MongoDB官网
: https://www.mongodb.com
MongoDB
是一个基于分布式文件存储的数据库。由C++语言编写,旨在为WEB应用提供可扩展的高性能数据存储解决方案。- MongodDB
是一个开源,高性能,支持海量数据存储的文档型数据库
,是NoSQL数据库产品的一种 - MongodDB是一个高效的非关系性数据库(
不支持表关系,只能操作单表
)
二 、MongoDB特点
2.1 数据特点
- 支持数据的海量存储
- 数据的读写响应速度较高
- 数据安全性不高,可以接受一定范围内的误差
- 不支持事务
- 动态字段
- MongodDB 使用Bson存储数据(Binary JSON),一种类似Json的数据格式
2.2 数据存储
2.3 扩展性
支持数据分片
2.4 MongoDB与Mysql对比
三、命令简单介绍
不常用
3.1 数据库以及表的操作
#查看所有的数据库
> show dbs#创建数据库
#说明:在MongoDB中,数据库是自动创建的,通过use切换到新数据库中,进行插入数据即可自动创建数据库
#通过use关键字切换数据库
> use test> show dbs #并没有创建数据库> db.user.insert({id:1,name:'zhangsan'}) #插入数据> show dbs#查看表
> show tables> show collections#删除集合(表)
> db.user.drop()
true #如果成功删除选定集合,则 drop() 方法返回 true,否则返回 false。#删除数据库
> use test #先切换到要删除的数据中> db.dropDatabase() #删除数据库
3.2 新增数据
#插入数据
> db.user.insert({id:1,username:'zhangsan',age:20})
>
> db.user.find() #查询数据
3.3 更新数据
#查询全部
> db.user.find()#更新数据
> db.user.update({id:1},{$set:{age:22}}) #注意:如果这样写,会删除掉其他的字段
> db.user.update({id:1},{age:25})#更新不存在的字段,会新增字段
> db.user.update({id:2},{$set:{sex:1}}) #更新数据#更新不存在的数据,默认不会新增数据
> db.user.update({id:3},{$set:{sex:1}})#如果设置第一个参数为true,就是新增数据
> db.user.update({id:3},{$set:{sex:1}},true)
3.4 删除数据
#删除数据
> db.user.remove({})#插入4条测试数据
db.user.insert({id:1,username:'zhangsan',age:20})
db.user.insert({id:2,username:'lisi',age:21})
db.user.insert({id:3,username:'wangwu',age:22})
db.user.insert({id:4,username:'zhaoliu',age:22})> db.user.remove({age:22},true)#删除所有数据
> db.user.remove({})
3.5 查询数据
#插入测试数据
db.user.insert({id:1,username:'zhangsan',age:20})
db.user.insert({id:2,username:'lisi',age:21})
db.user.insert({id:3,username:'wangwu',age:22})
db.user.insert({id:4,username:'zhaoliu',age:22})db.user.find() #查询全部数据
db.user.find({},{id:1,username:1}) #只查询id与username字段
db.user.find().count() #查询数据条数
db.user.find({id:1}) #查询id为1的数据
db.user.find({age:{$lte:21}}) #查询小于等于21的数据
db.user.find({$or:[{id:1},{id:2}]}) #查询id=1 or id=2#分页查询:Skip()跳过几条,limit()查询条数
db.user.find().limit(2).skip(1) #跳过1条数据,查询2条数据
db.user.find().sort({id:-1}) #按照id倒序排序,-1为倒序,1为正序
3.6 索引
1:升序索引 2:降序索引
#查看索引
db.user.getIndex()#创建索引
db.user.createIndex({'age':1})
四、MongoDB常用注解
注解 | 描述 |
---|---|
@Document | 把一个java类声明为mongodb的文档,可以通过collection参数指定这个类对应的文档,标注在实体类上,类似于hibernate的entity注解。 |
@Id | 文档的唯一标识,在mongodb中为ObjectId,它是唯一的,不可重复,自带索引,通过时间戳+机器标识+进程ID+自增计数器(确保同一秒内产生的Id不会冲突)构成。 |
@Transient | 映射忽略的字段,该字段不会保存到mongodb,只作为普通的javaBean属性。 |
@Field | 映射 mongodb中的字段名,可以不加,不加的话默认以参数名为列名。 |
@Indexed | 声明该字段需要索引,建索引可以大大的提高查询效率。 |
@CompoundIndex | 复合索引的声明,建复合索引可以有效地提高多字段的查询效率。 |
@GeoSpatialIndexed | 声明该字段为地理信息的索引。 |
@DBRef | 关联另一个document对象。类似于mysql的表关联,但并不一样,mongo不会做级联的操作。 |
五、Spring Boot整合MongoDB
5.1 引入依赖
<!--SpringDataMongo起步依赖-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
5.2 yml配置
spring:data:mongodb:uri: mongodb://127.0.0.1:27017/tanhua
5.3 实体类
MongoDB 推荐id 为:ObjectId 类型
@Data
@AllArgsConstructor
@NoArgsConstructor
@Document(value="person")
public class Person {@Idprivate ObjectId id; @Field("username")private String name;private int age;private String address;
}
5.4 新增数据
@SpringBootTest
public class MongoPersonTest {@Autowiredprivate MongoTemplate mongoTemplate;@Testpublic void testSave() {Person person = new Person();person.setName("李四");person.setAge(18);person.setAddress("杭州");mongoTemplate.save(person);}
}
新增成功
5.5 条件查询
这是目前表中数据用于查询
/*** 条件查询*/@Testpublic void testFind() {//查询年龄小于20的所有人Query query = new Query(Criteria.where("age").lt(20)); //查询条件对象//查询List<Person> list = mongoTemplate.find(query, Person.class);for (Person person : list) {System.out.println(person);}}
查询成功
5.6 分页查询
/*** 分页查询*/@Testpublic void testPage() {Criteria criteria = Criteria.where("age").lt(30);//1 查询总数Query queryCount = new Query(criteria);long count = mongoTemplate.count(queryCount, Person.class);System.out.println(count);//2 查询第二页,每页查询2条Query queryLimit = new Query(criteria).skip(2) //开启查询的条数 (page-1)*size.limit(5)//设置每页查询条数.with(Sort.by(Sort.Order.desc("age")));//排序List<Person> list = mongoTemplate.find(queryLimit, Person.class);for (Person person : list) {System.out.println(person);}}
查询成功
5.7 更新数据
/*** 更新:* 根据id,更新年龄 地址*/@Testpublic void testUpdate() {//1 条件 id对应age为18的数据Query query = Query.query(Criteria.where("id").is("64ca7274b8287f3990363504"));//2 更新的数据Update update = new Update();update.set("age", 20);update.set("address", "上海");mongoTemplate.updateFirst(query, update, Person.class);}
更新成功
5.8 删除数据
/*** 删除*/@Testpublic void testRemove() {Query query = Query.query(Criteria.where("id").is("64ca7274b8287f3990363504"));mongoTemplate.remove(query, Person.class);}
已删除上面更新的数据
5.9 地理位置搜索
使用MongoDB进行地理位置搜索,选择索引类型为:2dsphere
(支持地球表面上进行几何计算)
存储地址数据使用GeoJsonPoint
搜索原理:已以某个位置为圆点,然后以搜索的距离为半径画圆。
注意事项:
- 需要给对应字段建立索引类型为:
2dsphere
- 配置对应的实体类及相应注解
GeoJsonPoint
对像不支持序列化,如果项目使用Dubbo
进行远程调用(使用RPC通信,采用二进制,需要对对象进行序列化处理)那么GeoJsonPoint
对象无法传递,需要通过经纬度传递后在整合。
实体类
@Data
@NoArgsConstructor
@AllArgsConstructor
@Document(collection = "user_location")
@CompoundIndex(name = "location_index", def = "{'location': '2dsphere'}")
public class UserLocation implements Serializable {private static final long serialVersionUID = 45088645678765429970L;@Idprivate ObjectId id;@Indexedprivate Long userId; //用户idprivate GeoJsonPoint location; //x:经度 y:纬度private String address; //位置描述private Long created; //创建时间private Long updated; //更新时间
}
第一种(不推荐)
无法获取圆心到目标的距离
@Overridepublic void testQueryNear(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();
// GeoJsonPoint point = new GeoJsonPoint(110.123, 47.982);//3. 绘制半径Distance distance = new Distance(metre / 1000, Metrics.KILOMETERS);//4. 绘制圆形Circle circle = new Circle(point, distance);//5. 查询Query locationQuery = Query.query(Criteria.where("location").withinSphere(circle));List<UserLocation> list = mongoTemplate.find(locationQuery, UserLocation.class);for (UserLocation userLocation : list) {System.out.println(userLocation);}}
第二种(推荐)
public void testQueryNear(Double metre) {//构建圆点GeoJsonPoint point = new GeoJsonPoint(10.123, 47.982);//创建NearQuery对象NearQuery nearQuery = NearQuery.near(point, Metrics.KILOMETERS).maxDistance(metre / 1000, Metrics.KILOMETERS);//查询GeoResults<UserLocation> results = mongoTemplate.geoNear(nearQuery, UserLocation.class);for (GeoResult<UserLocation> result : results) {System.out.println(result.getContent());System.out.println(result.getDistance().getValue());}}