1、MongonDB简介
问 | 答 |
---|---|
什么是MongoDB | 一个以JSON为数据模型的文档非关系型数据库 |
什么是非关系型数据库 | NoSQL,—种区分关系型数据库的数据存储方案,具有易扩展,大数据量,高性能,灵活数据模型,高可用等特点 |
为什么叫文档数据库 | 文档来自与"JSON Document",并不是我们理解的PDF,WORD文档 |
MonogDB它爹是谁 | 美国上市公司MongoDB Inc. |
有哪些用途 | 应用数据库,类似于Oracle,Mysql,专注于海量数据处理,数据平台 |
有哪些特点 | 1:建模灵活,2: json数据模型,3:横向扩展简单 4:大数据量存储,5:高并发 |
是开源的吗 | 社区版:居于SSPL协议,开源的,企业版:居于商业协议,需付费使用 |
2、MongonDB与RDBMS数据库的区别
MongonDB | RDBMS | |
---|---|---|
数据模型 | 文档类型(json) | 关系模型(二维表) |
数据库类型 | OLTP | OLTP |
CRUD操作 | MQL/sQL | sQ |
高可用 | 复制集 | 集群模式 |
横向扩展能力 | 通过原生分片完善支持 | 数据分区或者应用侵入式 |
索引支持 | B-树、全文索引、地理位置索引、多键所以、TTL索引 | B树 |
开发难度 | 容易 | 困难 |
数据容量 | 没有理论的上限 | 千万、亿 |
扩展方式 | 垂直扩展+水平扩展 | 垂直扩展+水平扩展 |
3、MongonDB优势
- 简单直观
- 结构灵活
- 快速开发
- 高可用与易拓展
4、MongonDB应用场景
- 游戏场景,使用 MongoDB 存储游戏用户信息,用户的装备、积分等直接以内嵌文档的形式存储,方便查询、更新
- 物流场景,使用 MongoDB 存储订单信息,订单状态在运送过程中会不断更新,以 MongoDB 内嵌数组的形式来存储,一次查询,就能将订单所有的变更读取出来。
- 社交场景,使用 MongoDB 存储存储用户信息,以及用户发表的朋友圈信息,通过地理位置索引实现附近的人、地点等功能
- 物联网场景,使用 MongoDB 存储所有接入的智能设备信息,以及设备汇报的日志信息,并对这些信息进行多维度的分析
- 视频直播,使用 MongoDB 存储用户信息、礼物信息等
- 日志处理
5、MongonDB安装
- mongon安装参考文章
6、基本概念
7、数据类型
8、MongonDB增删改查
//语法:
//db.集合名.insert( 文档 ) : 往集合中插入一个文档或者多个
//注意:
//1:往集合中新增文档,当集合不存在时会自动先创建集合
//2:当操作成功时,集合会给文档生成一个**_id**字段,也可以自己指定
db.users.insert({
id: 1,
name: "dafei",
age: 18
})
db.users.insert({
id: 2,
name: "xiaofei",
age: 17
})
格式:
//update users set xx=1 where xx = 1
//db.集合名.updateOne(<query>, <update>)
//db.集合名.updateMany(<query>,<update>)
//query : update的查询条件,类似sql update查询内where后面的。
//update : update的对象和一些更新的操作符(如$,$inc...)等,也可以理解为sql update查询内set后面的
//把一个带有name=dafei的文档,修改其age值为30
db.users.updateOne({
name: "dafei"
}, {
$set: {
age: 30
}
})
//修改所有name=dafei的文档,修改其name=大飞,age=20
db.users.updateMany({
name: "dafei"
},{
$set: {
name: "大飞",
age: 20
}
})
//修改所有的文档,修改其name=xxx,age=10
db.users.updateMany({},{
$set: {
name: "xxx",
age: 10
}
})
//删除1个:
//db.集合名.deleteOne(<query>)
//删除多个:
//db.集合名.deleteMany(<query>)
//删除_id=xxx的文档
db.users.deleteOne({
_id: ObjectId("xxx")
})
//删除所有带有name=dafei的文档
db.users.deleteMany({
name: "bunny"
})
//删除当前数据库中所有文档
db.users.deleteMany({})
语法:
//sql: select age, name from table where ....
//db.集合名.find(query, projection)
//query: 是条件
//projection: 列的投影,指定返回哪些列 _id默认返回 eg: {"_id": 0}
//查所有用户
//sql: select * from users;
db.users.find()
db.users.find({}) //{} 是条件
db.users.find({}, {
name: 1,
age: 1
}) //第二个{} 表示查询哪些列
//db.集合名.find(query, projection).
sort({
列:1
}) //正序
sort({
列: - 1
}) //倒序
//多列排序
sort({
列1: 1, 列2: 1
})
//查询所有用户按年龄排序
//sql: select * from users order by age desc|asc
db.users.find({}).sort({
age: 1
}) //正序
db.users.find({}).sort({
age: - 1
}) //倒序
db.users.find({}).sort({
age: - 1,
id: 1
}) //多列排序
//db.集合.find({}).skip(n).limit(m)
//分页查询所有用户
//sql: select * from users limit 0, 3
db.users.find().skip(0).limit(3) //第一页
db.users.find().skip(3).limit(3) //第二页
db.users.find().skip((currentPage - 1) * pageSize).limit(pageSize)
//语法 ->db.集合名. find({字段: {比较操作符: 值, ...}})
//> 大于 - $gt
//< 小于 - $lt
//>= 大于等于 - $gte
//<= 小于等于 - $lte
//!= 不等 - $ne
//is null {$exists: false}
//in {$in: [xx, xx ...]}
//查询age > 30的用户
//sql: select * from users where age > 300
db.users.find({
age: {
$gt: 30
}
})
//查询名字为 dafei 或xiaofei用户
//sql: select * form users where name in("dafei", "xiaofei")
db.users.find({
name: {
$in: ["dafei", "xiaofei"]
}
})
//判断判断指定列是否存在
db.users.find({
name: {
$exists: true
}
})
语法 -> find({
逻辑操作符: [条件1, 条件2,...]
})
&& 与 - $and
|| 或 - $or
!非 - $not
查年龄在28 到 30间的用户信息
//sql: select * from users where age >= 28 and age <=30
db.users.find(
{
age: {
$gte: 28,
$lte: 30
}
}
)
db.users.find(
{
$and: [{
age: {
$gte: 28
}
}, {
age: {
$lte: 30
}
}]
}
)
// 查看年龄小于28或者年龄大于30用户信息
//sql: select * from users where age <28 or age >30
db.users.find(
{
$or: [{
age: {
$lt: 28
}
}, {
age: {
$gt: 30
}
}]
}
)
查看年龄等于28或者等于30用户信息
//sql: select * from users where age =28 or age =30
db.users.find(
{
$or: [{
age: 28
}, {
age: 30
}]
}
)
db.集合.find({
列: {
$regex: /关键字/
}
})
//sql: select * from user where name like '%关键字%'
db.集合.find({
列: {
$regex: /关键字/
}
}) / / 表示正则对象(js)
db.集合.find({
列: {
$regex: "关键字"
}
})
{
name: /xxx/
} --->% xxx %
{
name: /^xxx/
} ---> xxx %
{
name: /xxx$/
} --->% xxx
{
name: /xxx/i
} 忽略大小写
查询name带有fei的用户信息
//sql: select * from users where name like '%fei%'
db.users.find(
{
name: {
$regex: /fei/
}
}
)
查name中包含fei字样,并且年龄在28 到 30间的用户信息, //sql: select * from users where name like '%fei%' and age >= 28 and age <=30
db.users.find(
{
$and: [{
name: {
$regex: /fei/
}
}, {
age: {
$gte: 28,
$lte: 30
}
}]
})
9、SpringBoot集成MongonDB
- 创建maven项目
- 添加相关依赖
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.4.3</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!--spring boot data mongodb-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
</dependencies>
- 配置文件
# application.properties
# 配置数据库连接
#格式: mongodb://账号:密码@ip:端口/数据库?认证数据库
#spring.data.mongodb.uri=mongodb://root:admin@localhost/mongodemo?authSource=admin
spring.data.mongodb.uri=mongodb://localhost/mongodemo
# 配置MongoTemplate的执行日志
logging.level.org.springframework.data.mongodb.core=debug
- 创建实体类
@AllArgsConstructor
@NoArgsConstructor
@Setter
@Getter
@ToString
@Document("users") //设置文档所在的集合
public class User {
//文档的id使用ObjectId类型来封装,并且贴上@Id注解,
// 自动映射为_id 自动封装ObjectId
@Id
private String id;
private String name;
private Integer age;
private List<String> hobby = new ArrayList<>();
}
- crud操作及测试
// 持久层接口——继承接口:MongoRepository
@Repository
public interface UserMongoRepository extends MongoRepository<User, String> {
// 使用Spring Data命名规范做高级查询
List<User> findByName(String name);
}
// 业务层接口
public interface IUserService {
void save(User user);
void delete(String id);
void update(User user);
User get(String id);
List<User> list();
}
// 业务层实现类
@Service
public class UserServiceImpl implements IUserService{
@Autowired
private UserRepository userRepository;
@Override
public void save(User user) {
userRepository.save(user);
}
@Override
public void delete(String id) {
userRepository.deleteById(id);
}
@Override
public void update(User user) {
userRepository.save(user);
}
@Override
public User get(String id) {
return userRepository.findById(id).get();
}
@Override
public List<User> list() {
return userRepository.findAll();
}
}
// 测试类
@SpringBootTest
public class UserTest {
@Autowired
private IUserService userService;
@Test
public void testSave(){
User user = new User();
user.setId(21L);
user.setName("dafei");
user.setAge(18);
userService.save(user);
}
@Test
public void testUpdate(){
User user = new User();
user.setId("5de507fca0852c6c7ebc1eac");
user.setId(21L);
user.setName("dafei2222");
user.setAge(18);
userService.update(user);
}
@Test
public void testDelete(){
userService.delete("5de507fca0852c6c7ebc1eac");
}
@Test
public void testGet(){
System.out.println(userService.get("5de507fca0852c6c7ebc1eac"));
}
@Test
public void testList(){
System.out.println(userService.list());
}
}
-
JPA 查询规则
-
分页查询
@Autowired
private MongoTemplate mongoTemplate;
// 分页查询文档,显示第2页,每页显示3个,按照id升序排列
@Test
public void testQuery1() throws Exception {
// 创建查询对象
Query query = new Query();
// 设置分页信息
query.skip(3).limit(3);
// 设置排序规则
query.with(Sort.by(Sort.Direction.ASC,"id"));
List<User> list = mongoTemplate.find(query, User.class, "users");
list.forEach(System.err::println);
}
- 条件查询
@SpringBootTest
public class QueryTest {
@Autowired
private MongoTemplate mongoTemplate;
// 分页查询文档,显示第2页,每页显示3个,按照id升序排列
@Test
public void testQuery1() throws Exception {
// 创建查询对象
Query query = new Query();
// 设置分页信息
query.skip(3).limit(3);
// 设置排序规则
query.with(Sort.by(Sort.Direction.ASC,"id"));
List<User> list = mongoTemplate.find(query, User.class, "users");
list.forEach(System.err::println);
}
// 查询所有name为dafei的文档
@Test
public void testQuery2() throws Exception {
// 构建限制条件 {"name": "dafei"}
Criteria criteria = Criteria.where("name").is("dafei");
// 创建查询对象
Query query = new Query();
// 添加限制条件
query.addCriteria(criteria);
List<User> list = mongoTemplate.find(query, User.class, "users");
list.forEach(System.err::println);
}
// 查询所有name为dafei或者age<30的文档
@Test
public void testQuery3() throws Exception {
// 构建限制条件 { "$or": [{"name": "dafei"}, {"age": {"$lt": 30}}] }
Criteria criteria = new Criteria().orOperator(
Criteria.where("name").is("dafei"),
Criteria.where("age").lt(30)
);
// 创建查询对象
Query query = new Query();
// 添加限制条件
query.addCriteria(criteria);
List<User> list = mongoTemplate.find(query, User.class, "users");
list.forEach(System.err::println);
}
// 查询所有name含有fei并且30<=age<=32的文档
@Test
public void testQuery4() throws Exception {
// 构建限制条件 { "$and" : [{"name": {"$regex": ".*fei.*"} }, {"age": {"$gte": 30, "$lte": 32 } }] }
Criteria criteria = new Criteria().andOperator(
Criteria.where("name").regex(".*fei.*"),
Criteria.where("age").gte(30).lte(32)
);
// 创建查询对象
Query query = new Query();
// 添加限制条件
query.addCriteria(criteria);
List<User> list = mongoTemplate.find(query, User.class, "users");
list.forEach(System.err::println);
}
}