目录
1.MongoDB概念
MongoDB是一种NoSQL数据库。
1.1 MongoDB和SQL术语概念区分
SQL术语概念 | 说明 | MongoDB术语概念 | 说明 |
database | 数据库 | database | 数据库 |
table | 数据库表 | collection | 集合 |
row | 数据记录行 | document | 文档 |
column | 数据字段 | field | 域 |
index | 索引 | index | 索引 |
table joins | 表连接 | MongoDB不支持 | |
primary key | 主键 | primary key | MongoDB自动将_id字段设置为主键 |
1.2 MongoDB的_id
其形式为:
_id: ObjectId('62f9f33f39f9507afcf5329d
ObjectId是_id的默认类型,使用12字节的存储空间,每个字节是二位十六进制数字,是一个24位的字符串
生成规则为:时间戳+机器+PID+计数器
2.MongoDB用户权限
2.1 角色
MongoDB内置了7个角色,如下所示:
数据库用户角色 | read、readWrite |
数据库管理角色 | dbAdmin、dbOwner、useAdmin |
集群管理角色 | clusterAdmin、clusterManager、clusterMonitor、hostManager |
备份恢复角色 | backup、restore |
所有数据库角色 | readAnyDatabase、readWriteAnyDatabase、userAdminAnyData、dbAdminAnyDatabase |
超级用户角色 | root |
系统超级用户的访问 | dbOwner、userAdmin、userAdminAnyDatabase |
2.2 角色权限
角色权限如下所示:
read | 允许用户读取指定数据库 |
readWrite | 允许用户读写指定数据库 |
dbAdmin | 允许用户在指定数据库中执行管理函数,如索引创建、删除、查看统计或访问system.profile |
userAdmin | 允许用户向system.users集合写入,可以在指定数据库里创建、删除和管理用户 |
clusterAdmin | 只在admin数据库中可用,赋予用户所有分片和复制集相关函数的管理权限。 |
readAnyDatabase | 只在admin数据库中可用,赋予用户所有数据库的读权限 |
readWriteAnyDatabase | 只在admin数据库中可用,赋予用户所有数据库的读写权限 |
userAdminAnyDatabase | 只在admin数据库中可用,赋予用户所有数据库的userAdmin权限 |
dbAdminAnyDatabase | 只在admin数据库中可用,赋予用户所有数据库的dbAdmin权限。 |
root | 只在admin数据库中可用。超级账号,超级权限 |
2.3 设置用户
这里以在Ubuntu的Docker设置MongoDB用户为例:
# Docker里面的MongoDB容器已运行,且名称为mongodb
$ docker exec -it mongodb bash # 使用mongo命令,进入MongoDB数据库
> mongo
# 切换到MongoDB自带的数据库admin,用于创建管理员账户
> use admin
# 创建管理员账户,授予root权限
db.createUser({user:'admin',pwd:'123456',roles:[{role:'root',db:'admin'}]});# 切换到数据库sms-send(如果没有该数据库,则会创建该数据库),用于创建普通用户。 > use sms-send
# 创建一个名为 lqs,密码为 123456 的普通用户,授予读写权限。
> db.createUser({ user:'lqs',pwd:'123456',roles:[ { role:'readWrite', db: 'admin'}]});
# 验证:尝试使用上面创建的用户信息进行连接,返回1就表示认证成功。
> db.auth('lqs', '123456')
# 修改密码
db.changeUserPassword('lqs','123');
# 查看当前数据库里面的所有用户
> show users
# 查看所有用户(pretty()格式化显示,只能在admin数据库下执行)
> db.system.users.find().pretty()
# 删除用户
> db.dropUser("lqs")
# 退出
> exit
注意:用户只能在创建该用户时所在的数据库进行认证。认证成功后,就可以对该数据库执行权限范围内的操作。
3.操作数据库
3.1 数据库
- 创建/切换数据库
//如果数据库不存在,则创建数据库;否则切换到此数据库
use 数据库名称
- 查询所有数据库
show dbs;
- 删除当前使用的数据库
db.dropDatabase();
- 查看当前使用的数据库
db.getName();
- 显示当前db状态
db.stats();
- 当前db版本
db.version();
- 查看当前sb的链接机器地址
db.getMongo();
3.2 查询
- 查询所有数据库
show dbs
- 查询所有
sql | select * from user |
mongodb | db.user.find() |
- 带where条件查询
sql | select * from user where age = 21 |
mongodb | db.user.find({age:21}) |
- 查询指定字段
sql | select nage, age from user where age = 21 |
mongodb | db.user.find({age:21},{'nage':1,'age':1) |
- 排序
MongoDB中使用sort()方法对数据进行排序。sort()方法可以通过参数指定排序的字段,并使用1和-1来指定排序的方式:其中1为升序,-1为降序。
sql | select * from user order by age |
mongodb | db.user.find().sort({age:1}) |
- limit和skip
MongoDB中使用limit()方法来读取指定数量的数据;skip()方法拉力跳过指定数量的数据
sql | select * from user skip 2 limit 3 |
mongodb | db.user.find().skip(2).limit(3) |
- in
sql | select * from user where age in (10,12,16) |
mongodb | db.user.find({age:{$in:[10,12,16]}}) |
- count
sql | select count(*) from user where age > 10 |
mongodb | db.user.find({age:{$gt:20}}).count() |
- or
sql | select * from user where age = 12 or age = 18 |
mongodb | db.user.find({$or:[{age:12}, {age:18}]}) |
3.3 插入
db.User.save({name:'luck',age:21});
3.4 更新
sql | update user set age = 19, sex = 1 where name = "luck" |
mongodb | db.user.update({name:"luck"}, {$set:{age:19, sex:1}}) |
3.5 删除
remove用于删除单个或全部文档,删除后的文档无法恢复。
- 删除对应id的行
db.user.remove(id)
- 删除所有
db.user.remove({})
4.索引
创建索引:
db.user.createIndex({"name":1})
5.SpringBoot集成MongoDB
spring-data-mongodb提供了两种方式访问MongoDB:MongoTemplate和MongoRepository
5.1 引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
5.2 yml配置MongoDB
spring:
data:
mongodb:
uri: mongodb://localhost:27017/sms-send
#禁止自动创建索引
auto-index-creation: false
5.3 创建对应实体类
@Document("User")
@Data
public class User {
@Id
private String id;
private String name;
private Integer age;
}
5.4 增删改查
下面分别以MongoTemplate和MongoRepository分别实现CRUD
5.4.1 基于MongoTemplate的CRUD
-
增加
User obj = mongoTemplate.insert(user);
- 查询所有
List<User> list = mongoTemplate.findAll(User.class);
- 根据ID查询
User user = mongoTemplate.findById("31hg123g123u1sdgsb2", User.class);
- 条件查询
Query query = new Query();
query.addCriteria(Criteria.where("name").is("luck").and("age").is(19));
List<User> list = mongoTemplate.find(query, User.class);
- 模糊查询
// 根据名称模糊查询
Pattern pattern = Pattern.compile("^[\\s\\S]*" + name + "[\\s\\S]*$", Pattern.CASE_INSENSITIVE);
Query query = new Query(Criteria.where("name").regex(pattern ));
List<User> list = mongoTemplate.find(query, User.class);
- 分页查询
Query query = new Query();
//统计总记录数
long count = mongoTemplate.count(query, User.class);
//分页:page当前页,size每页记录数
//跳过多少条数据
query.skip((page-1) * size);
//每页多少条数据
query.limit(size);
//查询数据
List<User> list = mongoTemplate.find(query, User.class);
-
修改
User user = mongoTemplate.findById("31hg123g123u1sdgsb2", User.class);
//设置新值
user.setName("naco");
Query query = new Query(Criteria.where("_id").is(user.getId());
Update update = new Update();
update.set("name", user.getName());
UpdateResult upResult = mongoTemplate.upsert(query, update, User.class);
long modifiedCount = upResult.getModifiedCount();
-
删除
Query query = new Query(Criteria.where("_id").is("77dsgusd98s8c7s6d8f7");
DeleteResult deleteResult = mongoTemplate.upsert(query, update, User.class);
long deletedCount = deleteResult.getDeletedCount();
5.4.2 基于MongoRepository的CRUD
第一步,创建实体类的interface,继承MongoRepository
@Repository
public interface UserRepository extends MongoRepository<User, String> {
// todo
}
-
增加
User obj = userRepository.save(user)
- 查询所有
List<User> list = userRepository.findAll();
- 根据ID查询
User user = userRepository.findById("31hg123g123u1sdgsb2").get();
- 条件查询
User user = new User();
user.setName("luck");
Example<User> example = Example.of(user);
List<User> list = userRepository.findAll(example);
- 模糊查询
User user = new User();
user.setName("luck");
// 设置模糊查询匹配规则
ExampleMatcher matcher = ExampleMatcher.matching()
.withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING)
.withIgnoreCase(true);
Example<User> example = Example.of(user, matcher);
List<User> list = userRepository.findAll(example);
- 分页查询
// page传0时,代表第一页
Pageable pageable = PageRequest.of(page-1, size);
User user = new User();
user.setName("luck");
Example<User> example = Example.of(user);
// page里面包含了分页相关的数据
Page<User> page = userRepository.findAll(example, pageable);
-
修改
User user = userRepository.findById("31hg123g123u1sdgsb2").get();
//设置新值
user.setName("naco");
User u = userRepository.save(user);
-
删除
// 无返回
userRepository.deleteById("31hg123g123u1sdgsb2");
6.Spring Data方法规范
Spring Data提供了对MongoDB数据访问的支持,只需要继承MongoRepository类,然后按照Spring Data规范编写方法即可。
关键字 | 方法命名 | JPQL snippet |
and | findByNameAndAge | ...where x.name = ?1 and age = ?2 |
or | findByLastnameOrFirstname | ...where x.lastname = ?1 and lastname = ?2 |
between | findByStartDateBetween | ...where x.startDate between ?1 and ?2 |
LessThan | findByAgeLessThan | ...where x.age < ?1 |
GreaterThan | findByAgeGreaterThan | ...where x.age > ?1 |
after | findByStartDateAfter | ...where x.startDate > ?1 |
before | findByStartDateBefore | ...where x.startDate < ?1 |
IsNull | findByAgeIsNull | ...where x.age is null |
isNotNull, NotNull | findByAge(is)NotNull | ...where x.age not null |
like | findByNameLike | ...where x.name like ?1 |
NotLike | findByNameNotLike | ...where x.name not like ?1 |
StartingWith | findByNameStartingWith | ...where x.name like ?1(parameter bound with appended %) |
EndingWith | findByNameEndingWith | ...where x.name like ?1(parameter bound with prepended %) |
Containing | findByNameContaining | ...where x.name like ?1(parameter bound with wrapped in %) |
OrderBy | findByAgeOrderByNameDesc | ...where x.age = ?1 order by x.name desc |
Not | findByNameNot | ...where x.name <> ?1 |
in | findByAgeIn(Collection<Age> ages) | ...where x.age in ?1 |
NotIn | findByAgeNotIn(Collection<Age> ages) | ...where x.age not in ?1 |
True | findByActiveTrue() | ...where x.active = true |
False | findByActiveFalse() | ...where x.active = false |