MongoDB(一)--基础知识及安装部署和使用

简介

本文介绍一下非关系型数据库的特点,及MongoDB的优势和简单的部署使用MongoDB。
本文java客户端使用mongodb源码: https://github.com/itwwj/iot-project.git 中的iot-mongodb项目,其他请忽略。

一、MongoDB介绍

MongoDB是一种强大、灵活、可扩展的数据存储方式。他扩展了关系型数据库的众多有用功能,如辅助索引、范围查询和排序。MongoDB的功能非常丰富,比如内置的对MapReduce式聚合的支持,以及地理空间索引的支持。MongoDB的数据模型对开发者来说非常友好,配置选项对于管理员来说也很轻松,并且有驱动程序和数据库shell提供的自然语言式的API。
它主要有以下的优点:

  • 丰富的数据模型
  • 容易扩展
  • 丰富的功能
  • 不牺牲速度
  • 简便的管理

二、入门知识

在使用mongo前需要先来了解几个名词:
文档:
文档是MongoDB中数据的基本单元,非常类似于关系型数据库管理系统中的行。多个键及其关联的值有序地放在一起便是文档。例如:

"name":"jie"

这个文档只有一个键“name”,其对应的值为“jie”,当然在文档中可以多个键/值对。
集合:
集合就是一组文档,如果说文档相当于关系型数据库中的行,那么集合就相当于关系型数据库的表。
集合是无模式的。这就意味着一个集合里面的文档可以是各式各样的,例如,下边的两个文档可以存在一个集合中。

{"name":"hello,word!"}
{"text":"welcome!"}

集合的命名:

  • 集合名不能是空字符串“”;
  • 集合名不能含有\0字符,这个字符表示集合名的结尾;
  • 集合名不能以“system”开头,这是为系统集合保留的前缀;
  • 用户创建的集合名不能含有保留字段$;

数据库:
MongoDB中多个文档组成集合,同样多个集合可以组成数据库。一个mongo实例可以承载多个数据库,他们之间可以视为完全独立,每个数据库都有独立的权限控制。
数据库命名:

  • 不能是空字符串“”;
  • 不能含有‘’、。、$、/、\、和\0;
  • 全部小写;
  • 最多64字节;

有一些数据库名是保留的,可以直接访问这些有特殊作用的数据库:

  • admin:这个是root数据库,将一个用户添加到这个数据库,这个用户自动继承所有数据库的权限,一些特定的服务器命令也只能从这个数据库运行,比如列出所有的数据库或关闭数据库。
  • local:用来存储限于本地单台服务器的任意集合。
  • config:当MongoDB用于分片设置时,config数据库内部使用。

三、简单的安装部署

这里使用docker容器部署,编写docker启动脚本start.sh:

#!/bin/bash
cur_dir=`pwd`
mkdir `pwd`/data
docker stop mongodb
docker rm mongodb
docker run --restart=always --name mongodb \
       -p 27017:27017 \
       -v `pwd`/data/:/data/db  \
       -v `pwd`/conf/:/data/configdb  \
       -v `pwd`/backup/:/data/backup  \
       -d mongo --auth
#在将start.sh复制到linux系统后赋予权限:
chmod u+x *.sh

#修改在windows和linux换行符不一致问题:
sed -i "s/\r//" start.sh

#使用mongodb shell客户端 
docker exec -it mongodb mongo admin

#创建一个root权限用户
db.createUser({
		user:'admin',
		pwd:'public',
		roles:[
			{role:'root',db:'admin'}
		]
	})
	
#使用新创建的用户
db.auth('admin', 'public') 

#创建一个iot数据库
use iot

#创建一个iot普通用户 并分配读和写权限 指定操作iot数据库
db.createUser({
		user:'iot',
		pwd:'root',
		roles:[
			{role:'readWrite',db:'iot'}
		]
	})
	
#使用iot用户
db.auth('iot', 'root')

四、spring-data-mongodb使用MongoDB

4.1运行环境配置

添加pom依赖:

 <dependencies>
    <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>8</source>
                    <target>8</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

monogo中创建数据库:iot-test
创建集合:user

4.2代码实现简单的增删改查

配置文件application.yml:

spring:
  data:
    mongodb:
      host: 192.168.1.177
      port: 27017
      username: iot
      password: root
      database: iot
server:
  port: 9102

model层:

@Data
@NoArgsConstructor
@AllArgsConstructor
@Document(collection = "user")
public class User {
    @Id
    private String id;

    private String name;

    private Integer age;

    private String description;
}

编写通用的service层:

public interface BaseService<T> {
    /**
     * 获取service
     *
     * @return
     */
    MongoTemplate getDao();

    /**
     * 获取实体的类型
     *
     * @return
     */
    Class<T> getEntityClass();
    /**
     * 增
     *
     * @param t
     */
    default T save(T t) {
        return (T) getDao().insert(t);
    }

    /**
     * 批量增加
     *
     * @param batchToSave
     * @return
     */
    default Collection<T> saveAll(List<T> batchToSave) {
        return getDao().insert(batchToSave, getEntityClass());
    }

    /**
     * 条件删除(物理删除)
     *
     * @param query
     * @return
     */
    default void delByQuery(Query query) {
        getDao().remove(query, getEntityClass());
    }


    /**
     * 改
     *
     * @param t
     */
    default T update(T t) {
        return (T) getDao().save(t);
    }

    /**
     * 批量修改
     *
     * @return
     */
    default UpdateResult updateByQuery(Query query, Update update) {
        return getDao().updateMulti(query, update, getEntityClass());
    }

    /**
     * 条件修改,当没有符合条件的文档,就以这个条件和更新文档为基础创建一个新的文档,如果找到匹配的文档就正常的更新
     *
     * @param query
     * @param t
     * @return
     */
    default UpdateResult upsert(Query query, T t) {
        Map<String, Object> map = BeanUtil.beanToMap(t);
        Update update = new Update();
        for (String s : map.keySet()) {
            if (map.get(s) != null) {
                update.set(s, map.get(s));
            }
        }
        return getDao().upsert(query, update, getEntityClass());
    }


    /**
     * 累加操作
     *
     * @param query
     * @return
     */
    default UpdateResult updateInc(Query query, String field, Number value) {
        Update update = new Update();
        update = update.inc(field, value);
        return updateByQuery(query, update);
    }

    /**
     * 查
     *
     * @param id
     * @return
     */
    default T findById(Object id) {
        return getDao().findOne(Query.query(Criteria.where("id").is(id)), getEntityClass());
    }

    /**
     * 分页查询
     *
     * @param pageRequest
     * @return
     */
    default Page<T> findPage(PageRequest pageRequest) throws ParseException {
        Query query = new Query();
        int count = (int) getDao().count(query, getEntityClass());
        List<T> list = getDao().find(query.with(pageRequest), getEntityClass());
        return PageableExecutionUtils.getPage(list, pageRequest, () -> count);
    }

    /**
     * 查询符合条件的数量
     *
     * @param query
     * @return
     */
    default Long findCountByQuery(Query query) {
        return getDao().count(query, getEntityClass());
    }

    /**
     * 条件查询分页查询
     *
     * @param pageRequest
     * @return
     */
    default Page<T> findPageByQuery(PageRequest pageRequest,Query query) throws ParseException {
        int count = (int) getDao().count(query, getEntityClass());
        List<T> list = getDao().find(query.with(pageRequest), getEntityClass());
        return PageableExecutionUtils.getPage(list, pageRequest, () -> count);
    }

    /**
     * 条件查询全部
     *
     * @param query
     * @return
     */
    default List<T> findByQuery(Query query) {
        return getDao().find(query, getEntityClass());
    }

service抽象:

public abstract class SuperService<T>  implements BaseService<T>{
    @Autowired
    private MongoTemplate mongoTemplate;

    protected Class<T> entityClass = null;

    @Override
    public MongoTemplate getDao() {
        return mongoTemplate;
    }

    @Override
    public Class<T> getEntityClass() {
        if (entityClass == null) {
            this.entityClass = (Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
        }
        return this.entityClass;
    }
}

service层:

@Service
public class UserService extends SuperService<User>{
}

controller层:

@Data
@RestController
public class UserController {
    private final Userservice userservice;

    @PostMapping("/add")
    public void add(@RequestBody User user) {
        userservice.save(user);
    }

    @GetMapping("/del/{id}")
    public void del(@PathVariable String id) {
        userservice.delByQuery(Query.query(Criteria.where("id").is(id)));
    }

    @PostMapping("/update")
    public void update(@RequestBody User user) {
        userservice.update(user);
    }

    @GetMapping("/findById/{id}")
    public User findById(@PathVariable String id) {
        return userservice.findById(id);
    }
    
}

启动类:

@SpringBootApplication
public class MongoDBApplication {

    public static void main(String[] args) {
        SpringApplication.run(MongoDBApplication.class,args);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值