十次方day03(文档型数据库MongoDB)

一.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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奋斗的小巍

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值