简介
本文介绍一下非关系型数据库的特点,及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);
}
}