Spring和Mongodb非关系型数据库整合详解

Spring和Mongodb非关系型数据库整合详解

一、概述

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

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

关系型数据库最典型的数据结构是表,由二维表及其之间的联系所组成的一个数据组织

优点:

  • 1、易于维护:都是使用表结构,格式一致;
  • 2、使用方便:SQL语言通用,可用于复杂查询;
  • 3、复杂操作:支持SQL,可用于一个表以及多个表之间非常复杂的查询。

缺点:

  • 1、读写性能比较差,尤其是海量数据的高效率读写;
  • 2、固定的表结构,灵活度稍欠;
  • 3、高并发读写需求,传统关系型数据库来说,硬盘I/O是一个很大的瓶颈。

非关系型数据库严格上不是一种数据库,应该是一种数据结构化存储方法的集合,可以是文档或者键值对等。

优点:

  • 1、格式灵活:存储数据的格式可以是key,value形式、文档形式、图片形式等等,文档形式、图片形式等等,使用灵活,应用场景广泛,而关系型数据库则只支持基础类型。
  • 2、速度快:nosql可以使用硬盘或者随机存储器作为载体,而关系型数据库只能使用硬盘;
  • 3、高扩展性;
  • 4、成本低:nosql数据库部署简单,基本都是开源软件。

缺点:

  • 1、不提供sql支持,学习和使用成本较高;
  • 2、无事务处理;
  • 3、数据结构相对复杂,复杂查询方面稍欠。

首发地址:
品茗IT-同步发布

品茗IT 提供在线支持:

一键快速构建Spring项目工具

一键快速构建SpringBoot项目工具

一键快速构建SpringCloud项目工具

一站式Springboot项目生成

Mysql一键生成Mybatis注解Mapper

如果大家正在寻找一个java的学习环境,或者在开发中遇到困难,可以加入我们的java学习圈,点击即可加入,共同学习,节约学习时间,减少很多在学习中遇到的难题。

二、环境配置

本文假设你已经引入Spring必备的一切了,已经是个Spring项目了,如果不会搭建,可以打开这篇文章看一看《Spring和Spring Mvc 5整合详解》

2.1 maven依赖

使用Mongodb需要引入spring-data-mongodb。

<?xml version="1.0"?>
<project
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
    xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>cn.pomit</groupId>
        <artifactId>SpringWork</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <artifactId>Mongodb</artifactId>
    <packaging>jar</packaging>
    <name>Mongodb</name>
    <url>http://maven.apache.org</url>
    <properties>
        <!-- redis 版本 -->
        <mongodb.version>2.1.8.RELEASE</mongodb.version>

    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-mongodb</artifactId>
            <version>${mongodb.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
        </dependency>

        <!--log4j-core -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
        </dependency>

        <!-- log4j-web -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
        </dependency>
    </dependencies>
    <build>
        <finalName>Mongodb</finalName>
    </build>
</project>


父模块可以在https://www.pomit.cn/spring/SpringWork/pom.xml获取。

2.2 Spring配置

需要配置mongodb地址登信息、mongoTemplate和mongo:repositories 。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mongo="http://www.springframework.org/schema/data/mongo"
    xsi:schemaLocation="http://www.springframework.org/schema/context
          http://www.springframework.org/schema/context/spring-context.xsd
          http://www.springframework.org/schema/data/mongo 
          http://www.springframework.org/schema/data/mongo/spring-mongo.xsd
          http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="annotationPropertyConfigurerMongodb"
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="order" value="1" />
        <property name="ignoreUnresolvablePlaceholders" value="true" />
        <property name="locations">
            <list>
                <value>classpath:mongodb.properties</value>
            </list>
        </property>
    </bean>

    <mongo:mongo-client host="${mongodb.host}" port="${mongodb.port}">
        <mongo:client-options connections-per-host="8"
            threads-allowed-to-block-for-connection-multiplier="4"
            connect-timeout="1000" max-wait-time="1500" socket-keep-alive="true"
            socket-timeout="1500" />
    </mongo:mongo-client>

    <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
        <constructor-arg ref="mongoClient" />
        <constructor-arg name="databaseName" value="${mongodb.dbName}" />
    </bean>
    
    <mongo:repositories base-package="cn.pomit.springwork.mongodb.dao" />
</beans>

mongodb.properties中存放mongodb的地址端口信息和数据库名称。

mongodb.properties:

mongodb.host=localhost
mongodb.port=27017
mongodb.dbName=pomit

三、使用MongoRepository访问数据层

3.1 Dao数据访问

我们直接使用Spring-data-mongodb, 一切都会变的特别简单。Spring-data-mongodb支持快速查询。

UserAddationDao:

package cn.pomit.springwork.mongodb.dao;

import org.springframework.data.mongodb.repository.MongoRepository;

import cn.pomit.springwork.mongodb.model.User;

public interface UserAddationDao extends MongoRepository<User, Long> {
    User findByName(String name);
}


这个写法和Spring-data-jpa基本上一样,应该说Spring-data系列的写法都是类同的。

**注意,User实体需要加上@Document注解指明mongodb中的collection。

3.2 业务逻辑

我们可以新建一个service来使用上面的MongoRepository。

UserAddationService :

package cn.pomit.springwork.mongodb.service;

import java.util.Date;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cn.pomit.springwork.mongodb.dao.UserAddationDao;
import cn.pomit.springwork.mongodb.model.User;

/**
 * 第二种方式
 * 
 * @author fufei
 *
 */
@Service
public class UserAddationService {
    private static final Logger logger = LoggerFactory.getLogger(UserAddationService.class);
    @Autowired
    private UserAddationDao userAddationDao;

    /**
     * 保存对象
     *
     * @param book
     * @return
     */
    public String save(User user) {
        logger.info("--------------------->[MongoDB save start]");
        user.setRegisterTime(new Date());
        userAddationDao.save(user);
        return "添加成功";
    }

    /**
     * 查询所有
     *
     * @return
     */
    public List<User> findAll() {
        logger.info("--------------------->[MongoDB find start]");
        return userAddationDao.findAll();
    }

    /***
     * 根据id查询
     * 
     * @param id
     * @return
     */
    public User getUserById(Long id) {
        logger.info("--------------------->[MongoDB find start]");
        return userAddationDao.findById(id).orElse(null);
    }

    /**
     * 根据名称查询
     *
     * @param name
     * @return
     */
    public User getUserByName(String name) {
        logger.info("--------------------->[MongoDB find start]");
        return userAddationDao.findByName(name);
    }

    /**
     * 更新对象
     *
     * @param book
     * @return
     */
    public String update(User user) {
        logger.info("--------------------->[MongoDB update start]");
        userAddationDao.save(user);
        return "success";
    }

    /***
     * 删除对象
     * 
     * @param book
     * @return
     */
    public String deleteUser(User user) {
        logger.info("--------------------->[MongoDB delete start]");
        userAddationDao.delete(user);
        return "success";
    }
}

3.3 测试Web

package cn.pomit.springwork.mongodb.web;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import cn.pomit.springwork.mongodb.model.User;
import cn.pomit.springwork.mongodb.service.UserAddationService;

@RestController
@RequestMapping("/mongo2")
public class MongodbAddationRest {
    @Autowired
    UserAddationService userService;

    @PostMapping("/save")
    public String saveObj(@RequestBody User user) {
        return userService.save(user);
    }

    @GetMapping("/findAll")
    public List<User> findAll() {
        return userService.findAll();
    }

    @GetMapping("/findOne")
    public User findOne(@RequestParam Long id) {
        return userService.getUserById(id);
    }

    @GetMapping("/findOneByName")
    public User findOneByName(@RequestParam String name) {
        return userService.getUserByName(name);
    }

    @PostMapping("/update")
    public String update(@RequestBody User user) {
        User existUser = userService.getUserById(user.getId());
        if (existUser == null) {
            existUser = user;
        } else {
            if (user.getAge() != null) {
                existUser.setAge(user.getAge());
            }

            if (user.getPassword() != null) {
                existUser.setPassword(user.getPassword());
            }

            if (user.getName() != null) {
                existUser.setName(user.getName());
            }

            if (user.getPhone() != null) {
                existUser.setPhone(user.getPhone());
            }

            if (user.getRegisterTime() != null) {
                existUser.setRegisterTime(user.getRegisterTime());
            }

            if (user.getUsername() != null) {
                existUser.setUsername(user.getUsername());
            }
        }

        return userService.update(existUser);
    }

    @PostMapping("/delOne")
    public String delOne(@RequestBody User user) {
        return userService.deleteUser(user);
    }
}

四、使用MongoTemplate访问数据层

下面是另一种操作mongodb的方式。

4.1 数据访问及业务层

使用MongoTemplate,我们可以不需要建dao这一层,在业务逻辑中直接使用MongoTemplate进行数据访问。

UserService :

package cn.pomit.springwork.mongodb.service;

import java.util.Date;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import cn.pomit.springwork.mongodb.model.User;


/**
 * 第一种方式
 * @author fufei
 *
 */
@Service
public class UserService {
    private static final Logger logger = LoggerFactory.getLogger(UserService.class);
    @Autowired
    private MongoTemplate mongoTemplate;

    /**
     * 保存对象
     *
     * @param book
     * @return
     */
    public String save(User user) {
        logger.info("--------------------->[MongoDB save start]");
        user.setRegisterTime(new Date());
        mongoTemplate.save(user);
        return "添加成功";
    }

    /**
     * 查询所有
     *
     * @return
     */
    public List<User> findAll() {
        logger.info("--------------------->[MongoDB find start]");
        return mongoTemplate.findAll(User.class);
    }

    /***
     * 根据id查询
     * 
     * @param id
     * @return
     */
    public User getUserById(Long id) {
        logger.info("--------------------->[MongoDB find start]");
        Query query = new Query(Criteria.where("_id").is(id));
        return mongoTemplate.findOne(query, User.class);
    }

    /**
     * 根据名称查询
     *
     * @param name
     * @return
     */
    public User getUserByName(String name) {
        logger.info("--------------------->[MongoDB find start]");
        Query query = new Query(Criteria.where("name").is(name));
        return mongoTemplate.findOne(query, User.class);
    }

    /**
     * 更新对象
     *
     * @param book
     * @return
     */
    public String update(User user) {
        logger.info("--------------------->[MongoDB update start]");
        Query query = new Query(Criteria.where("_id").is(user.getId()));
        Update update = new Update().set("password", user.getPassword()).set("age", user.getAge()).set("phone",
                user.getPhone());
        // updateFirst 更新查询返回结果集的第一条
        mongoTemplate.updateFirst(query, update, User.class);
        return "success";
    }

    /***
     * 删除对象
     * 
     * @param book
     * @return
     */
    public String deleteUser(User user) {
        logger.info("--------------------->[MongoDB delete start]");
        mongoTemplate.remove(user);
        return "success";
    }
}

4.2 测试Web

MongodbRest :

package cn.pomit.springwork.mongodb.web;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import cn.pomit.springwork.mongodb.model.User;
import cn.pomit.springwork.mongodb.service.UserService;

@RestController
@RequestMapping("/mongo")
public class MongodbRest {
    @Autowired
    UserService userService;

    @PostMapping("/save")
    public String saveObj(@RequestBody User user) {
        return userService.save(user);
    }

    @GetMapping("/findAll")
    public List<User> findAll() {
        return userService.findAll();
    }

    @GetMapping("/findOne")
    public User findOne(@RequestParam Long id) {
        return userService.getUserById(id);
    }

    @GetMapping("/findOneByName")
    public User findOneByName(@RequestParam String name) {
        return userService.getUserByName(name);
    }

    @PostMapping("/update")
    public String update(@RequestBody User user) {
        return userService.update(user);
    }

    @PostMapping("/delOne")
    public String delOne(@RequestBody User user) {
        return userService.deleteUser(user);
    }
}

五、过程中用到的实体

User :


详细完整的实体,可以访问品茗IT-博客《Spring和Mongodb非关系型数据库整合详解》进行查看

全部代码可以在Spring组件化构建https://www.pomit.cn/java/spring/spring.html中的MongoDb组件中查看,并下载。

快速构建项目

Spring组件化构建

SpringBoot组件化构建

SpringCloud服务化构建

喜欢这篇文章么,喜欢就加入我们一起讨论Spring技术吧!


品茗IT交流群
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,542评论 6 504
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,822评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,912评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,449评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,500评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,370评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,193评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,074评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,505评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,722评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,841评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,569评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,168评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,783评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,918评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,962评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,781评论 2 354

推荐阅读更多精彩内容