一、在Ubuntu下进行MongoDB安装步骤:
1.MongoDB可以直接用apt-get命令进行安装。
sudo apt-get install mongodb
2.mongodb服务常用命令
- systemctl status mongodb // 查看状态
- systemctl start mongodb //启动
- systemctl restart mongodb //重新启动
- systemctl stop mongodb //停止
- mongo 或者 mongo ip地址:端口号 //进入数据库
- mongo --host=127.0.0.1 --port=27017
二、重启系统以后mongo程序要自己重新手动启动,步骤如下:
1.运行“locate mongo”命令查看系统默认把mongo装到了哪里,这里主要关注三个东西。
一个是名为“mongod”的程序的位置(他相当于mongo数据库的Server,需要一直在后台运行,我的路径:/usr/bin/mongod);
一个是mongo 数据库文件的位置(我的路径:/var/lib/mongodb/);
一个是mongo的log日志的位置(我的路径:/var/log/mongodb/mongodb.log)。
2.先进入mongod所在的目录(/usr/bin/mongod),然后运行“./mongod --dbpath /var/lib/mongodb/ --logpath /var/log/mongodb/mongodb.log --logappend &”
- --dbpath:指定mongo的数据库文件在哪个文件夹
- --logpath:指定mongo的log日志是哪个,这里log一定要指定到具体的文件名
- --logappend:表示log的写入是采用附加的方式,默认的是覆盖之前的文件
- &:表示程序在后台运行
注意:如果是系统非正常关闭,这样启动会报错,由于mongodb自动被锁上了,这是需要进入mongodb数据库文件所在的目录(/var/lib/mongodb/),删除目录中的mongodb.lock文件,然后再进行上述操作。
三、使用MongoDB
1.进入mongodb数据库
- mongo
- mongo ip地址:端口号 //进入数据库
- mongo --host=127.0.0.1 --port=27017
2.常用操作命令:
show dbs
:显示数据库列表
show collections
:显示当前数据库中的集合(类似关系数据库中的表table)
show users
:显示所有用户
use yourDB
:切换当前数据库至yourDB
db.help()
:显示数据库操作命令
db.yourCollection.help()
:显示集合操作命令,yourCollection是集合名
MongoDB没有创建数据库的命令,如果你想创建一个“School”的数据库,先运行use School命令,之后做一些操作(如:创建聚集集合db.createCollection('teacher')),这样就可以创建一个名叫“School”的数据库。截图如下:
下面以一个School数据库为例,在School数据库中创建两个集合teacher和student,并对student集合中的数据进行增删改查基本操作(集合Collection相当于关系型数据库中的表table)。
- 切换到School数据库
use School #切换到School数据库。MongoDB 无需预创建School数据库,在使用时会自动创建
- 创建Collection
db.createCollection('teacher') #创建一个聚集集合。MongoDB 其实在插入数据的时候,也会自动创建对应的集合,无需预定义集合
- 插入数据
与数据库创建类似,插入数据时也会自动创建集合。
插入数据有两种方式:insert和save。
db.student.insert({_id:1, sname: 'zhangsan', sage: 20}) #_id可选
db.student.save({_id:1, sname: 'zhangsan', sage: 22}) #_id可选
这两种方式,其插入的数据中_id字段均可不写,会自动生成一个唯一的_id来标识本条数据。而insert和save不同之处在于:在手动插入_id字段时,如果_id已经存在,insert不做操作,save做更新操作;如果不加_id字段,两者作用相同都是插入数据。
- 查找数据
db.youCollection.find(criteria, filterDisplay)
- criteria :查询条件,可选
- filterDisplay:筛选显示部分数据,如显示指定列数据,可选(当选择时,第一个参数不可省略,若查询条件为空,可用{}做占位符,如下例第三句)
- db.student.find() #查询所有记录。相当于:select * from student
- db.student.find({sname: 'lisi'}) #查询sname='lisi'的记录。相当于: select * from student where sname='lisi'
- db.student.find({},{sname:1, sage:1}) #查询指定列sname、sage数据。相当于:select sname,sage from student。sname:1表示返回sname列,默认_id字段也是返回的,可以添加_id:0(意为不返回_id)写成{sname: 1, sage: 1,_id:0},就不会返回默认的_id字段了
- db.student.find({sname: 'zhangsan', sage: 22}) #and 与条件查询。相当于:select * from student where sname = 'zhangsan' and sage = 22
- db.student.find({$or: [{sage: 22}, {sage: 25}]}) #or 条件查询。相当于:select * from student where sage = 22 or sage = 25
查询操作类似,这里只给出db.student.find({sname: 'lisi'})查询的截图,如下:
- 修改数据
db.youCollection.update(criteria, objNew, upsert, multi )
- criteria: update的查询条件,类似sql update查询内where后面的
- objNew : update的对象和一些更新的操作符(如$set)等,也可以理解为sql update查询内set后面的upsert ,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。
- multi: mongodb默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。默认false,只修改匹配到的第一条数据。
其中criteria和objNew是必选参数,upsert和multi可选参数。举例如下:
db.student.update({sname: 'lisi'}, {$set: {sage: 30}}, false, true) #相当于:update student set sage =30 where sname = 'lisi';
- 删除数据
db.student.remove({sname: 'chenliu'}) #相当于:delete from student where sname='chenliu'
- 退出shell命令模式
输入exit或者Ctrl+C退出shell命令模式
四、springBoot中使用MongoDB
1.pom文件
<!--mongo-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
2.yml文件配置
spring.data.mongodb.uri=mongodb://zzq:123456@localhost:27017/mydb
或者
spring:
data:
mongodb:
uri: mongodb://192.168.1.87:49901/ums
3.Controller层
@Api(tags = "文件上传下载API")
@RequestMapping("/api/file/")
@RestController
public class FileController {
@Autowired
private FileService fileService;
@ApiOperation("文件上传")
@PostMapping
public Result uploadFile(@RequestBody MultipartFile file, HttpServletRequest request) {
return Result.ok(fileService.uploadFile(file, request));
}
@ApiOperation("文件下载")
@GetMapping
public Result downloadFile(@RequestParam("ObjectId") String ObjectId, HttpServletResponse response) {
fileService.downloadFile(ObjectId, response);
return Result.ok();
}
@ApiOperation("文件删除")
@PutMapping
public Result deleteFile(@RequestParam("ObjectId") String ObjectId) {
fileService.deleteFile(ObjectId);
return Result.ok();
}
}
4.Service层
@Service
public class FileService {
private static final Logger LOGGER = LoggerFactory.getLogger(FileService.class);
@Autowired
private GridFsTemplate gridFsTemplate;
@Autowired
private MongoDbFactory mongodbfactory;
public Object uploadFile(MultipartFile file, HttpServletRequest request) {
try {
ObjectId objectId = null;
// 获得提交的文件名
String fileName = file.getOriginalFilename();
// 获得文件类型
String contentType = file.getContentType();
BufferedImage image = isImage(file.getInputStream());
int angle = 0;
if(image != null){
//获取需要旋转的角度 angle为0说明图片不需要进行旋转 直接返回图片
angle = ImageUtils.getRotateAngleForPhoto(file.getInputStream());
}
if(angle == 0){
// 获得文件输入流
InputStream ins = file.getInputStream();
// 将文件存储到mongodb中,mongodb 将会返回这个文件的objectId
objectId = gridFsTemplate.store(ins, fileName, contentType);
ins.close();
} else {
String name = fileName.substring(0, fileName.lastIndexOf(".") + 1) + "jpg";
image = ImageUtils.rotate(image, angle);
// 将文件存储到mongodb中,mongodb 将会返回这个文件的objectId
objectId = gridFsTemplate.store(ImageUtils.getImageStream(image), name, "image/jpeg");
image = null;
}
return objectId.toString();
} catch (Exception e) {
LOGGER.error(MsgEnum.UPLOAD_ERROR.getMessage(), e);
throw new ServerException(MsgEnum.UPLOAD_ERROR);
}
}
/**
* 判断文件是否为图片
*
* @param in
* @return
*/
public static BufferedImage isImage(InputStream in) {
try {
BufferedImage image = ImageIO.read(in);
return image;
} catch (IOException e) {
return null;
}
}
public void downloadFile(String objectId, HttpServletResponse response) {
DBObject query = new BasicDBObject("_id", new ObjectId(objectId));
GridFS gridFS = new GridFS(mongodbfactory.getLegacyDb());
GridFSDBFile file = gridFS.findOne(query);
try {
if (file == null) {
response.getWriter().write("文件已经不存在啦!");
} else {
// 通知浏览器进行文件下载
response.setContentType(file.getContentType());
String fileName = URLEncoder.encode(file.getFilename(), "UTF-8");
response.setHeader("Content-Disposition", "attachment;filename=\"" + fileName+"\"");
file.writeTo(response.getOutputStream());
}
} catch (Exception e) {
LOGGER.error(MsgEnum.DOWNLOAD_ERROR.getMessage(), e);
throw new ServerException(MsgEnum.DOWNLOAD_ERROR);
}
}
public void deleteFile(String objectIdString) {
ObjectId objectId = new ObjectId(objectIdString);
GridFS gridFS = new GridFS(mongodbfactory.getLegacyDb());
gridFS.remove(objectId);
}
}
-
ImageUtils
public final class ImageUtils {
/**
* 获取图片中需要调整的角度信息
* 图片的 exif 信息,
*
* @param in
* @return
*/
public static int getRotateAngleForPhoto(InputStream in) {
int angle = 0;
Metadata metadata = null;
try {
metadata = ImageMetadataReader.readMetadata(in);
// todo getFirstDirectoryOfType 方法是否有问题?获取第一个还是获取多个处理?
ExifDirectoryBase directory = metadata.getFirstDirectoryOfType(ExifDirectoryBase.class);
if (directory != null && directory.containsTag(ExifDirectoryBase.TAG_ORIENTATION)) {
// 原图片的方向信息
int orientation = directory.getInt(ExifDirectoryBase.TAG_ORIENTATION);
switch (orientation) {
case 6: // 6旋转90
angle = 90;
break;
case 3: //3 旋转180
angle = 180;
break;
case 8: //8旋转270
angle = 270;
break;
}
}
in.close();
} catch (Exception e) {
e.printStackTrace();
}
return angle;
}
/**
* 调整图片角度
*
* @param image
* @param angle
* @return
*/
public static BufferedImage rotate(BufferedImage image, int angle) {
int width = image.getWidth(null);
int height = image.getHeight(null);
//计算新图片的大小
Rectangle rectangle = calcRotatedSize(
new Rectangle(new Dimension(width, height)),
angle);
BufferedImage res = new BufferedImage(rectangle.width, rectangle.height, BufferedImage.TYPE_INT_RGB);
Graphics2D graphics2D = res.createGraphics();
//转换图片
graphics2D.translate(
(rectangle.width - width) / 2,
(rectangle.height - height) / 2);
graphics2D.rotate(Math.toRadians(angle), width / 2, height / 2);
graphics2D.drawImage(image, null, null);
graphics2D.dispose();
return res;
}
private static Rectangle calcRotatedSize(Rectangle src, int angle) {
// 角度超过90
if (angle >= 90) {
if (angle / 90 % 2 == 1) {
int temp = src.height;
src.height = src.width;
src.width = temp;
}
angle = angle % 90;
}
double r = Math.sqrt(src.height * src.height + src.width * src.width) / 2;
double len = 2 * Math.sin(Math.toRadians(angle) / 2) * r;
double angel_alpha = (Math.PI - Math.toRadians(angle)) / 2;
double angel_dalta_width = Math.atan((double) src.height / src.width);
double angel_dalta_height = Math.atan((double) src.width / src.height);
int len_dalta_width = (int) (len * Math.cos(Math.PI - angel_alpha
- angel_dalta_width));
int len_dalta_height = (int) (len * Math.cos(Math.PI - angel_alpha
- angel_dalta_height));
int des_width = src.width + len_dalta_width * 2;
int des_height = src.height + len_dalta_height * 2;
return new Rectangle(new Dimension(des_width, des_height));
}
public static InputStream getImageStream(BufferedImage bimage) {
InputStream is = null;
ByteArrayOutputStream bs = new ByteArrayOutputStream();
ImageOutputStream imOut;
try {
imOut = ImageIO.createImageOutputStream(bs);
ImageIO.write(bimage, "jpg", imOut);
is = new ByteArrayInputStream(bs.toByteArray());
is.close();
} catch (IOException e) {
e.printStackTrace();
}
return is;
}
}