Spring集成MongoDB实战

Spring集成MongoDB

简介

MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。

MongoDB是一个介于关系数据库和非关系数据库(nosql)之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。

与RDBMS区别

SQL属于/概念 MongoDB术语/概念 解释/说明
database database 数据库
table collection 数据库表/集合
row document 数据记录行/文档
column field 数据字段/域
index index 索引
table joins 表连接,MongoDB不支持
primary key primary key 主键,MongoDB自动将_id字段设置为主键

docker部署mongodb

# 暂时没有加数据卷映射,只是demo测试
docker run -d -p 27017:27017 -e MONGO_INITDB_ROOT_USERNAME=root -e MONGO_INITDB_ROOT_PASSWORD=123456 --restart=always --name=mongodb mongo

mongodb命令行

以docker容器内为例:

  1. mongodb命令行
#1. 进入容器并进入mongodb命令行
docker exec -it d2a mongo admin
#2. 先进入容器 再进入命令行
docker exec -it d2a bash
mongo admin
  1. 认证
## 如果是直接进入命令行
db.auth("username","password")

#或者
mongo -uroot -p --authenticationDatabase admin
#然后输入密码
  1. 常用数据属性状态命令
#查看所有数据库
show dbs

#查询数据库连接数
show collecitions

#获取数据库名称
db.getName()

#获取数据库状态
db.stats()

#获取数据库版本
db.version()

#查看当前db的链接机器地址
db.getMongo()
  1. 数据库相关
# 进入数据库 如果没有则创建
use mongo_demo

# 删除数据库
db.dropDatabase()
  1. 集合相关
#查看集合
show collections

#删除集合
db.collection.drop()

#创建结合 
#options具体查阅文档 可以默认
db.createCollection(name, options)
  1. 索引相关
# 查看索引 collection为集合名称
db.collection.getIndexes()

# 创建索引
# 1为正序  -1为倒序  也可以通过实体类添加@Indexed添加索引

db.daily_unit_report.createIndex({"date":-1,"unitId":1})

# 删除索引

db.collection.dropIndex("索引名称")

  1. 具体操作
#查看所有数据
db.集合名字.find()

依赖

  
         org.springframework.boot
        spring-boot-starter-data-mongodb
  

yml配置

spring:
  data:
    mongodb:
      # 两种配置都可,选择其中一种即可
      # 配置一
      # uri: mongodb://root:[email protected]:27017/mongo_demo?authSource=admin&authMechanism=SCRAM-SHA-1
      # 配置二
      username: root
      #易错点1 如果是纯数字
      password: '123456'
      database: mongo_demo
      host: 192.168.100.21
      port: 27017
      #易错点2
      authentication-database: admin

错误

  1. Caused by: com.mongodb.MongoCommandException: Command failed with error 18 (AuthenticationFailed): ‘Authentication failed.’
    原因分析:主要是没有配置认证数据库导致(authentication-database)具体见配置中的易错点2,mongodb默认会将认证和授权信息保存到admin数据库,所以在配置数据库连接的时候需要配置。

  2. Caused by: java.lang.IllegalArgumentException: Prohibited character at position 0
    原因分析:数据库密码为数字的时候比如配置为123456(如果不带引号),会识别不到,具体原因是spring-boot-starter-data-mongodb读取配置文件的时候password使用char[]数组接收,所以会识别不到导致报错,正确的做法是数字加单引号和双引号即可识别。
    此处还有两个小细节:

    1. password如果为字符串则不用带引号即可识别;
    2. 如果采用uri配置则即使是纯数字也可以识别。

使用

Mongodb有一个特别方便的地方就是,不用专门去创建集合的结构和_id,它会根据实体类自动去创建域(字段),如果你的实体类带有id字段,则会是用你的id,如果没有id字段则会自动生成一个。

  1. 实体对象:
@Data
@Document(collection = "user")
public class User {

    @Id
    private String id;

    private String name;

    private String userName;

    private String password;

    private String age;
}
  1. 注解:
  • @Document 用来表明关联的mongo中的那个collection(类似于表名)
  • @Indexed 为某个字段建立索引
  • @Field 声明属性对应的数据库中的哪个字段
  1. CRUD
  • MongoTemplate
@SpringBootTest
@Slf4j
public class UserTemplateTest {

    @Resource
    private MongoTemplate mongoTemplate;

    /**
     * 新增
     */
    @Test
    public void insert(){
        User user = User.builder().userName("template").age("100").build();
        mongoTemplate.insert(user);
    }

    /**
     * 删除
     */
    @Test
    public void delete(){
        Query query = new Query();
        query.addCriteria(Criteria.where("userName").is("template"));
        mongoTemplate.findAndRemove(query,User.class);
    }


    /**
     * 修改
     */
    @Test
    public void update(){
        Query query = new Query();
        query.addCriteria(Criteria.where("userName").is("template"));
        Update update = new Update();
        update.set("age","200");
        mongoTemplate.findAndModify(query,update,User.class);
    }

    /**
     * 查询
     */
    @Test
    public void findList(){
        Query query = new Query();
        query.addCriteria(Criteria.where("age").is("100"));
        //模糊匹配
        String pattern_name = "template";
        Pattern pattern = Pattern.compile("^.*" + pattern_name + ".*$", Pattern.CASE_INSENSITIVE);
        query.addCriteria(Criteria.where("userName").regex(pattern));
        List list = mongoTemplate.find(query,User.class);
        for (User tempUser : list) {
            System.out.println(tempUser);
        }
    }
}

   
  • extends MongoRepository

Dao层继承UserRepository

@Repository
public interface UserRepository extends MongoRepository {
}

增删改查

@SpringBootTest
public class UserTest {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private TestProperties testProperties;


    /**
     * 新增
     */
    @Test
    public void insert(){

        User user = new User();
        user.setName("amxliuli");
        user.setAge("19");
        user.setPassword("123456");
        user.setUserName("amxliuli");
        User insertUser = userRepository.insert(user);
        System.out.println(insertUser.toString());
    }

    /**
     * 查询所有
     */
    @Test
    public void findAll(){
        List lists = userRepository.findAll();
        for (User user: lists) {
            System.out.println(user);
        }
    }
    /**
     * 根据id查询
     */
    @Test
    public void findById(){
        User user = userRepository.findById("62cc09c776552e4c908f4666").get();
        System.out.println(user);
    }


    /**
     * 条件查询
     */
    @Test
    public void findUserList(){
        User user = new User();
        user.setName("amx");
        Example example = Example.of(user);
        List list = userRepository.findAll(example);
        System.out.println(list);
    }

    /**
     * 模糊匹配
     */
    @Test
    public void findLikeUserList(){
        ExampleMatcher matcher = ExampleMatcher.matching()
                .withStringMatcher(ExampleMatcher.StringMatcher.CONTAINING)
                .withIgnoreCase(true);
        User user = new User();
        user.setName("amx");
        Example example = Example.of(user,matcher);
        List list = userRepository.findAll(example);
        System.out.println(list);
    }

    /**
     * 更新
     */
    @Test
    public void update(){
        User user = userRepository.findById("62cc09c776552e4c908f4666").get();
        user.setAge("100");
        User updateUser = userRepository.save(user);
        System.out.println(updateUser);
    }

    /**
     * 删除
     */
    @Test
    public void delete(){
        userRepository.deleteAllById(Arrays.asList("62cc09c776552e4c908f4666"));
    }
}

性能对比

针对我司某系统的某数据表进行对比,此表共有86个字段,每条记录数据大小平均为2M,数据条数共有3000多条。

  1. 针对没有索引的列进行查询
数据库(ms) 第一次 第二次 第三次
mongo 1287 1175 985
mysql 4245 4310 4779
  1. mysql加索引,mongoDB无索引进行查询
数据库(ms) 第一次 第二次 第三次
mongo 246 201 215
mysql 498 510 478
  1. 都加索引
数据库(ms) 第一次 第二次 第三次
mongo 170 196 143
mysql 469 334 320

你可能感兴趣的:(Spring全家桶,java,数据库,Springboot,MongoDB)