SpringBoot 快速使用mongodb

前言

  • 1、为什么要使用mongodb?


    image.png
  • 2、什么场景下使用mongdb?
    • 应用不需要事务及复杂 join 支持必须
    • 新应用,需求会变,数据模型无法确定,想快速迭代开发
    • 应用需要2000-3000以上的读写QPS(更高也可以)
    • 应用需要TB甚至 PB 级别数据存储
    • 应用发展迅速,需要能快速水平扩展
    • 应用要求存储的数据不丢失
    • 应用需要99.999%高可用
    • 应用需要大量的地理位置查询、文本查询
      如果上述有1个 Yes,可以考虑 MongoDB,2个及以上的 Yes,选择MongoDB绝不会后悔

SpringBoot快速使用

配置

1、pom.xml配置

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

2、application.propertiesp配置

spring.data.mongodb.uri=mongodb://192.168.0.13/test

完整配置

spring.data.mongodb.authentication-database= # Authentication database name.
spring.data.mongodb.database= # Database name.
spring.data.mongodb.field-naming-strategy= # Fully qualified name of the FieldNamingStrategy to use.
spring.data.mongodb.grid-fs-database= # GridFS database name.
spring.data.mongodb.host= # Mongo server host. Cannot be set with URI.
spring.data.mongodb.password= # Login password of the mongo server. Cannot be set with URI.
spring.data.mongodb.port= # Mongo server port. Cannot be set with URI.
spring.data.mongodb.repositories.type=auto # Type of Mongo repositories to enable.
spring.data.mongodb.uri=mongodb://localhost/test # Mongo database URI. Cannot be set with host, port and credentials.
spring.data.mongodb.username= # Login user of the mongo server. Cannot be set with URI.

配置好了之后就直接可以注入MongoTemplate操作数据了

增/删/改/查例子

1、增

首先创建一个实体类,我们这边用文章来做实体类,定义如下字段:

import java.util.Date;
import java.util.List;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;
/**
 * 文章信息
 * @author yinjihuan
 *
 */
@Document(collection = "article_info")
public class Article {
    @Id
    private String id;
    @Field("title")
    private String title;
    @Field("url")
    private String url;
    @Field("author")
    private String author;
    @Field("tags")
    private List<String> tags;
    @Field("visit_count")
    private Long visitCount;
    @Field("add_time")
    private Date addTime;
    
    //省略get set方法
}

实体类中的注解解释如下:
1.Document注解标识这是一个文档,等同mysql中的表,collection值表示mongodb中集合的名称,不写默认为实体类名article。
2.Id注解为主键标识
3.Field注解为字段标识,指定值为字段名称,这边有个小技巧,之所有spring-data.mongodb中有这样的注解,是为了能够让用户自定义字段名称,可以和实体类不一致,还有个好处就是可以用缩写,比如username我们可以配置成unane或者un,这样的好处是节省了存储空间,mongodb的存储方式是key value形式的,每个key就会重复存储,key其实就占了很大一份存储空间。
接下来可以操作数据库了,接着上次,在测试类里写代码

@Autowired
private MongoTemplate mongoTemplate;

/**
 * 初始化文章信息
 * @author yinjihuan
 */
public static void initArticle() {
    //循环添加
    for (int i = 0; i < 10; i++) {
        Article article = new Article();
        article.setTitle("MongoTemplate的基本使用");
        article.setAuthor("yinjihuan");
        article.setUrl("http://cxytiandi.com/blog/detail/" + i);
        article.setTags(Arrays.asList("java", "mongodb", "spring"));
        article.setVisitCount(0L);
        article.setAddTime(new Date());
        mongoTemplate.save(article);
    }
    
    //批量添加
    List<Article> articles = new ArrayList<>(10);
    for (int i = 0; i < 10; i++) {
        Article article = new Article();
        article.setTitle("MongoTemplate的基本使用");
        article.setAuthor("yinjihuan");
        article.setUrl("http://cxytiandi.com/blog/detail/" + i);
        article.setTags(Arrays.asList("java", "mongodb", "spring"));
        article.setVisitCount(0L);
        article.setAddTime(new Date());
        articles.add(article);
    }
    mongoTemplate.insert(articles, Article.class);
  
}

在数据量大的情况下批量添加性能会更好哦。

2、删
//删除author为yinjihuan的数据
Query query = Query.query(Criteria.where("author").is("yinjihuan"));
mongoTemplate.remove(query, Article.class);


//如果实体类中没配集合名词,可在删除的时候单独指定article_info
query = Query.query(Criteria.where("author").is("yinjihuan"));
mongoTemplate.remove(query, "article_info");

//删除集合,可传实体类,也可以传名称
mongoTemplate.dropCollection(Article.class);
mongoTemplate.dropCollection("article_info");

//删除数据库
mongoTemplate.getDb().dropDatabase();

下面这2种适合要知道删除的数据有哪些的场景,比如记录删除的记录

//查询出符合条件的第一个结果,并将符合条件的数据删除,只会删除第一条
query = Query.query(Criteria.where("author").is("yinjihuan"));
Article article = mongoTemplate.findAndRemove(query, Article.class);

//查询出符合条件的所有结果,并将符合条件的所有数据删除
query = Query.query(Criteria.where("author").is("yinjihuan"));
List<Article> articles = mongoTemplate.findAllAndRemove(query, Article.class);



1、改

首先初始化需要修改的数据

{
    "_id": ObjectId("57c43caed4c63d7e39b5dc48"),
    "title": "MongoTemplate的基本使用",
    "url": "http://cxytiandi.com/blog/detail/0",
    "author": "yinjihuan",
    "tags": [
        "java",
        "mongodb",
        "spring"
    ],
    "visit_count": 0,
    "add_time": ISODate("2016-08-29T13:46:21.881Z")
}
{
    "_id": ObjectId("57c43caed4c63d7e39b5dc49"),
    "title": "MongoTemplate的基本使用",
    "url": "http://cxytiandi.com/blog/detail/1",
    "author": "yinjihuan",
    "tags": [
        "java",
        "mongodb",
        "spring"
    ],
    "visit_count": 0,
    "add_time": ISODate("2016-08-29T13:46:22.201Z")
}

java 代码

//修改第一条author为yinjihuan的数据中的title和visitCount
Query query = Query.query(Criteria.where("author").is("yinjihuan"));
Update update = Update.update("title", "MongoTemplate").set("visitCount", 10);
mongoTemplate.updateFirst(query, update, Article.class);


修改后结果如下,我们会发现第一条数据的title还有visit_count被修改了

{
    "_id": ObjectId("57c43caed4c63d7e39b5dc48"),
    "title": "MongoTemplate",
    "url": "http://cxytiandi.com/blog/detail/0",
    "author": "yinjihuan",
    "tags": [
        "java",
        "mongodb",
        "spring"
    ],
    "visit_count": 10,
    "add_time": ISODate("2016-08-29T13:46:21.881Z")
}
{
    "_id": ObjectId("57c43caed4c63d7e39b5dc49"),
    "title": "MongoTemplate的基本使用",
    "url": "http://cxytiandi.com/blog/detail/1",
    "author": "yinjihuan",
    "tags": [
        "java",
        "mongodb",
        "spring"
    ],
    "visit_count": 0,
    "add_time": ISODate("2016-08-29T13:46:22.201Z")
}

修改全部符合条件的

//修改全部符合条件的
query = Query.query(Criteria.where("author").is("yinjihuan"));
update = Update.update("title", "MongoTemplate").set("visitCount", 10);
mongoTemplate.updateMulti(query, update, Article.class);

特殊更新,更新author为jason的数据,如果没有author为jason的数据则以此条件创建一条新的数据

//特殊更新,更新author为jason的数据,如果没有author为jason的数据则以此条件创建一条新的数据
//当没有符合条件的文档,就以这个条件和更新文档为基础创建一个新的文档,如果找到匹配的文档就正常的更新。
query = Query.query(Criteria.where("author").is("jason"));
update = Update.update("title", "MongoTemplate").set("visitCount", 10);
mongoTemplate.upsert(query, update, Article.class);

修改后结果如下,我们会发现新增了一条数据

{
    "_id": ObjectId("57c43caed4c63d7e39b5dc48"),
    "title": "MongoTemplate",
    "url": "http://cxytiandi.com/blog/detail/0",
    "author": "yinjihuan",
    "tags": [
        "java",
        "mongodb",
        "spring"
    ],
    "visit_count": 10,
    "add_time": ISODate("2016-08-29T13:46:21.881Z")
}
{
    "_id": ObjectId("57c43caed4c63d7e39b5dc49"),
    "title": "MongoTemplate",
    "url": "http://cxytiandi.com/blog/detail/1",
    "author": "yinjihuan",
    "tags": [
        "java",
        "mongodb",
        "spring"
    ],
    "visit_count": 10,
    "add_time": ISODate("2016-08-29T13:46:22.201Z")
}
{
    "_id": ObjectId("57c6e1601e4735b2c306cdb7"),
    "author": "jason",
    "title": "MongoTemplate",
    "visit_count": 10
}

更新条件不变,更新字段改成了一个我们集合中不存在的,用set方法如果更新的key不存在则创建一个新的key

//更新条件不变,更新字段改成了一个我们集合中不存在的,用set方法如果更新的key不存在则创建一个新的key
query = Query.query(Criteria.where("author").is("jason"));
update = Update.update("title", "MongoTemplate").set("money", 100);
mongoTemplate.updateMulti(query, update, Article.class);


修改后结果如下,我们会发现新加了一个ke

{
    "_id": ObjectId("57c6e1601e4735b2c306cdb7"),
    "author": "jason",
    "title": "MongoTemplate",
    "visit_count": 10,
    "money":100
}

update的inc方法用于做累加操作,将money在之前的基础上加上100

//update的inc方法用于做累加操作,将money在之前的基础上加上100
query = Query.query(Criteria.where("author").is("jason"));
update = Update.update("title", "MongoTemplate").inc("money", 100);
mongoTemplate.updateMulti(query, update, Article.class);

修改列名

//update的rename方法用于修改key的名称
query = Query.query(Criteria.where("author").is("jason"));
update = Update.update("title", "MongoTemplate").rename("visitCount", "vc");
mongoTemplate.updateMulti(query, update, Article.class);


{
    "_id": ObjectId("57c6e1601e4735b2c306cdb7"),
    "author": "jason",
    "title": "MongoTemplate",
    "vc": 10,
    "money":200
}

删除key

//update的unset方法用于删除key
query = Query.query(Criteria.where("author").is("jason"));
update = Update.update("title", "MongoTemplate").unset("vc");
mongoTemplate.updateMulti(query, update, Article.class);

{
    "_id": ObjectId("57c6e1601e4735b2c306cdb7"),
    "author": "jason",
    "title": "MongoTemplate",
    "money":200
}


update的pull方法用于删除tags数组中的java

//update的pull方法用于删除tags数组中的java
query = Query.query(Criteria.where("author").is("yinjihuan"));
update = Update.update("title", "MongoTemplate").pull("tags", "java");
mongoTemplate.updateMulti(query, update, Article.class);

{
    "_id": ObjectId("57c43caed4c63d7e39b5dc48"),
    "title": "MongoTemplate",
    "url": "http://cxytiandi.com/blog/detail/0",
    "author": "yinjihuan",
    "tags": [
        "mongodb",
        "spring"
    ],
    "visit_count": 10,
    "add_time": ISODate("2016-08-29T13:46:21.881Z")
}
{
    "_id": ObjectId("57c43caed4c63d7e39b5dc49"),
    "title": "MongoTemplate",
    "url": "http://cxytiandi.com/blog/detail/1",
    "author": "yinjihuan",
    "tags": [
        "mongodb",
        "spring"
    ],
    "visit_count": 10,
    "add_time": ISODate("2016-08-29T13:46:22.201Z")
}

1、查

查询,无论是关系型数据库还是mongodb这种nosql,都是使用比较多的,大部分操作都是读的操作。
mongodb的查询方式很多种,下面只列了一些常用的,比如:
1.=查询
2.模糊查询
3.大于小于范围查询
4.in查询
5.or查询
6.查询一条,查询全部
7.自己慢慢学习...

根据作者查询所有符合条件的数据,返回List

Query query = Query.query(Criteria.where("author").is("yinjihuan"));
List<Article> articles = mongoTemplate.find(query, Article.class);

只查询符合条件的第一条数据,返回Article对象

query = Query.query(Criteria.where("author").is("yinjihuan"));
Article article = mongoTemplate.findOne(query, Article.class);

查询集合中所有数据,不加条件

articles = mongoTemplate.findAll(Article.class);

查询符合条件的数量

query = Query.query(Criteria.where("author").is("yinjihuan"));
long count = mongoTemplate.count(query, Article.class);

根据主键ID查询

article = mongoTemplate.findById(new ObjectId("57c6e1601e4735b2c306cdb7"), Article.class);

in查询

List<String> authors = Arrays.asList("yinjihuan", "jason");
query = Query.query(Criteria.where("author").in(authors));
articles = mongoTemplate.find(query, Article.class);

ne(!=)查询

query = Query.query(Criteria.where("author").ne("yinjihuan"));
articles = mongoTemplate.find(query, Article.class);

lt(<)查询访问量小于10的文章

query = Query.query(Criteria.where("visitCount").lt(10));
articles = mongoTemplate.find(query, Article.class);

范围查询,大于5小于10

query = Query.query(Criteria.where("visitCount").gt(5).lt(10));
articles = mongoTemplate.find(query, Article.class);

模糊查询,author中包含a的数据

query = Query.query(Criteria.where("author").regex("a"));
articles = mongoTemplate.find(query, Article.class);

数组查询,查询tags里数量为3的数据

query = Query.query(Criteria.where("tags").size(3));
articles = mongoTemplate.find(query, Article.class);

or查询,查询author=jason的或者visitCount=0的数据

query = Query.query(Criteria.where("").orOperator(
    Criteria.where("author").is("jason"),
    Criteria.where("visitCount").is(0)));
articles = mongoTemplate.find(query, Article.class);

** 分页查询

 int pageSize = pageParam.getPageSize();
        final DQueueLogReq queueLog = pageParam.getParam();
        Query query = this.buildCommonWhere(queueLog);
        //查询总数
        final long count = mongoTemplate.count(query, DQueueLog.class);
        Sort sort = new Sort(Sort.Direction.DESC, DQueueLog.Fields.consumerTime);
        //分页
        query.with(new PageRequest(pageParam.getPageNo()-1, pageSize,sort));
        final List<DQueueLog> dQueueLogs = mongoTemplate.find(query, DQueueLog.class);
        PageResult<DQueueLog> pageResult =new PageResult<>();
        pageResult.setResults(dQueueLogs);
        pageResult.setPageSize(pageSize);
        pageResult.setPageNo(pageParam.getPageNo());
        pageResult.setTotalCount(count);
        final long pages = count / pageSize;
        pageResult.setPageCount(count % pageSize == 0 ? pages : pages + 1);

** 完整例子

package com.chehejia.dqueue.admin.service.impl;

import cn.hutool.core.util.StrUtil;
import com.chehejia.dqueue.admin.DqueueESDApplication;
import com.chehejia.dqueue.admin.document.DQueueLog;
import com.chehejia.dqueue.admin.model.DQueueLogReq;
import com.chehejia.dqueue.admin.service.IDQueueLogService;
import com.chehejia.framework.beans.model.page.PageParam;
import com.chehejia.framework.beans.model.page.PageResult;
import com.mongodb.WriteResult;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.stream.Stream;

/**
 * @author jack-cooper
 * @version 1.0.0
 * @ClassName DQueueLogServiceImpl.java
 * @Description 业务逻辑类
 * @createTime 2019年11月12日 16:52:00
 */
@Service
public class DQueueLogServiceImpl implements IDQueueLogService {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Override
    public DQueueLog getById(String id) {
        return mongoTemplate.findById(new ObjectId(id),DQueueLog.class);
    }

    @Override
    public List<DQueueLog> list(DQueueLogReq logReq) {
        Query query = this.buildCommonWhere(logReq);
        return mongoTemplate.find(query,DQueueLog.class);
    }

    @Override
    public void save(DQueueLog dQueueLog) {
        mongoTemplate.insert(dQueueLog);
    }

    @Override
    public void deleteById(String id) {
        mongoTemplate.remove(new ObjectId(id));
    }

    @Override
    public boolean updateById(DQueueLog dQueueLog) throws Exception {
        final Query query = Query.query(Criteria.where(DQueueLog.Fields.id).is(new ObjectId(dQueueLog.getId())));
        final Update update = new Update();
        final Class queueLogClass = dQueueLog.getClass();
        final Field[] fields = queueLogClass.getDeclaredFields();
        for (Field t : fields) {
            if(t.isAnnotationPresent(org.springframework.data.mongodb.core.mapping.Field.class)){
                //获取字段读方法
                final PropertyDescriptor pd = new PropertyDescriptor(t.getName(), queueLogClass);
                final Method method = pd.getReadMethod();
                final Object result = method.invoke(dQueueLog);
                if(result != null){
                    update.set(t.getName(), result);
                }
            }
        }
        final WriteResult result = mongoTemplate.upsert(query, update, DQueueLog.class);
        return result.isUpdateOfExisting();
    }

    @Override
    public PageResult<DQueueLog> selectPage(PageParam<DQueueLogReq> pageParam) {
        int pageSize = pageParam.getPageSize();
        final DQueueLogReq queueLog = pageParam.getParam();
        Query query = this.buildCommonWhere(queueLog);
        //查询总数
        final long count = mongoTemplate.count(query, DQueueLog.class);
        Sort sort = new Sort(Sort.Direction.DESC, DQueueLog.Fields.consumerTime);
        //分页
        query.with(new PageRequest(pageParam.getPageNo()-1, pageSize,sort));
        final List<DQueueLog> dQueueLogs = mongoTemplate.find(query, DQueueLog.class);
        PageResult<DQueueLog> pageResult =new PageResult<>();
        pageResult.setResults(dQueueLogs);
        pageResult.setPageSize(pageSize);
        pageResult.setPageNo(pageParam.getPageNo());
        pageResult.setTotalCount(count);
        final long pages = count / pageSize;
        pageResult.setPageCount(count % pageSize == 0 ? pages : pages + 1);
        return pageResult;
    }

    /**
     * 查询条件构造器
     * @param req
     * @return
     */
    private Query buildCommonWhere(DQueueLogReq req){
        Query query = new Query();
        if(!StringUtils.isEmpty(req.getId())){
            query.addCriteria(Criteria.where(DQueueLog.Fields.id).is(req.getId()));
        }
        if(!StringUtils.isEmpty(req.getEnv())){
            query.addCriteria(Criteria.where(DQueueLog.Fields.env).is(req.getEnv()));
        }
        if(!StringUtils.isEmpty(req.getTopic())){
            query.addCriteria(Criteria.where(DQueueLog.Fields.topic).is(req.getTopic()));
        }
        if(!StringUtils.isEmpty(req.getConsumerAppName())){
            query.addCriteria(Criteria.where(DQueueLog.Fields.consumerAppName).is(req.getConsumerAppName()));
        }
        if(!StringUtils.isEmpty(req.getMsgId())){
            query.addCriteria(Criteria.where(DQueueLog.Fields.msgId).is(req.getMsgId()));
        }
        if(!StringUtils.isEmpty(req.getJsonData())){
            query.addCriteria(Criteria.where(DQueueLog.Fields.jsonData).is(req.getJsonData()));
        }
        if(!StringUtils.isEmpty(req.getFromIp())){
            query.addCriteria(Criteria.where(DQueueLog.Fields.fromIp).is(req.getFromIp()));
        }
        if(!StringUtils.isEmpty(req.getToIp())){
            query.addCriteria(Criteria.where(DQueueLog.Fields.toIp).is(req.getToIp()));
        }
        if(!StringUtils.isEmpty(req.getMsg())){
            query.addCriteria(Criteria.where(DQueueLog.Fields.msg).is(req.getMsg()));
        }
        if(!StringUtils.isEmpty(req.getResendCount())){
            query.addCriteria(Criteria.where(DQueueLog.Fields.resendCount).is(req.getResendCount()));
        }
        if(!CollectionUtils.isEmpty(req.getJoinTimeList())){
            if(req.getJoinTimeList().size()>0){
                query.addCriteria(Criteria.where(DQueueLog.Fields.joinTime).gte(req.getJoinTimeList().get(0)));
            }
            if(req.getJoinTimeList().size()>1){
                query.addCriteria(Criteria.where(DQueueLog.Fields.joinTime).lte(req.getJoinTimeList().get(1)));
            }
        }
        if(!CollectionUtils.isEmpty(req.getConsumerTimeList())){
            if(req.getConsumerTimeList().size()>0){
                query.addCriteria(Criteria.where(DQueueLog.Fields.consumerTime).gte(req.getConsumerTimeList().get(0)));
            }
            if(req.getConsumerTimeList().size()>1){
                query.addCriteria(Criteria.where(DQueueLog.Fields.consumerTime).lte(req.getConsumerTimeList().get(1)));
            }
        }
        return query;
    }


}


摘自:https://juejin.im/post/5afb9de8518825426c690307
高阶更新:https://my.oschina.net/u/566591/blog/3017030

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,711评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,932评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,770评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,799评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,697评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,069评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,535评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,200评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,353评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,290评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,331评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,020评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,610评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,694评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,927评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,330评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,904评论 2 341

推荐阅读更多精彩内容

  • 1. 简介 1.1 什么是 MyBatis ? MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的...
    笨鸟慢飞阅读 5,422评论 0 4
  • 一、MongoDB简介 1.概述 ​ MongoDB是一个基于分布式文件存储的数据库,由C++语言编写。旨在为WE...
    郑元吉阅读 974评论 0 2
  • Mongodb数据库 课程介绍 Ø 数据库概述(了解) Ø NoSQL和MongoDB简介(了解) Ø Mongo...
    致自己_cb38阅读 1,749评论 0 4
  • 今天是熙悦预约的第一天,向两组客户推荐了熙悦住宅,这两组客户的第一反应都持否定态度,觉得孙娄大集这个位置太偏,项...
    王衍辉阅读 827评论 0 0
  • 复制、粘贴及其他常规的键盘快捷方式 Windows 徽标键键盘快捷方式 命令提示符键盘快捷方式 对话框键盘快捷方式...
    Ordinaire阅读 594评论 0 0