1>MongoDB概念 优点 缺点 定位 运用场景 与mysql的区别 与redis的区别(面试大概率)
2>MongoDB的 crud
3>MongoDB 文档设计
4>SpringBoot集成 MongoDB(必须掌握)
----------------------------------------------------------------------------------------------------------------
1>复习web阶段 分页操作 PageResult
----------------------------------------------------------------------------------------------------------------
MongoDB的优势
1>直观 --> 一个表 对 一个类 不存在多表关联
2>结构灵活-->对象做一个动作 toJsonString
3>快速开发-->反范式,无关联 数据读写引擎只需要在一个内存
MongoDB为什么用来缓存
MongoDB 在实例启动的时候,从硬盘中加载部分数据,放到虚拟内容 做crud的操作的时候,在内存中操作虚拟内存拷贝到硬盘的同步时间的间隔是1s,有可能会导致数据丢失 所以只能当做缓存,只有硬件成本+人工成本上去了,就能解决以上问题
应用场景
物流订单查询 社交场景(朋友圈,地理位置搜索,地点) 物联网场景(智能设备) 视频直播 日志处理
语法规则和sql规则一致
增删改查操作 参照官网Introduction to MongoDB — MongoDB Manual
添加
// 文档添加:db.集合名.insert(文档)
var user = {id:1,name:"古天乐",age:18}
db.users.insert(user)
var userArr =[
{id:5,name:"王力宏",age:28},
{id:6,name:"罗志祥",age:30}
]
db.users.insert(userArr)
更改
query-->条件
update-->更改对象-->set
所有的参数都用大括号包起来
// 修改 语法格式
// db.集合名.update(
)
// db.集合名.updateMany(
)
// 把一个带有name=罗志祥的文档,修改其age值为40
db.users.update({name:"罗志祥"},{$set:{age:40}})
db.users.update({name:"王力宏"},{$set:{age:50}})
删除
严格匹配类型-->要删掉_id的时候得看封装的类型
N/A-->没有这列
Null-->空,列在
// 删除_id=62653376c03a00008b005d48的文档
db.users.deleteMany({_id:ObjectId("62653376c03a00008b005d48")})
// 删除name=王力宏的文档
db.users.deleteMany({name:"王力宏"})
查询
// 查询语法格式-->db.集合名.find(query,projection)
// 查询所有用户
db.users.find({})
db.users.find()
// 只查询name,age列
db.users.find({},{name:1,age:1})
列映射,除了_id之外,其他列要么全部是1,要么全部是0
-->报错,id选择0
排序
// 排序 语法格式-->db.集合名.find().sort({列:1}) // 正序
.sort({列:-1}) // 倒序
.sort({列1:1 ,列2:1}) // 多列排序
// 查询所有用户按年龄排序
db.users.find().sort({age:1}) 从小到大
db.users.find().sort({age:-1}) 从大到小
// 如果年龄一样,根据id倒序
db.users.find().sort({age:1 ,id:-1})
分页
// 分页 语法格式-->db.集合名.find({}).skip(n).limit(m)
n:(当前页第一条数据-1)*当前页总条数 m:当前页总条数
// 第一页,显示三条
db.users.find().skip(0).limit(3)
// 第二页,显示三条
db.users.find().skip(3).limit(3)
/ 第n页 显示三条
db.users.find().skip((currentPage-1)*pageSize).limit(pageSize)
比较运算符
// 比较运算符
语法 ->db.集合名. find({字段: {比较操作符: 值, ...}})
> 大于 - $gt greate than
< 小于 - $lt less than
>= 大于等于 - $gte greate than equals
<= 小于等于 - $lte less than equals
!= 不等 - $ne
exists {$exists: false}
in {$in: [xx, xx ...]}
// 查询age > 30的用户
//sql: select * from users where age > 300
db.users.find({age:{$gt:18}})
// 查询名字为 dafei 或xiaofei用户
//sql: select * form users where name in("dafei", "xiaofei")
db.users.find({name:{$in:["古天乐","张智霖"]}})
// 判断判断指定列是否存在
db.users.find({sex:{$exists:true}})
逻辑运算符
// 逻辑运算符
语法 -> find({逻辑操作符: [条件1, 条件2, ...]})
&& 与 - $and
|| 或 - $or
! 非 - $not
// 查年龄在28 到 30间的用户信息
//sql: select * from users where age >= 28 and age <=30
db.users.find({$and:[{age:{$gte:18}},{age:{$lte:40}}]})
// 查看年龄小于28或者年龄大于30用户信息
//sql: select * from users where age <28 or age >30
db.users.find({$or:[{age:{$lt:18}},{age:{$gt:30}}]})
// 查看年龄等于28或者等于30用户信息
//sql: select * from users where age =28 or age =30
db.users.find({age:{$in:[20,30]}})
模糊查询
// 模糊查询
db.集合.find( { 列: {$regex: /关键字/} } )
//sql: select * from user where name like '%关键字%'
db.集合.find({列: {$regex: /关键字/}}) / / 表示正则对象(js)
db.集合.find({列: {$regex: "关键字"}})
// 查询name带有fei的用户信息
//sql: select * from users where name like '%fei%'
db.users.find({name:{$regex:/天/}})
// 查name中包含fei字样,并且年龄在28 到 30间的用户信息,
//sql: select * from users where name like '%fei%' and age >= 28 and age <=30
db.users.find({$and:[{name:{$regex:/天/}},{age:{$gte:10}},{age:{$lte:40}}]})
切记三条原则
1>所见所得
2>隐藏字段
3>关联关系
文档嵌套
数组方式
pom.xml
org.springframework.boot
spring-boot-starter-parent
2.4.3
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
test
org.projectlombok
lombok
org.springframework.boot
spring-boot-starter-data-mongodb
application.properties文件配置
# 配置数据库连接
#格式: mongodb://账号:密码@ip:端口/数据库?认证数据库
不展示 按照格式来即可
# 配置MongoTemplate的执行日志
logging.level.org.springframework.data.mongodb.core=debug
创建domain
@AllArgsConstructor
@NoArgsConstructor
@Setter
@Getter
@ToString
@Document("users") //设置文档所在的集合
public class User {
//文档的id使用ObjectId类型来封装,并且贴上@Id注解,
// 自动映射为_id 自动封装ObjectId
// private ObjectId _id;
@Id
private String id; // 等价_id
// private String id; // 对应删掉数据的id
private String name;
private Integer age;
}
新建repository-->UserRepository
public interface UserRepository extends MongoRepository {
}
存在三个问题
1>自定义接口的UserRepository没看到扫描 为啥测试类可以直接使用
-->项目启动之后Spring-data-mongo自动扫描所有继承MongoRepository接口类,自动动态代理
2>自定义接口MongoRepository没有写crud方法 测试类中可以使用crud方法
因为继承了MongoRepository接口 继承器crud方法
3>如果想在UserRepository接口中自定义方法怎么办
要求-->只能做查询操作
-->查询方法定义要求符合一定格式
规则-->前缀 + 操作符 + 属性
属性-->实体类的字段/表的列
上面规范叫做JPA查询规范
上述操作如果做简单条件查询非常好用.如果高级查询JPA操作方式无法适用
新建service
接口
public interface IUserService {
void save(User user);
void delete(String id);
void update(User user);
User get(String id);
List list();
}
实现类
update和save实现方法一样
@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); // update
}
@Override
public User get(String id) {
// jdk8推出的封装对象 为了配合lambda语法
// 查看实际实例对象
System.err.println(userRepository.getClass()); // class com.sun.proxy.$Proxy65 动态代理
Optional op = userRepository.findById(id);
return op.get();
}
@Override
public List list() {
return userRepository.findAll();
}
}
创建测试类
@SpringBootTest
public class UserTest {
@Autowired
private IUserService userService;
@Test
public void testSave(){
User user = new User();
user.setName("yfct");
user.setAge(18);
userService.save(user);
}
@Test
public void testUpdate(){
User user = new User();
user.setId("6265333ec03a00008b005d46");
user.setName("黑丰息");
user.setAge(18);
userService.update(user);
}
@Test
public void testDelete(){
userService.delete("626553cd8b7eb7738652fb43");
}
@Test
public void testGet(){
System.out.println(userService.get("62652efbc03a00008b005d44"));
}
@Test
public void testList(){
System.out.println(userService.list());
}
}