Spring Boot MongoDB
1. Linux下启动MongoDB并使用mongosh连接
启动方式有两种:
- systemctl start mongod
- mongod <选项参数>
启动的时候有可能会报类似如下的错误:
ExecStart=/usr/bin/mongod $OPTIONS (code=exited, status=14)
mongod.service: Control process exited, code=exited status=14
当看到这种“code=exited, status=14”的时候,一般是文件或目录权限问题,即执行mongodb启动命令的用户对某些文件或目录没有访问权限,此时应检查一些几个文件或目录:
- /var/run/mongodb/
- /var/log/mongodb/
- /var/lib/mongo/
- /tmp/*.sock
看看这些文件或目录的所有者和所属组是否正确
chown -R mongodb:mongodb /var/lib/mongodb
chown -R mongodb:mongodb /var/log/mongodb/
chown -R mongodb:mongodb /var/run/mongodb/
chown mongodb:mongodb /tmp/mongodb-27017.sock
首先,不启用访问控制,创建一个用户管理员
然后,启用访问控制,用用户管理员认证,再创建其它用户
备忘录
ls -l /var/run/mongodb/
ls -l /var/log/mongodb/
ls -l /var/lib/mongo/
ls -l /tmp/*.sock
id
rm -rf /tmp/mongodb-27017.sock
systemctl start mongod
mongosh
test> use admin
admin> db.createUser(
{
user: "myUserAdmin",
pwd: passwordPrompt(),
roles: [
{ role: "userAdminAnyDatabase", db: "admin" },
{ role: "readWriteAnyDatabase", db: "admin" }
]
}
)
sudo vim /etc/mongod.conf
sudo systemctl restart mongod
mongosh --port 27017 --authenticationDatabase "admin" -u "myUserAdmin" -p
test> use book
switched to db book
book> db.chinese.insertOne({title:"语文"})
test> use admin
switched to db admin
admin> db.auth("myUserAdmin","123456")
{ ok: 1 }
admin> use book
switched to db book
book> db.createUser({user:"zhangsan",pwd:"123456",roles:[{role:"readWrite",db:"book"}]})
{ ok: 1 }
book> db.auth("zhangsan","123456")
{ ok: 1 }
book> show collections
2. Docker 运行 MongoDB
方式一:另启一个容器去连接(PS:相当于远程连接)
docker run -d --network my-network --name my-mongo \
-e MONGO_INITDB_ROOT_USERNAME=mongoroot \
-e MONGO_INITDB_ROOT_PASSWORD=123456 \
-v /data/mongo/db:/data/db \
-p 27017:27017 \
mongo
docker run -it --rm --network my-network mongo \
mongosh --host my-mongo \
-u mongoroot \
-p 123456 \
--authenticationDatabase admin
方式二:从运行MongoDB实例的容器内部进行连接(PS:相当于本地连接)
docker run -d --network my-network --name my-mongo \
-e MONGO_INITDB_ROOT_USERNAME=mongoroot \
-e MONGO_INITDB_ROOT_PASSWORD=123456 \
-v /data/mongo/db:/data/db \
-p 27017:27017 \
mongo
docker exec -it my-mongo mongosh
备忘录
docker run -d --network my-network --name my-mongo \
-e MONGO_INITDB_ROOT_USERNAME=mongoroot \
-e MONGO_INITDB_ROOT_PASSWORD=123456 \
-v /data/mongo/db:/data/db \
-p 27017:27017 \
mongo
docker run -it --rm --network my-network mongo \
mongosh --host my-mongo \
-u mongoroot \
-p 123456 \
--authenticationDatabase admin
docker exec -it my-mongo mongosh
docker run -it --rm mongo mongosh --help
docker exec -it some-mongo bash
docker logs -f some-mongo
docker exec -it my-mongo mongosh
use admin
db.auth("myUserAdmin","123456")
db.createUser({user:"hello",pwd:"world",roles:[{role:"readWrite",db:"movie"}]})
补充
不建议用root用户来运行MongoDB
https://docs.mongodb.com/manual/tutorial/install-mongodb-on-red-hat/
3. Spring Boot 集成 MongoDB
maven依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
完整的pom.xml如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.2</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.cjs.example</groupId>
<artifactId>demo-mongodb</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo-mongodb</name>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
application.yml
spring:
data:
mongodb:
host: 192.168.28.32
port: 27017
database: movie
username: hello
password: world
# uri: mongodb://192.168.28.32:27017
连接字符串格式,参见 https://docs.mongodb.com/manual/reference/connection-string/
方式一:MongoTemplate
首先,定义一个实体类
package com.cjs.example.domain;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.index.Indexed;
import org.springframework.data.mongodb.core.mapping.Document;
import java.io.Serializable;
import java.util.List;
/**
* @Author ChengJianSheng
* @Date 2022/1/12
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@Document(collection = "film")
public class Film implements Serializable {
@Id
private String id;
private String name;
private List<String> category;
}
然后,利用MongoTemplate进行操作
package com.cjs.example;
import com.cjs.example.domain.Film;
import com.cjs.example.repository.FilmRepository;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
@SpringBootTest
class DemoMongodbApplicationTests {
@Resource
private MongoTemplate mongoTemplate;
/**
* movie> db.createUser({user:"hello",pwd:"world",roles:["readWrite"]})
*/
@Test
void contextLoads() {
Film film = new Film();
film.setName("我和我的父辈");
film.setCategory(Arrays.asList("剧情"));
mongoTemplate.insert(film);
}
@Test
void testQuery() {
List<Film> filmList = mongoTemplate.findAll(Film.class);
System.out.println(filmList);
Query query = new Query();
query.addCriteria(Criteria.where("name").is("我和我的父辈").and("category").in("爱情","战争","剧情"));
Film film = mongoTemplate.findOne(query, Film.class);
System.out.println(film);
}
@Test
void testSave() {
Film film = new Film();
film.setId("asdfgh");
film.setName("长津湖");
film.setCategory(Arrays.asList("战争","历史"));
mongoTemplate.save(film);
}
}
方式二:Spring Data MongoDB Repositories
定义一个Repository
package com.cjs.example.repository;
import com.cjs.example.domain.Film;
import org.springframework.data.repository.CrudRepository;
import java.util.List;
/**
* @Author ChengJianSheng
* @Date 2022/1/12
*/
public interface FilmRepository extends CrudRepository<Film, String> {
List<Film> findByName(String name);
}
完整测试代码如下:
package com.cjs.example;
import com.cjs.example.domain.Film;
import com.cjs.example.repository.FilmRepository;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
@SpringBootTest
class DemoMongodbApplicationTests {
@Resource
private MongoTemplate mongoTemplate;
@Resource
private FilmRepository filmRepository;
/**
* movie> db.createUser({user:"hello",pwd:"world",roles:["readWrite"]})
*/
@Test
void contextLoads() {
Film film = new Film();
film.setName("我和我的父辈");
film.setCategory(Arrays.asList("剧情"));
mongoTemplate.insert(film);
}
@Test
void testQuery() {
List<Film> filmList = mongoTemplate.findAll(Film.class);
System.out.println(filmList);
Query query = new Query();
query.addCriteria(Criteria.where("name").is("我和我的父辈").and("category").in("爱情","战争","剧情"));
Film film = mongoTemplate.findOne(query, Film.class);
System.out.println(film);
}
@Test
void testSave() {
Film film = new Film();
film.setId("asdfgh");
film.setName("长津湖");
film.setCategory(Arrays.asList("战争","历史"));
mongoTemplate.save(film);
}
@Test
void testSaveByRepository() {
filmRepository.save(new Film("1234", "火影忍者", Arrays.asList("动画","喜剧","动作","冒险")));
}
@Test
void testQueryByRepository() {
Film film = filmRepository.findById("1234").orElse(null);
System.out.println(film);
film = filmRepository.findByName("火影忍者").get(0);
System.out.println(film);
filmRepository.findAll().forEach(System.out::println);
}
}
工程结构如下: