# MongDataBase **Repository Path**: xiyg/mong-data-base ## Basic Information - **Project Name**: MongDataBase - **Description**: MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。他支持的数据结构非常松散,是类似 json 的 bjson 格式,因此可以存储比较复杂的数据类型。MongoDB 最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2023-06-09 - **Last Updated**: 2023-06-09 ## Categories & Tags **Categories**: Uncategorized **Tags**: MongoDB, Nosql ## README # MongDataBase #### 介绍 MongoDB(来自于英文单词“Humongous”,中文含义为“庞大”)是可以应用于各种规模的企业、各个行业以及各类应用程序的开源数据库。基于分布式文件存储的数据库。由C++语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方案。MongoDB 是一个高性能,开源,无模式的文档型数据库,是当前 NoSql 数据库中比较热门的一种。 MongoDB 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。他支持的数据结构非常松散,是类似 json 的 bjson 格式,因此可以存储比较复杂的数据类型。MongoDB 最大的特点是他支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。 传统的关系数据库一般由数据库(database)、表(table)、记录(record)三个层次概念组成,MongoDB 是由数据库(database)、集合(collection)、文档对象(document)三个层次组成。MongoDB 对于关系型数据库里的表,但是集合中没有列、行和关系概念,这体现了模式自由的特点。 MongoDB 中的一条记录就是一个文档,是一个数据结构,由字段和值对组成。MongoDB 文档与 JSON 对象类似。字段的值有可能包括其它文档、数组以及文档数组。MongoDB 支持 OS X、Linux 及 Windows 等操作系统,并提供了 Python,PHP,Ruby,Java及 C++ 语言的驱动程序,社区中也提供了对 Erlang 及 .NET 等平台的驱动程序。 MongoDB 的适合对大量或者无固定格式的数据进行存储,比如:日志、缓存等。对事物支持较弱,不适用复杂的多文档(多表)的级联查询。 #### 软件架构 软件架构说明 #### 安装教程 ##### [安装MongDBserver](https://zhuanlan.zhihu.com/p/560864778) ##### [安装studio3T可视化工具](https://zhuanlan.zhihu.com/p/560864778) #### MongDB非关系型数据库 ##### [MongDB非关系型数据库CURD](https://blog.csdn.net/jerry010101/article/details/89823320) ##### 查: 查询所有文档: ``` db.test.find( {} ); ⇒ SELECT * FROM test; ``` 精确条件匹配: ``` db.test.find( { name: "xiaoming" } ); ⇒ SELECT * FROM test WHERE name = "xiaoming"; ``` IN的用法: ``` db.test.find( { name: { $in: [ "xiaoming", "xiaohong" ] } } ) ;⇒ SELECT * FROM test WHERE name in ("xiaoming", "xiaohong"); ``` AND的用法: ``` db.test.find( { name: "xiaohong", age: { $lt: 15 } } ); ⇒ SELECT * FROM test WHERE name = "A" AND age < 15; ``` #其中age使用了运算符小于的语法, mongo中大于、小于、大于等于、小于等于分别用$gt、$lt、$gte、$lte表示 OR的用法: ``` db.test.find( { $or: [ { name: "xiaoming" }, { age: { $lt: 15 } } ] } ); ⇒ SELECT * FROM test WHERE name = "xiaoming" OR age < 15; ``` AND+OR: ``` db.test.find( { name: "小明", $or: [ { qty: { $lt: 15 } }, { address: /^北京/ } ] } ); ``` #如上MongoDB语句转换为关系型数据库的SQL即为 `SELECT * FROM test WHERE name = "xiaoming" AND ( age < 15 OR address LIKE "北京%");` #其中address处用的了MongoDB中的模糊匹配(即关系型数据库中的`like`),语法相比较如下: ``` #/^北京/ = like '北京%' #/北京/ = like '%北京%' ``` 另外,MongoDB还提供了方法执行读取操作以返回单个文档: `db.collection.findOne() 即 = db.collection.find().limit(1)` ##### 增: 将单个文档插入集合中: ``` db.test.insertOne( { name: "xiaoming", age: 13, address: "北京市西城区" } ) ``` 将多个文档插入到一个集合中: ``` db.test.insertMany([ { name: "xiaoming", age: 13, address: "北京市西城区" }, { name: "xiaohong", age: 14, address: "北京市东城区" }, { name: "xiaogang", age: 15, address: "北京市朝阳区" } ]) ``` 另外,MongoDB提供了insert()方法既可以将单个文档也可以将多个文档插入到集合中,所以insert()是我们实际中更常用的方法: ``` db.test.insert([ { name: "xiaoming", age: 13, address: "北京市西城区" }, { name: "xiaohong", age: 14, address: "北京市东城区" }, { name: "xiaogang", age: 15, address: "北京市朝阳区" } ]) ``` #或 ``` db.test.insert([ { name: "xiaoming", age: 13, address: "北京市西城区" } ]) ``` ##### 改: 仅修改与指定过滤器匹配的单个文档,即使匹配到多个文档: #以下语句将姓名为xiaoming的第一条数据的年龄修改为20 ``` db.test.updateOne( { name: "xiaoming" }, { $set: { "age": 20 } } ) ``` 更新与指定过滤器匹配的所有文档: #以下语句将所有年龄小于25的数据修改为年龄为15 ``` db.test.updateMany( { "age": { $lt: 25 } }, { $set: { age: 15 } } ) ``` 文档替换(最多替换与指定过滤器匹配的单个文档,即使匹配到多个文档): #以下语句将姓名为xiaoming的第一条数据修改为 { name: "xiaoming", sex: "男", phone:"13911111111" } ``` db.test.replaceOne( { name: "xiaoming" }, { name: "xiaoming", sex: "男", phone:"13911111111" } ) ``` 另外,MongoDB提供了update方法,既可以更新或者替换单个文档,也可以更新匹配的所有文档,包含了以上三个方法的所有功能,也是我们实际使用中更常用的方法: 即db.collection.update() , 语法与上述三个方法相同,仅需要将updateOne、updateMany、replaceOne 修改为 update即可,但要注意默认情况下,该方法仅更新单个文档,若要更新多个文档,需要使用multi选项。 #以下语句将所有年龄小于25的数据修改为年龄为15 ``` db.test.update( { "age": { $lt: 25 } }, { $set: { age: 15 } }, {multi:true} ) ``` ##### 删除 仅删除一个与指定过滤器匹配的文档,即使匹配到多个文档也只删除第一条: `db.inventory.deleteOne( { age: 13 } )` 删除与指定过滤器匹配的所有文档: ``` db.inventory.deleteMany({ age : 13 }) ``` 删除集合中的所有文档: ``` db.inventory.deleteMany({}) ``` remove()方法,可以删除与指定过滤器匹配的单个文档或所有文档: remove()删除集合中的所有文档: `db.test.remove({})` remove和deleteOnede、leteMany 都用于删除文档记录。区别是remove返回结果为WriteResult,delete返回bson格式。 #### Springboot使用MongDB数据库 ##### pom 包配置 pom 包里面添加 spring-boot-starter-data-mongodb 包引用 ``` org.springframework.boot spring-boot-starter-data-mongodb ``` ##### 在 application.properties 中添加配置 ``` spring.data.mongodb.uri=mongodb://name:pass@localhost:27017/test 多个 IP 集群可以采用以下配置: spring.data.mongodb.uri=mongodb://user:pwd@ip1:port1,ip2:port2/database ``` ##### 创建数据实体 ``` public class User implements Serializable { private static final long serialVersionUID = -3258839839160856613L; private Long id; private String userName; private String passWord; //getter、setter省略 } ``` ##### 创建实体的增删改查操作 Repository 层实现了 User 对象的增删改查 ``` @Component public class UserRepositoryImpl implements UserRepository { @Autowired private MongoTemplate mongoTemplate; /** * 创建对象 * @param user */ @Override public void saveUser(User user) { mongoTemplate.save(user); } /** * 根据用户名查询对象 * @param userName * @return */ @Override public User findUserByUserName(String userName) { Query query=new Query(Criteria.where("userName").is(userName)); User user = mongoTemplate.findOne(query , User.class); return user; } /** * 更新对象 * @param user */ @Override public long updateUser(User user) { Query query=new Query(Criteria.where("id").is(user.getId())); Update update= new Update().set("userName", user.getUserName()).set("passWord", user.getPassWord()); //更新查询返回结果集的第一条 UpdateResult result =mongoTemplate.updateFirst(query,update,User.class); //更新查询返回结果集的所有 // mongoTemplate.updateMulti(query,update,UserEntity.class); if(result!=null) return result.getMatchedCount(); else return 0; } /** * 删除对象 * @param id */ @Override public void deleteUserById(Long id) { Query query=new Query(Criteria.where("id").is(id)); mongoTemplate.remove(query,User.class); } } ``` ##### 开发对应的测试方法 ``` @RunWith(SpringRunner.class) @SpringBootTest public class UserDaoTest { @Autowired private UserDao userDao; @Test public void testSaveUser() throws Exception { UserEntity user=new UserEntity(); user.setId(2l); user.setUserName("小明"); user.setPassWord("fffooo123"); userDao.saveUser(user); } @Test public void findUserByUserName(){ UserEntity user= userDao.findUserByUserName("小明"); System.out.println("user is "+user); } @Test public void updateUser(){ UserEntity user=new UserEntity(); user.setId(2l); user.setUserName("天空"); user.setPassWord("fffxxxx"); userDao.updateUser(user); } @Test public void deleteUserById(){ userDao.deleteUserById(1l); } } ``` ##### 查看验证结果 ``` 可以使用工具 MongoVUE 工具来连接后直接图形化展示查看,也可以登录服务器用命令来查看 1.登录 mongos bin/mongo -host localhost -port 20000 2、切换到 test 库 use test 3、查询 user 集合数据 db.user.find() 根据3查询的结果来观察测试用例的执行是否正确。 到此 Spring Boot 对应 MongoDB 的增删改查功能已经全部实现。 ``` #### 多数据源 MongoDB 的使用 接下来实现 MongoDB 多数据源的使用 ##### pom 包配置 ``` org.springframework.boot spring-boot-starter-data-mongodb org.springframework.boot spring-boot-starter-test ``` ##### 配置两条数据源,如下: ``` mongodb.primary.uri=mongodb://192.168.0.75:20000 mongodb.primary.database=primary mongodb.secondary.uri=mongodb://192.168.0.75:20000 mongodb.secondary.database=secondary ``` ##### 配置两个库的数据源 封装读取以 Mongodb 开头的两个配置文件 ``` @Data @ConfigurationProperties(prefix = "mongodb") public class MultipleMongoProperties { private MongoProperties primary = new MongoProperties(); private MongoProperties secondary = new MongoProperties(); } ``` 配置不同包路径下使用不同的数据源 第一个库的封装 ``` @Configuration @EnableMongoRepositories(basePackages = "com.neo.model.repository.primary", mongoTemplateRef = PrimaryMongoConfig.MONGO_TEMPLATE) public class PrimaryMongoConfig { protected static final String MONGO_TEMPLATE = "primaryMongoTemplate"; } ``` 第二个库的封装 ``` @Configuration @EnableMongoRepositories(basePackages = "com.neo.model.repository.secondary", mongoTemplateRef = SecondaryMongoConfig.MONGO_TEMPLATE) public class SecondaryMongoConfig { protected static final String MONGO_TEMPLATE = "secondaryMongoTemplate"; } ``` 读取对应的配置信息并且构造对应的 MongoTemplate ``` @Configuration public class MultipleMongoConfig { @Autowired private MultipleMongoProperties mongoProperties; @Primary @Bean(name = PrimaryMongoConfig.MONGO_TEMPLATE) public MongoTemplate primaryMongoTemplate() throws Exception { return new MongoTemplate(primaryFactory(this.mongoProperties.getPrimary())); } @Bean @Qualifier(SecondaryMongoConfig.MONGO_TEMPLATE) public MongoTemplate secondaryMongoTemplate() throws Exception { return new MongoTemplate(secondaryFactory(this.mongoProperties.getSecondary())); } @Bean @Primary public MongoDbFactory primaryFactory(MongoProperties mongo) throws Exception { return new SimpleMongoDbFactory(new MongoClient(mongo.getHost(), mongo.getPort()), mongo.getDatabase()); } @Bean public MongoDbFactory secondaryFactory(MongoProperties mongo) throws Exception { return new SimpleMongoDbFactory(new MongoClient(mongo.getHost(), mongo.getPort()), mongo.getDatabase()); } } ``` 两个库的配置信息已经完成。 ##### 创建两个库分别对应的对象和 Repository 对应可以共用 ``` public class User implements Serializable { private static final long serialVersionUID = -3258839839160856613L; private String id; private String userName; private String passWord; public User(String userName, String passWord) { this.userName = userName; this.passWord = passWord; } } ``` 对应的 Repository ``` public interface PrimaryRepository extends MongoRepository { } ``` 继承了 MongoRepository 会默认实现很多基本的增删改查,省了很多自己写 Repository 层的代码 Secondary 和上面的代码类似就不贴出来了 ##### 最后测试 ``` @RunWith(SpringRunner.class) @SpringBootTest public class MuliDatabaseTest { @Autowired private PrimaryRepository primaryRepository; @Autowired private SecondaryRepository secondaryRepository; @Test public void TestSave() { System.out.println("************************************************************"); System.out.println("测试开始"); System.out.println("************************************************************"); this.primaryRepository .save(new PrimaryMongoObject(null, "第一个库的对象")); this.secondaryRepository .save(new SecondaryMongoObject(null, "第二个库的对象")); List primaries = this.primaryRepository.findAll(); for (PrimaryMongoObject primary : primaries) { System.out.println(primary.toString()); } List secondaries = this.secondaryRepository.findAll(); for (SecondaryMongoObject secondary : secondaries) { System.out.println(secondary.toString()); } System.out.println("************************************************************"); System.out.println("测试完成"); System.out.println("************************************************************"); } } ``` 到此,MongoDB 多数据源的使用已经完成。 参考博文[http://www.ityouknow.com/springboot/2017/05/08/spring-boot-mongodb.html](http://www.ityouknow.com/springboot/2017/05/08/spring-boot-mongodb.html)