MongoDB与分布式文件系统GridFS

mongodb介绍
MongoDB与分布式文件系统GridFS_第1张图片
Mongodb是非关系型数据库,存储Json格式数据 ,数据格式灵活。

在win7系统安装mongodb需要vc++运行库,如果没有则会提示“无法启动此程序,因为计算机中丢失
VCRUNTIME140.dll”。

安装完mongodb之后
启动mongodb
在bin目录的同级下创建几个文件夹具体如下:数据库路径(data目录)、日志路径(logs目录)并在logs目录下添加日志文件(mongo.log文件)
创建配置文件mongo.conf,文件内容如下:

#数据库路径
dbpath=d:\MongoDB\Server\3.4\data
#日志输出文件路径
logpath=d:\MongoDB\Server\3.4\logs\mongo.log
#错误日志采用追加模式
logappend=true
#启用日志文件,默认启用
journal=true
#这个选项可以过滤掉一些无用的日志信息,若需要调试使用请设置为false
quiet=true
#端口号 默认为27017
port=27017

安装 MongoDB服务
安装完mongodb之后,会自动的在windows的服务中注册一个mongodb服务
如果没有注册可以通过执行bin/mongod.exe,使用–install选项来安装服务,使用–config选项来指定之前创建的配置文件。
cmd进入d:\MongoDB\Server\3.4\bin
执行: mongod.exe ‐‐config “d:\MongoDB\Server\3.4\mongo.conf” ‐‐install
然后就可以在服务中去启动mongodb服务
也可以通过命令启动: net start MongoDB
关闭MongoDB服务: net stop MongoDB
移除MongoDB服务: " d:\MongoDB\Server\3.4\bin\mongod.exe" ‐‐remove

命令执行后,浏览器中输入http://127.0.0.1:27017看到如下界面即说明启动成功

安装studio3t
studio3t是mongodb优秀的客户端工具。官方地址在https://studio3t.com/
修改字体:
默认Studio3t的字体太小,需要修改字体:
点击菜单:Edit—>Preferences
点击Connect新建一个连接输入连接名称以及数据库所在的ip地址和端口(一般使用默认的27017)即可通过studio3t连接mongodb数据库

mongodb入门
基础概念
在mongodb中是通过数据库、集合、文档的方式来管理数据,下边是mongodb与关系数据库的一些概念对比:
MongoDB与分布式文件系统GridFS_第2张图片
@Document:是Spring Data mongodb提供的注解,用在实体类上,用来指定对应的是哪个表
比如: @Document(collection = “cms_page”) 表示该实体类对应的是cms_page这张表

项目使用spring data mongodb操作mongodb数据库
Spring Data Mongodb提供一套快捷操作mongodb的方法。
在pom.xml中添加依赖:

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

在classpath下配置application.yml

server:
  port: 31001
spring:
  application:
    name: xc‐service‐manage‐cms
  data:
    mongodb:
      uri: mongodb://root:123@localhost:27017
      database: xc_cms

创建Dao,继承MongoRepository,并指定实体类型和主键类型。

public interface CmsPageRepository extends MongoRepository<CmsPage,String> {
}

编写测试类
test下的包路径与main下的包路径保持一致。
测试程序使用@SpringBootTest和@RunWith(SpringRunner.class)注解,启动测试类会从main下找springBoot启动类,加载spring容器。
测试代码如下:

@SpringBootTest
@RunWith(SpringRunner.class)
public class CmsPageRepositoryTest {
@Autowired
CmsPageRepository cmsPageRepository;

**//分页测试**
@Test
public void testFindPage() {
int page = 0;//从0开始
int size = 10;//每页记录数
Pageable pageable = PageRequest.of(page,size);  //类似于PageHelper分页插件
Page<CmsPage> all = cmsPageRepository.findAll(pageable);
System.out.println(all);
}
}

基础方法测试
这里Dao接口继承了MongoRepository,在MongoRepository中定义了很多现成的方法,如save、delete等,通过下边的代码来测试这里父类方法。
添加

@Test
public void testInsert(){
//定义实体类
CmsPage cmsPage = new CmsPage();
cmsPage.setSiteId("s01");
cmsPage.setTemplateId("t01");
cmsPage.setPageName("测试页面");
cmsPageRepository.save(cmsPage); //使用save()方法进行保存
}

删除

@Test
public void testDelete() {
cmsPageRepository.deleteById("5b17a2c511fe5e0c409e5eb3");
}

修改
//修改

@Test
public void testUpdate() {
Optional<CmsPage> optional = cmsPageRepository.findOne("5b17a34211fe5e2ee8c116c9");
if(optional.isPresent()){  //如果查出来的对象不为空,用来防止出现空指针异常
CmsPage cmsPage = optional.get();
cmsPage.setPageName("测试页面01");
cmsPageRepository.save(cmsPage); //查出来进行修改再保存
}
}

关于Optional:
Optional是jdk1.8引入的类型,Optional是一个容器对象,它包括了我们需要的对象,使用isPresent方法判断所包
含对象是否为空,isPresent方法返回false则表示Optional包含对象为空,否则可以使用get()取出对象进行操作。
Optional的优点是:
1、提醒你非空判断。
2、将对象非空检测标准化。

自定义Dao方法
同Spring Data JPA一样Spring Data mongodb也提供自定义方法的规则,如下:
按照findByXXX,findByXXXAndYYY、countByXXXAndYYY等规则定义方法,实现查询操作。

public interface CmsPageRepository extends MongoRepository<CmsPage,String> {
//根据页面名称查询
CmsPage findByPageName(String pageName);
//根据页面名称和类型查询
CmsPage findByPageNameAndPageType(String pageName,String pageType);
//根据站点和页面类型查询记录数
int countBySiteIdAndPageType(String siteId,String pageType);
//根据站点和页面类型分页查询
Page<CmsPage> findBySiteIdAndPageType(String siteId,String pageType, Pageable pageable);
}

自定义条件查询
需求分析
在页面输入查询条件,查询符合条件的页面信息。
查询条件如下:
站点Id:精确匹配
模板Id:精确匹配
页面别名:模糊匹配

/**
     * 页面列表分页+条件查询
     *
     * @param page             当前页码
     * @param size             页面显示个数
     * @param queryPageRequest 查询条件
     * @return 页面列表
     */
    public QueryResponseResult findList(int page, int size, QueryPageRequest queryPageRequest) {//查询条件封装在QueryPageRequest中
        if (queryPageRequest == null) {
            queryPageRequest = new QueryPageRequest(); //防止空指针异常
        }
        if (page <= 0) {
            page = 1; //响应给前端的是1
        }
        page = page - 1;//为了适应mongodb的接口将页码减1(查询数据库的时候是0),mongodb和mysql不同,第一页的页码为0
        if (size <= 0) {
            size = 20;
        }
        //条件匹配器
        //页面名称模糊查询,需要自定义字符串的匹配器实现模糊查询
        ExampleMatcher exampleMatcher = ExampleMatcher.matching()
                .withMatcher("pageAliase", ExampleMatcher.GenericPropertyMatchers.contains());//根据别名模糊查询
        //条件值对象
        CmsPage cmsPage = new CmsPage();
        //站点ID
        if (StringUtils.isNotEmpty(queryPageRequest.getSiteId())) { //StringUtils是框架自带的工具类
            cmsPage.setSiteId(queryPageRequest.getSiteId());
        }
        //页面别名
        if (StringUtils.isNotEmpty(queryPageRequest.getPageAliase())) {
        //虽然页面别名是模糊查询,也需要设置到条件值对象中,条件匹配器需要从条件值对象中取值
            cmsPage.setPageAliase(queryPageRequest.getPageAliase()); 
        }
        //创建条件实例
        Example<CmsPage> example = Example.of(cmsPage, exampleMatcher);//将所有可能的条件封装成一个对象

        //分页对象
        Pageable pageable = PageRequest.of(page, size);
        //分页查询
        Page<CmsPage> all = cmsPageRepository.findAll(example, pageable); //findAll()为mongoRepository提供的查询所有的方法
        QueryResult queryResult = new QueryResult();
        queryResult.setList(all.getContent());//需要返回的数据
        queryResult.setTotal(all.getTotalElements());//总记录数
        QueryResponseResult queryResponseResult = new QueryResponseResult(CommonCode.SUCCESS, queryResult);
        //返回结果
        return queryResponseResult;
    }

GridFS介绍
GridFS是MongoDB提供的用于持久化存储文件的模块
它的工作原理是:
在GridFS存储文件是将文件分块存储,文件会按照256KB的大小分割成多个块进行存储,GridFS使用两个集合(collection)存储文件,一个集合是chunks, 用于存储文件的二进制数据;一个集合是files,用于存储文件的元数据信息(文件名称、块大小、上传时间等信息)。
从GridFS中读取文件要对文件的各各块进行组装、合并。

1、存文件
使用GridFsTemplate存储文件测试代码:

先向测试程序注入GridFsTemplate。
@Autowired
private GridFsTemplate gridFsTemplate;
@Test
public void testGridFs() throws FileNotFoundException {
//要存储的文件
File file = new File("d:/index_banner.html");
//定义输入流
FileInputStream inputStram = new FileInputStream(file);
//向GridFS存储文件
ObjectId objectId = = gridFsTemplate.store(inputStram, "轮播图测试文件01");   // 第一个参数为文件流,第二个参数为文件名称
//得到文件ID
String fileId = objectId.toString();
System.out.println(file);
}

存储原理说明:
文件存储成功得到一个文件id
此文件id是fs.files集合中的主键。
可以通过文件id查询fs.chunks表中的记录,得到文件的内容。(fs.files表的主键id和fs.chunks表的files_id是关联的)

2、读取文件
1)在config包中定义Mongodb的配置类,如下:
GridFSBucket用于打开下载流对象

@Configuration
public class MongoConfig {
@Value("${spring.data.mongodb.database}")
String db;
@Bean
public GridFSBucket getGridFSBucket(MongoClient mongoClient){
MongoDatabase database = mongoClient.getDatabase(db);
GridFSBucket bucket = GridFSBuckets.create(database);
return bucket;
}
}

测试代码如下:

@SpringBootTest
@RunWith(SpringRunner.class)
public class GridFsTest {
@Autowired
GridFsTemplate gridFsTemplate;
@Autowired
GridFSBucket gridFSBucket;
@Test
public void queryFile() throws IOException {
String fileId = "5b9c54e264c614237c271a99";
//根据id查询文件
GridFSFile gridFSFile =gridFsTemplate.findOne(Query.query(Criteria.where("_id").is(fileId)));  //_id是fs.files表的主键
//打开下载流对象 需要指定文件的id
GridFSDownloadStream gridFSDownloadStream =gridFSBucket.openDownloadStream(gridFSFile.getObjectId());
//创建gridFsResource,用于获取流对象
GridFsResource gridFsResource = new GridFsResource(gridFSFile,gridFSDownloadStream);
//获取流中的数据
String s = IOUtils.toString(gridFsResource.getInputStream(), "UTF‐8");
System.out.println(s);
}
...

你可能感兴趣的:(常用技术点解析)