一.MongoDB简介以及使用场景
MongoDB 是一个跨平台的,面向文档的数据库,是当前 NoSQL 数据库产品中最热门的一种。它介于关系数据库和非关系数据库之间,是非关系数据库当中功能最丰富,最像关系数据库的产品。它支持的数据结构非常松散,是类似 JSON 的 BSON 格式,因此可以存储比较复杂的数据类型。
1.特点
MongoDB 最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查
询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。它是一个面向集合的,模式自由的文档型数据库。
具体特点总结如下:
(1)面向集合存储,易于存储对象类型的数据
(2)模式自由
(3)支持动态查询
(4)支持完全索引,包含内部对象
(5)支持复制和故障恢复
(6)使用高效的二进制数据存储,包括大型对象(如视频等)
(7)自动处理碎片,以支持云计算层次的扩展性
(8)支持 Python,PHP,Ruby,Java,C,C#,Javascript,Perl 及 C++语言的驱动程
序,
社区中也提供了对 Erlang 及.NET 等平台的驱动程序
(9) 文件存储格式为 BSON(一种 JSON 的扩展)
2.体系结构
与mysql相比较
3.数据类型
基本数据类型
null:用于表示空值或者不存在的字段,{“x”:null}
布尔型:布尔类型有两个值true和false,{“x”:true}
数值:shell默认使用64为浮点型数值。{“x”:3.14}或{“x”:3}。对于整型值,可以使用NumberInt(4字节符号整数)或NumberLong(8字节符号整数),{“x”:NumberInt(“3”)}{“x”:NumberLong(“3”)}
字符串:UTF-8字符串都可以表示为字符串类型的数据,{“x”:“呵呵”}
日期:日期被存储为自新纪元依赖经过的毫秒数,不存储时区,{“x”:new Date()}
北京市昌平区建材城西路金燕龙办公楼一层 电话:400-618-9090
正则表达式:查询时,使用正则表达式作为限定条件,语法与JavaScript的正则表达式相
同,{“x”:/[abc]/}
数组:数据列表或数据集可以表示为数组,{“x”: [“a“,“b”,”c”]}
内嵌文档:文档可以嵌套其他文档,被嵌套的文档作为值来处理,{“x”:{“y”:3 }}
对象Id:对象id是一个12字节的字符串,是文档的唯一标识,{“x”: objectId() }
二进制数据:二进制数据是一个任意字节的字符串。它不能直接在shell中使用。如果要
将非utf-字符保存到数据库中,二进制数据是唯一的方式。
代码:查询和文档中可以包括任何JavaScript代码,{“x”:function(){/…/}}
4.使用场景
温度 湿度 的记录
驾车记录
评论数据
一般都是数据不太重要,而且不做修改的,这样的数据适合用MongoDB
二.java操作mongoDB
安装 window版 一路next 就ok了
window安装: mongod.exe 服务端名称
mongo.exe 客户端
mongod.exe --dbpath=磁盘目录名
默认端口 : 27017
默认连接名称为:"test"
docker安装:
连接注意添加: mongo.exe + 端口号
1.创建数据库 user 数据库名称 如果有就是直接使用,反之创建
2.创建集合(collection) -新增文档需要指定集合名称 db.集合名称.insert({"x":"y"})文档标识手动指派,也是通过mongodb自动生成
db.spit.insert({
"content": "快过年了,心里好激动",
"createtime": new Date()
})
3.修改 db.集合名称.update({"":""},{"":""})
两个bson对象 问题:修改后不包含原始文档字段,将旧的跟新为nul,
如何解决: 使用修改器进行修改
db.集合名称.update({修改条件},{$set:{修改的内容}}) 注意:修改器中的内容必须加引号 key值可以不加
db.spit.update({"_id":ObjectId("5c4c236b58fa5217ec0046c7")},{$set:{"content":"真的快过年了,激动激动"}})
4.删除文档 db.spit.remove({删除记录的条件})
db.spit.remove({"_id":"1"})
5.查询: 统计条数
db.spt.find() 查询所有
db.spit.findOne()
db.spit.count({"":""}) 可以指定
模糊查询: db.spit.find(content:/匹配字符串/)
^ 以XX开头匹配
大于.小于,不等于:gt lt ne
db.spit.find({visits:{$gt:100}})
包含与不包含:db.spit.find(_id:{$in:["1","2"]})
条件连接: $and 条件必须满足 $or 或者 条件有即可 db.spit.find({$and:[{条件一},{条件二}]})
列值增长: db.spit.update({条件},{$inc:{字段:步长}})
java代码操作MongoDB:
public class Montest {
//初始参数
MongoClient mongoClient = null;
MongoDatabase mongoDatabase = null;
MongoCollection<Document> collection = null;
@Before
public void init(){
//1.获取连接对象mongoClient
mongoClient = new MongoClient("192.168.72.135",27017);
//2.获得集合mongoCollection
mongoDatabase = mongoClient.getDatabase("tensquare");
//3.通过集合实现crud操作
//获得集合
collection = mongoDatabase.getCollection("spit");
}
@After
public void destory(){
//4.关闭资源
mongoClient.close();
}
//查询所有的集合
@Test
public void findAll(){
//查询
FindIterable<Document> documents = collection.find();
for (Document document : documents) {
System.out.println(document.toString());
}
}
//指定条件查询
@Test
public void find(){
Bson bson = new BasicDBObject("_id","2");
FindIterable<Document> documents = collection.find(bson);
for (Document document : documents) {
System.out.println(document.toString());
}
}
//添加
@Test
public void add(){
Map map = new HashMap();
map.put("content","今天过得很充实");
map.put("visits",9);
Document document = new Document(map);
collection.insertOne(document);
}
//修改
@Test
public void update(){
Bson queryBson = new BasicDBObject("_id", "2");
//使用修改器修改
Bson updateBson = new BasicDBObject("$set", new BasicDBObject("content", "测试修改"));
UpdateResult updateResult = collection.updateOne(queryBson, updateBson);
System.out.println(updateResult);
}
//删除
@Test
public void delete(){
Bson queryBson = new BasicDBObject("_id", "2");
collection.deleteOne(queryBson);
}
}
springDataMongoDB操作数据库:
两种方法,实现,第一中,通过提供的MongoDBTemplate
第二种是接口继承 MongodbResportis
三.吐槽微服务开发
需求分析:
MongoDB数据库表结构:
搭建环境,编写配置文件,编写启动类,创建包结构三层
代码:
controller层:
@RestController
@RequestMapping("/spit")
public class SpitController {
@Autowired
private SpitService spitService;
@Autowired
private RedisTemplate redisTemplate;
//增加
@PostMapping
public Result add(@RequestBody Spit spit){
spitService.add(spit);
return new Result(true, StatusCode.OK,"添加成功");
}
//修改
@PutMapping("/{spitId}")
public Result update(@PathVariable String spitId,@RequestBody Spit spit){
spit.set_id(spitId);
spitService.update(spit);
return new Result(true, StatusCode.OK,"修改成功");
}
//查询
@GetMapping
public Result findAll(){
List<Spit> lists = spitService.findAll();
return new Result(true, StatusCode.OK,"查询成功",lists);
}
//根据id查询
@GetMapping("/{spitId}")
public Result findAll(@PathVariable String spitId){
Spit list = spitService.findOne(spitId);
return new Result(true, StatusCode.OK,"查询成功",list);
}
//删除
@DeleteMapping("/{spitId}")
public Result delete(@PathVariable String spitId){
spitService.deleteById(spitId);
return new Result(true, StatusCode.OK,"删除成功");
}
//根据上级id查询吐槽数据
@GetMapping("/comment/{parentid}/{page}/{size}")
public Result findByParentId(@PathVariable String parentId,@PathVariable int page,@PathVariable int size){
Page<Spit> pageDate = spitService.findByPage(parentId,page,size);
return new Result(true,StatusCode.OK,"查询成功",new PageResult<Spit>(pageDate.getTotalElements(),pageDate.getContent()));
}
//吐槽点赞 注意我们还要控制每个人只能点赞一次
@PutMapping("/thumbup/{spitId}")
public Result thumbup(@PathVariable String spitId){
//浏览
spitService.updateVistis(spitId);
//判断用户是否点赞
String userid = "2300";
if (redisTemplate.opsForValue().get("thumbup_"+userid+"_"+spitId)!=null){
//说明已经点过赞了
return new Result(true, StatusCode.ERROR,"您已经点过赞了,请勿重复点赞");
}
spitService.updateThumbup(spitId);
redisTemplate.opsForValue().set("thumbup_"+userid+"_"+spitId,1);
return new Result(true, StatusCode.OK,"点赞成功");
}
//增加分享数
service层:
@Service
public class SpitService {
@Autowired
private SpitDao spitDao;
@Autowired
private IdWorker idWorker;
@Autowired
private MongoTemplate mongoTemplate;
/**
* 吐槽或者评论
* @param spit
*/
public void add(Spit spit) {
spit.set_id(idWorker.nextId()+"");//发布id
spit.setPublishtime(new Date());//发布时间
spit.setVisits(0);//浏览量
spit.setShare(0);//分享数
spit.setThumbup(0);//点赞数
spit.setComment(0);//回复数
spit.setState("1");//状态
//判断是否有父id 如果有就是评论,反之就是发布吐槽
if (spit.getParentid()!=null&&!"".equals(spit.getParentid())){
//评论
Query query = new Query();
query.addCriteria(Criteria.where("_id").is(spit.getParentid()));
Update update = new Update();
mongoTemplate.updateFirst(query,update,"spit" );
}
//反之就是发布吐糟
spitDao.save(spit);
}
/**
* 修改
* @param spit
*/
public void update(Spit spit) {
spitDao.save(spit);
}
/**
* 查询所有
* @return
*/
public List<Spit> findAll() {
return spitDao.findAll();
}
/**
* 通过id查询
* @param spitId
* @return
*/
public Spit findOne(String spitId) {
Optional<Spit> option = spitDao.findById(spitId);
return option.isPresent()?option.get():null;
}
//通过id删除
public void deleteById(String spitId) {
spitDao.deleteById(spitId);
}
//根据父id查找评论
public Page<Spit> findByPage(String parentId, int page, int size) {
//封装pageable对象
PageRequest pagresult = PageRequest.of(page-1,size);
return spitDao.findByParentid(parentId, pagresult);
}
//点赞
public void updateThumbup(String spitId) {
Query query = new Query();
//构建查询条件
query.addCriteria(Criteria.where("_id").is(spitId));
Update update = new Update();
update.inc("thumbup",1);
mongoTemplate.updateFirst(query,update,"spit");
}
//浏览量
public void updateVistis(String spitId) {
Query query = new Query();
//构建
}
dao:
public interface SpitDao extends MongoRepository<Spit,String>{
/**
* 根据父id查询评论
*/
public Page<Spit> findByParentid(String parentid, Pageable pageable);
}
四.文章评论功能开发
需求分析:
完成专栏的文章的评论,注意如果父id是0代表的是顶级评论
数据库表:
步骤:
首先我们导入相关的jar包
编写配置文件
编写持久化类
controller层:
@RestController
@CrossOrigin
@RequestMapping("/comment")
public class CommentController {
@Autowired
private CommentService commentService;
//添加评论
@PostMapping
public Result comment(@RequestBody Comment comment){
commentService.save(comment);
return new Result(true, StatusCode.OK,"评论成功");
}
service:
@Service
public class CommentService {
@Autowired
private IdWorker idWorker;
@Autowired
private CommentDao commentDao;
/**
* 添加评论
*/
public void save(Comment comment) {
comment.set_id(idWorker.nextId()+"");
comment.setPublishdate(new Date());
commentDao.save(comment);
}
测试:
五.面试问题总结
1.你在项目中有没有使用到mongodb?
使用了
你的工程是如何操作MongoDB的?
spring data mongodb
在项目的哪些场景下使用MongoDB ?
吐槽 、文章评论
为什么在吐槽和文章评论中使用Mongodb而不使
用mysql?
吐槽和评论都是数据量较大且价值较低的数据,为了减轻mysql的压力,我们使用
mongodb