Spring集成MongoDB实战

10 篇文章 0 订阅
4 篇文章 0 订阅

Spring集成MongoDB

简介

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

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

与RDBMS区别

SQL属于/概念MongoDB术语/概念解释/说明
databasedatabase数据库
tablecollection数据库表/集合
rowdocument数据记录行/文档
columnfield数据字段/域
indexindex索引
table joins表连接,MongoDB不支持
primary keyprimary 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()

依赖

  <dependency>
         <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-mongodb</artifactId>
  </dependency>

yml配置

spring:
  data:
    mongodb:
      # 两种配置都可,选择其中一种即可
      # 配置一
      # uri: mongodb://root:123456@192.168.100.21: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<User> list = mongoTemplate.find(query,User.class);
        for (User tempUser : list) {
            System.out.println(tempUser);
        }
    }
}

   
  • extends MongoRepository

Dao层继承UserRepository

@Repository
public interface UserRepository extends MongoRepository<User,String> {
}

增删改查

@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<User> 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<User> example = Example.of(user);
        List<User> 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<User> example = Example.of(user,matcher);
        List<User> 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)第一次第二次第三次
mongo12871175985
mysql424543104779
  1. mysql加索引,mongoDB无索引进行查询
数据库(ms)第一次第二次第三次
mongo246201215
mysql498510478
  1. 都加索引
数据库(ms)第一次第二次第三次
mongo170196143
mysql469334320
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值