MongoDB基本使用介绍及SpringDataMongoDB框架常用方法

MongoDB

1.MongoDB简介

Mongo是一个跨平台的,面向文档的数据库,介于关系型和非关系型的一种数据库,是NoSQL(非关系型)数据库中比较热门的的一种

2.MongoDB特点

mongodb的数据结构十分的松散,是类似于JSON的BSON的格式,可以存储比较复杂的信息,支持完全索引,使用高效的二进制数据存储,支付复制和故障恢复

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.基本用法

1.增加

  • db.collections.insert(data) // 集合不存在会自己创建

eg:

db.student.insert({
    "age":NumberInt(18),    // 使用整数的时候 要使用NumbetInt(Int)
    "name":"Tyrone",
    "sex","male"
})
  • db.collection.save(data) //集合不存在会自己创建
db.student.save({
    "age":NumberInt(18),    // 使用整数的时候 要使用NumbetInt(Int)
    "name":"Tyrone",
    "sex","male"
})

2. 删除

  • db.collection.remove({条件})

eg:

db.student.remove({})   //全部删除
db.student.remove({		//删除 name 为 tyrone的数据
  "name":"tyrone"         
})                 

3.修改

  • db.collection.update({修改值})

​ eg:假设之前数据库之中已经有 name:tyrone age:20 ,sex:male这个数据

db.student.update({
	"name":"tyrone",
	"age":"19"
})

值得注意的是,这个时候,不修改的字段就变成null,原本的sex:male 就会变成sex:null ,也就是说mongoDB默认的是全字段修改。那么如何只对指定字段修改呢?

  • db.collection.update({$set:{data}})

​ 使用$set修改器,修改指定字段

​ eg:

db.student.update({
	"name":"tyrone"},{$set:{"age":"18"}}"   // 先指定要查询的的是name:tyrone的Document,然后通过$set修改指定属性 age 为18
})
  • db.collection.update({条件},{$inc:{data}}) // 原有基础上增加或减少

eg:

db.student.find({
    "name":"tyrone",                 //先查询tyrone 这个学生,并在原有基础上将年龄增加10 相当于 age+=10
    $inc:{"age":NumberInt(10)}
})

4.查询

  • db.collection.find() //查询collection下所有的Document

eg:

db.student.find()
  • db.collection.find({条件}) //条件查询

eg:

db.student.find({			//查询student下所有 age:18的document
    "age":"18"
})
  • db.collection.find({“field”:/content/})模糊查询

eg

db.student.find({    //模糊查询name中包含‘天’的document
    "name"://
})
db.student.find({
    "name":/^/    //查找name中以‘刘’开头的document
})
  • 复杂查询

    • 计算条目
      • db.collection.count()

    eg:

    db.student.count() //计算student的数量
    
    • 存在、不存在
      • db.collection.find({“field”:{$exist{}})

    eg:

    db.student.find("address":{$exist:true})  //查询存在address字段的document $exist:false 为不存在。
    
    • 大于,小于,不等于(比较)
      • db.collection.find({ “field” : { $gt: value }}) // 大于: field > value
      • db.collection.find({ “field” : { $lt: value }}) // 小于: field < value
      • db.collection.find({ “field” : { $gte: value }}) // 大于等于: field >= value
      • db.collection.find({ “field” : { $lte: value }}) // 小于等于: field <= value
      • db.collection.find({ “field” : { $ne: value }}) // 不等于: field != value

    eg:

    db.student.find({
        "age":{
            $gt: 18    //查询student中age字段 等于18的document
        }
    })
    
    • 包含不包含
      • db.collection.find({“field”:{$in:[data]}})

    eg:

    db.student.find({    "age":{$in:[18,19,20]}         //查询age在18,19,20中的数据 $in包含 $nin})
    
    • 条件连接

      • db.collection.find({KaTeX parse error: Expected 'EOF', got '}' at position 15: and[{条件},{条件}]}̲) //and 并且
      • db.collection.find({KaTeX parse error: Expected 'EOF', got '}' at position 14: or[{条件},{条件}]}̲) //or 或者

      eg:

    db.student.find({              //查询student中age >=18 <25的document    $and:[{        ”age:{            $gte: 18        }    },{        "age":{            $lt:25        }    }]})
    

5.SpringDataMongoDB

1.引入依赖

<dependency> 
    <groupId>org.springframework.boot</groupId> 
    <artifactId>spring‐boot‐starter‐data‐mongodb</artifactId> 
</dependency>

2.配置文件application.yml

spring:
	data:
		mongodb:
			host: 127.0.0.1    #mongodb地址
			database: test	   #数据库名称

3.常用方法

1.自定义接口并继承MongoRepository接口
public interface CommentDao extends MongoRepository<Comment,String > {
    /**
     * 根据商品ID查询评论列表
     * @param goodsid 文章ID
     * @return
     */
    public Page<Comment> findByGoodsid(String goodsid,Pageable pageable);

    /**
     * 查找当前的商品或者评论的所有评论
     * @param parentId
     * @return
     */
    public Page<Comment> findByParentid(String parentId, Pageable pageable);

}

继承MongoRepository之后,就可以像使用其他SpringData框架一样使用他,此时遵守Spring Data Jpa 方法定义规范,看一下官方文章支持的写法

在这里插入图片描述

在这里插入图片描述

service层:

@Service
@Transactional
public class CommentService {

    @Autowired
    private CommentDao commentDao;

    @Autowired
    private IdWorker idWorker;

    public void addGoodsComment(Comment comment){
        comment.set_id(idWorker.nextId()+"");
        comment.setPublish_date(new Date());
        commentDao.save(comment);           //插入数据,原有数据会给覆盖
    }

    public Page<Comment> findCommentByParentId(String parentId, int page, int size){
        Pageable pageable = PageRequest.of(page-1,size);
        return commentDao.findByParentid(parentId,pageable);    //根据parentId查询,开启分页
    }

    public Page<Comment> findCommentByGoodsId(String goodsid,int page,int size){
        Pageable pageable=PageRequest.of(page-1,size);
        return commentDao.findByGoodsid(goodsid,pageable);    //根据goodsid查询 ,开启分页
    }

    public void deleteGoodsComment(String id){
        commentDao.deleteById(id);             //根据id删除
    }

    public List<Comment> findAllGoodsComment(){
        return commentDao.findAll();    //查询所有
    }

    public Comment findCommentById(String id) throws Exception{
        return commentDao.findById(id).get();   //根据id查询
    }
}

2.使用mongoTemplate
public class Message implements Serializable {
    @Id
    private String id;
    private String msg;

    @Indexed
    private Integer status; //0-未读 1-已读  -1 - 删除
    @Field("send_date")
    private Date sendDate;
    @Field("read_date")
    private Date readDate;
    @Indexed
    private User from;
    @Indexed
    private User to;
}

@Service
public class MessageService {

    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private MessageDao messageDao;
    @Autowired
    private RabbitTemplate rabbitTemplate;


    //查询符合条件的第一条数据
    public Message queryLastMessage(String fromId,String toId){
        Query query = new Query();
        query.addCriteria(Criteria.where("from.id").is(fromId).and("toId").is(toId)).with(Sort.by(Sort.Order.desc("send_date")));
        Message message = mongoTemplate.findOne(query, Message.class);
        return message;

    }

    /**
     *查询所有信息
     * @return
     */
    public List<Message> findAll(){
        return messageDao.findAll();
    }

   //更新指定document指定字段
    public void updateMessStatusById(String id, Integer status){
        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(id));
        Update update = new Update();
        update.set("status",status);
        mongoTemplate.updateFirst(query,update,"message");

    }

    //使用BulkOperations 批量更新指定字段
    public void updateMessListById(List<String> ids,Integer status){
        BulkOperations operations = mongoTemplate.bulkOps(BulkOperations.BulkMode.UNORDERED,"message");
        ids.forEach(date->{
            Query query = new Query();
            query.addCriteria(Criteria.where("_id").is(date));
            Update update = new Update();
            update.set("status",status);
            update.set("readDate",new Date());
            operations.updateOne(query,update);
        });
        BulkWriteResult execute = operations.execute();
    }

   
    public List<Message> queryMessageList(String fromId, String toId, Integer page, Integer size) {
        Pageable pageable =PageRequest.of(page-1,size);
        Query query = new Query();   query.addCriteria(Criteria.where("from.id").is(fromId).and("to.id").is(toId).and("status").ne(-1)).with(pageable);
        List<Message> messages = mongoTemplate.find(query, Message.class);
        return messages;
    }
    //条件删除
    public void deleteMessageList(String fromId, String toId) {
        Query query = new Query();
        query.addCriteria(Criteria.where("from._id").is(fromId).and("to._id").is(toId));
        Update update = new Update();
        update.set("status",-1);
        mongoTemplate.updateMulti(query,update,"message");
    }
    //根据Message下User的id的复杂查询
    public List<Message> getUnReadMsgList(String acceptUserId) {
        Query query = new Query();
        query.addCriteria(new Criteria("to._id").is(acceptUserId).and("status").is(0));
        List<Message> messages = mongoTemplate.find(query, Message.class);
        return messages;
    }
}

MongoTemplate模板类中还有很多方法,感兴趣可以自己看一下一般来说需要用到操作符的话我个人更加倾向于这种方法

3.总结:

第一种方式比较方便,第二种功能更为强大

写在最后

实际上mongo官方针对java推了专门的驱动包——mongodb-drive,采用这种方式可以操作mongodb,但是我个人觉得这种方式比较复杂,所以就不做介绍了,但是其中的个别方法还是可以值得的。

eg:

MongoClient client=new MongoClient("192.168.184.134");//创建连接 
MongoDatabase message = client.getDatabase("message");//打开数据库 
MongoCollection<Document> spit = spitdb.getCollection("message");// 获取集合

mongodb的适用环境:

1.数据量大

2.数据价值量较低 (数据库可能丢失一两条数据,丢失的数据对整个系统的而言价值量较低)

3.读写频繁

你可能感兴趣的:(随笔总结,mongodb,java,spring)