SpringBoot简单使用MongoDB
一、配置步骤
1、application.yml
2、pom
3、entity
4、mapper
二、案例代码使用
1、库
前期准备上一篇安装MongoDB地址http://t.csdn.cn/G4oYJ
数据格式
MongoDB 将一条数据存储为一个文档(BSON格式, 由key 和 value组成(类似于Json))。
{
"_id" : ObjectId("61d6927658c3b5acf4723616"),
"name" : "希望小学",
"studentNum" : 10000.0
}
大数据量存储场景
MongoDB自带副本集和分片,天生就适用于大数量场景,无需开发人员通过中间件去分库分表,非常方便。
操作日志存储
很多时候,我们需要存储一些操作日志,可能只需要存储比如最近一个月的,一般的做法是定期去清理,在MongoDB中有固定集合的概念,我们在创建集合的时候可以指定大小,当数据量超过大小的时候会自动移除掉老数据。
爬虫数据存储
爬下来的数据有网页,也有Json格式的数据,一般都会按照表的格式去存储,如果我们用了MongoDB就可以将抓下来的Json数据直接存入集合中,无格式限制。
社交数据存储
在社交场景中使用 MongoDB 存储存储用户地址位置信息,通过地理位置索引实现附近的人,附近的地点等。
电商商品存储
不同的商品有不同的属性,常见的做法是抽出公共的属性表,然后和SPU进行关联,如果用MongoDB的话那么SPU中直接就可以内嵌属性。
单个文档插入到集合中
db.collection.insertOne()
多个文档插入到集合中
db.collection.insertMany()
单个或者多个文件插入到集合中
db.collection.insert()
查询数据
db.collection.find( )
更新单条
db.inventory.updateOne()
更新多条
db.inventory.updateMany()
删除单条文档
db.inventory.deleteOne( )
删除多条文档
db.inventory.deleteMany()
我们总是在对比中看到自己的优点和缺点,对于mongodb来说也是一样,对比学习让我们尽快的掌握关于mongodb的基础知识。
关系型数据库Mysql,Oracle一般是由数据库(database)、表(table)、记录(record)三个层次概念组成。
而非关系型数据库mongodb是由数据库(database)、集合(collection)、文档对象(document)三个层次组成。
mongodb对于关系型数据库里的表,没有行和列的关系概念,这体现了模式的自由特点。
Mysql表结构固定,而Mongo的表结构是可变的。
Mysql数据量大时,查询速度慢;除非分库分表 或者使用索引(?)。
Mongo数据量大时,查询速度快,逻辑(?)
(结构固定的数据对象使用Mysql,结构不固定的使用Mongo)
Eg: 使用Mongo用户信息表,(包含一些用户可随意增加的字段)
Mysql | MongoDB |
Database(数据库) | Database(数据库) |
Table(表) | Collection(集合) |
Row(行) | Document(文档) |
Column(列) | Field(字段) |
MySQL |
MongoDB |
说明 |
mysqld |
mongod |
服务器守护进程 |
mysql |
mongo |
客户端工具 |
mysqldump |
mongodump |
逻辑备份工具 |
mysql |
mongorestore |
逻辑恢复工具 |
db.repairDatabase() |
修复数据库 |
|
mysqldump |
mongoexport |
数据导出工具 |
source |
mongoimport |
数据导入工具 |
grant * privileges on *.* to … |
Db.addUser() Db.auth() |
新建用户并权限 |
show databases |
show dbs |
显示库列表 |
Show tables |
Show collections |
显示表列表 |
Show slave status |
Rs.status |
查询主从状态 |
Create table users(a int, b int) |
db.createCollection("mycoll", {capped:true, size:100000}) 另:可隐式创建表。 |
创建表 |
Create INDEX idxname ON users(name) |
db.users.ensureIndex({name:1}) |
创建索引 |
Create INDEX idxname ON users(name,ts DESC) |
db.users.ensureIndex({name:1,ts:-1}) |
创建索引 |
Insert into users values(1, 1) |
db.users.insert({a:1, b:1}) |
插入记录 |
Select a, b from users |
db.users.find({},{a:1, b:1}) |
查询表 |
Select * from users |
db.users.find() |
查询表 |
Select * from users where age=33 |
db.users.find({age:33}) |
条件查询 |
Select a, b from users where age=33 |
db.users.find({age:33},{a:1, b:1}) |
条件查询 |
select * from users where age<33 |
db.users.find({'age':{$lt:33}}) |
条件查询 |
select * from users where age>33 and age<=40 |
db.users.find({'age':{$gt:33,$lte:40}}) |
条件查询 |
select * from users where a=1 and b='q' |
db.users.find({a:1,b:'q'}) |
条件查询 |
select * from users where a=1 or b=2 |
db.users.find( { $or : [ { a : 1 } , { b : 2 } ] } ) |
条件查询 |
select * from users limit 1 |
db.users.findOne() |
条件查询 |
select * from users where name like "%Joe%" |
db.users.find({name:/Joe/}) |
模糊查询 |
select * from users where name like "Joe%" |
db.users.find({name:/^Joe/}) |
模糊查询 |
select count(1) from users |
Db.users.count() |
获取表记录数 |
select count(1) from users where age>30 |
db.users.find({age: {'$gt': 30}}).count() |
获取表记录数 |
select DISTINCT last_name from users |
db.users.distinct('last_name') |
去掉重复值 |
select * from users ORDER BY name |
db.users.find().sort({name:-1}) |
排序 |
select * from users ORDER BY name DESC |
db.users.find().sort({name:-1}) |
排序 |
EXPLAIN select * from users where z=3 |
db.users.find({z:3}).explain() |
获取存储路径 |
update users set a=1 where b='q' |
db.users.update({b:'q'}, {$set:{a:1}}, false, true) |
更新记录 |
update users set a=a+2 where b='q' |
db.users.update({b:'q'}, {$inc:{a:2}}, false, true) |
更新记录 |
delete from users where z="abc" |
db.users.remove({z:'abc'}) |
删除记录 |
db. users.remove() |
删除所有的记录 |
|
drop database IF EXISTS test; |
use test db.dropDatabase() |
删除数据库 |
drop table IF EXISTS test; |
db.mytable.drop() |
删除表/collection |
db.addUser(‘test', 'test') |
添加用户 readOnly-->false |
|
db.addUser(‘test', 'test', true) |
添加用户 readOnly-->true |
|
db.addUser("test","test222") |
更改密码 |
|
db.system.users.remove({user:"test"}) 或者db.removeUser('test') |
删除用户 |
|
use admin |
超级用户 |
|
db.auth(‘test', ‘test') |
用户授权 |
|
db.system.users.find() |
查看用户列表 |
|
show users |
查看所有用户 |
|
db.printCollectionStats() |
查看各collection的状态 |
|
db.printReplicationInfo() |
查看主从复制状态 |
|
show profile |
查看profiling |
|
db.copyDatabase('mail_addr','mail_addr_tmp') |
拷贝数据库 |
|
db.users.dataSize() |
查看collection数据的大小 |
|
db. users.totalIndexSize() |
查询索引的大小 |
mongodb语法很多,比如多列索引,查询时可以统计函数,支持多条件查询,
但是目前对多表的查询是不支持的,可以想办法通过数据冗余来解决多表查询的问题。举例如下所示。
查询colls所有数据
db.colls.find() //select * from colls
通过指定条件查询
db.colls.find({‘last_name': ‘Smith'});//select * from colls where last_name='Smith'
指定多条件查询
db.colls.find( { x : 3, y : “foo” } );//select * from colls where x=3 and y='foo'
指定条件范围查询
db.colls.find({j: {$ne: 3}, k: {$gt: 10} });//select * from colls where j!=3 and k>10
查询不包括某内容
db.colls.find({}, {a:0});//查询除a为0外的所有数据
支持<, <=, >, >=查询,需用符号替代分别为$lt,$lte,$gt,$gte
db.colls.find({ “field” : { $gt: value } } );
db.colls.find({ “field” : { $lt: value } } );
db.colls.find({ “field” : { $gte: value } } );
db.colls.find({ “field” : { $lte: value } } );
也可对某一字段做范围查询
db.colls.find({ “field” : { $gt: value1, $lt: value2 } } );
不等于查询用字符$ne
db.colls.find( { x : { $ne : 3 } } );
in查询用字符$in
db.colls.find( { “field” : { $in : array } } );
db.colls.find({j:{$in: [2,4,6]}});
not in查询用字符$nin
db.colls.find({j:{$nin: [2,4,6]}});
取模查询用字符$mod
db.colls.find( { a : { $mod : [ 10 , 1 ] } } )// where a % 10 == 1
$all查询
db.colls.find( { a: { $all: [ 2, 3 ] } } );//指定a满足数组中任意值时
$size查询
db.colls.find( { a : { $size: 1 } } );//对对象的数量查询,此查询查询a的子对象数目为1的记录
$exists查询
db.colls.find( { a : { $exists : true } } ); // 存在a对象的数据
db.colls.find( { a : { $exists : false } } ); // 不存在a对象的数据
$type查询
$type值为bson
http://bsonspec.org/数 据的类型值
db.colls.find( { a : { $type : 2 } } ); // 匹配a为string类型数据
db.colls.find( { a : { $type : 16 } } ); // 匹配a为int类型数据
使用正则表达式匹配
db.colls.find( { name : /acme.*corp/i } );//类似于SQL中like
内嵌对象查询
db.colls.find( { “author.name” : “joe” } );
1.3.3版本及更高版本包含$not查询
db.colls.find( { name : { $not : /acme.*corp/i } } );
db.colls.find( { a : { $not : { $mod : [ 10 , 1 ] } } } );
sort()排序
db.colls.find().sort( { ts : -1 } );//1为升序2为降序
limit()对限制查询数据返回个数
db.colls.find().limit(10)
skip()跳过某些数据
db.colls.find().skip(10)
snapshot()快照保证没有重复数据返回或对象丢失
count()统计查询对象个数
db.students.find({‘address.state' : ‘CA'}).count();//效率较高
db.students.find({‘address.state' : ‘CA'}).toArray().length;//效率很低
group() 分组,对查询结果分组和SQL中group by函数类似
distinct() 去重,返回不重复值
db.集合名称.insert/save/insertOne(文档) //添加
db.集合名称.update({条件},{操作种类:{文档}})
db.集合名称.remove(条件)
一、配置步骤
进入mongodb中创建数据库和用户
# (1)授权
# 我的管理员是root,密码是123456
db.auth("root", "123456")
# (2)创建应用数据库和用户
# 连接库直接使用相应库中的用户名称即可,如果仅仅使用appdb库,直接使用user=appdb,pwd=123456连接即可
use appdb
db.createUser({user:'appdbuser', pwd:'123456', roles:[ {role:'dbOwner', db:'appdb'} ]})
db.book.save({'name':'spring boot',type:'spring boot'}) //添加
db.book.remove({type:'spring boot'}) //删除
//修改第一条
db.book.update({name:'spring boot'}, {$set:{name:'Spring Boot'}})
//修改所有
db.book.updateMany({name:'spring boot'}, {$set:{type:'spring'}})
db.getCollection('book').find({}) //查询
db.book.find({type:'spring boot'}) //查询
# 登录用户所在的数据库
spring.data.mongodb.authentication-database=admin
# 数据库的ip地址
spring.data.mongodb.host=192.168.133.142
# MongoDB端口号
spring.data.mongodb.port=27017
# 用户账号
spring.data.mongodb.username=zlfeng
# 用户密码
spring.data.mongodb.password=123456
# 指定使用的数据库
# 不必预先创建,不存在该数据库会自动创建
spring.data.mongodb.database=db_student
spring:
data:
mongodb:
#192.168.217.128根据自己的ip进行修改
#test是MongoDB的集合名称 也就是表名
@Data
@AllArgsConstructor
@Document("User") //指定了这个模型类型所对应的集合名称即collection 表名
public class User {
@Id //自动生成的主键ID 主键 不可重复 自带索引
private String id;
private String name;
private Integer age;
}
@SpringBootTest
public class MongoTemplateTest {
@Autowired
private MongoTemplate mongoTemplate;
@Test
public void testMongoDB(){
//向表中插入数据
User user = new User(null,"张三",20);
User user1 = new User(null,"李四",16);
mongoTemplate.insert(user);
mongoTemplate.insert(user1);
//查询表中所有记录
List userList = mongoTemplate.findAll(User.class);
System.out.println(userList);
//[User(id=63acf541e6af652ac74fd008, name=张三, age=20),
// User(id=63acf541e6af652ac74fd009, name=李四, age=16)]
//根据表中id查询记录
User user2 = mongoTemplate.findById("63acf541e6af652ac74fd008", User.class);
System.out.println(user2);//User(id=63acf541e6af652ac74fd008, name=张三, age=20)
//条件查询
Query query = new Query(Criteria.where("name").is("李四").and("age").is(16));
List users = mongoTemplate.find(query, User.class);
System.out.println(users);//[User(id=63acf541e6af652ac74fd009, name=李四, age=16)]
//根据_id删除表中记录
Query query2 = new Query(Criteria.where("_id").is("63acf541e6af652ac74fd008"));
DeleteResult remove = mongoTemplate.remove(query2, User.class);
//获取删除记录的个数
long count = remove.getDeletedCount();
System.out.println(count);//1
//删除表中所有数据
Query query3 = new Query();
mongoTemplate.remove(query3,User.class);
}
}
Spring Data提供了对MongoDB数据访问的支持,我们只需要继承MongoRepository类,按照Spring Data规范就可以了。
构建仓库
public interface UserRepository extends MongoRepository {
}
方法测试
@SpringBootTest
public class MongoRepositoryTest {
@Autowired
private UserRepository userRepository;
@Test
public void test(){
//向数据库表中插入数据
User user = new User(null,"张三三",18);
User user1 = new User(null,"李四",16);
userRepository.save(user);
userRepository.save(user1);
//查询数据库表中所有记录
List all = userRepository.findAll();
System.out.println(all);
//[User(id=63acf24938e0d1033d50dc20, name=张三三, age=18),
// User(id=63acf24938e0d1033d50dc21, name=李四, age=16)]
//按照id查询表中数据
User user2 = userRepository.findById("63acf24938e0d1033d50dc20").get();
System.out.println(user2);//User(id=63acf24938e0d1033d50dc20, name=张三三, age=18)
//按条件(姓名与年龄)查询
Example example = Example.of(new User(null,"李四",16));
List list = userRepository.findAll(example);
System.out.println(list);//User(id=63acf24938e0d1033d50dc21, name=李四, age=16)
//模糊查询
User user3 = new User(null,"三",18);
//模糊查询匹配规则
ExampleMatcher matcher = ExampleMatcher.matching()
.withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING)
.withIgnoreCase(true);//忽略大小写
Example example1 = Example.of(user3,matcher);
List list1 = userRepository.findAll(example1);
System.out.println(list1);//User(id=63acf24938e0d1033d50dc20, name=张三三, age=18)
//分页查询
Pageable pageable = PageRequest.of(0, 2);//设置分页参数:第1页 每页2条数据
Page page = userRepository.findAll(pageable);
System.out.println("Page的总页数是:" + page.getTotalPages() + ",Page的总记录条数是:" + page.getTotalElements());
//Page的总页数是:1 + ,Page的总记录条数是:2
//根据_id修改信息
User user4 = userRepository.findById("63acf24938e0d1033d50dc20").get();
user4.setName("王五");//将取出的信息修改其name
userRepository.save(user4);
//根据id删除
userRepository.deleteById("63acf24938e0d1033d50dc20");
//删除全部
userRepository.deleteAll();
}
```
一、配置步骤
进入mongodb中创建数据库和用户
```bash
# (1)授权
# 我的管理员是root,密码是123456
db.auth("root", "123456")
# (2)创建应用数据库和用户
# 连接库直接使用相应库中的用户名称即可,如果仅仅使用appdb库,直接使用user=appdb,pwd=123456连接即可
use appdb
db.createUser({user:'appdbuser', pwd:'123456', roles:[ {role:'dbOwner', db:'appdb'} ]})
```
1、application.yml
```bash
#数据库配置
spring:
data:
mongodb:
# mongodb://用户名:密码@IP地址:27017/数据库
uri: mongodb://appdbuser:[email protected]:27017/appdb
# 可以不用设置数据库
# database: appdb
```
2、pom
3、entity
```bash
@Document("book")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Book {
@Id
private Long id;
private String title;
private Integer page;
}
```
4、mapper
```bash
@Repository
public interface BookDao extends MongoRepository
}
```
## 二、案例代码使用
```bash
@SpringBootTest
@Slf4j
class MymongoApplicationTests {
@Autowired
private BookDao bookDao;
@Test
void contextLoads() {
// 插入多条数据
Book book1 = new Book(2L, "China", 8);
Book book2 = new Book(3L, "American", 8);
ArrayList
bookArrayList.add(book1);
bookArrayList.add(book2);
bookDao.saveAll(bookArrayList);
// 查询一条数据
Book book3 = new Book();
book3.setTitle("American");
Example
Optional
log.info(one.get().toString());//Book(id=3, title=American, page=8)
}
}
```
## 操作集合下的文档
3) 切换至集合
连接至具体数据库以后,使用以下代码切换到集合,如果集合不存在,则使用如下代码新建集合:
```bash
MongoCollection collection = database.getCollection("myTestCollection");
```
4) 插入文档
切换至集合后,就可以进行文档的增、删、改、查操作。首先定义文档,并使用 append。方法追加内容,代码如下:
```bash
Document document = new Document("_id", 1999)
.append("title", "MongoDB Insert Demo")
.append("description","database")
.append("likes", 30)
.append("by", "demo point")
.append("url", "http://c.biancheng.net/mongodb/");
```
document 为 BSON 类型的文档,实际上为一个列表,每项有两个元素,即字段名和值。
文档定义完成后,再使用 insertOne 方法将此文档插入集合:
```bash
collection.insertOne(document);
```
如果插入多条数据,需要先定义一个 Document 列表,然后用 add() 方法添加多个 Document 元素,最后用 insertMany() 方法插入,代码如下:
```bash
List
documents.add(document1);
collection.insertMany(documents);
```
5) 删除文档
使用 delete() 方法删除一个或多个文档,代码如下:
```bash
collection.deleteOne(document);
collection.deleteMany(new Document ("likes", 30));
```
6) 更新数据
使用 updataOne() 方法更新一条数据或多个数据,代码如下:
```bash
collection.updataOne (eq ("likes", 30), new Document ("$set", new Document ("likes", 50)));
```
updateOne() 方法中有两个参数,第一个参数表示更新的内容等于 ("likes",30) 的文档,第二个参数为要修改的内容,使用 $set 参数修改当前值,修改的内容为 ("likes", 50)。
7) 查询数据
利用游标类型实现数据的查询和遍历显示,使用游标前需要 import MongoCursor 类库。
```bash
import com.mongodb.client.MongoCursor;
document Doc = (Document)collection.find(eq("likes", 30)).iterator();
MongoCursor
try{
while (cursor.hasNext()){
System.out.printin(cursor.next().toJson());
}
} finally{
Cursor.close();
```
}
设置 find() 方法的参数为查询条件,参数为比较的 Document 元素。
8) 其他方法
删除数据库或集合,代码如下:
```bash
mDatabase.drop();
collection.drop();
```
关闭客户端连接,代码如下:
```bash
mongoClient.close();
```