关于MySQL存取图片的三种方式(含源码示例)

2024-04-16 0 750
目录
  • 详细代码示例
    • Method1详细代码示例:
    • Method2 详细代码示例:包括存和取的代码
    • Method3 详细代码示例:

Method1:采用BLOB数据格式存图片。

其实这种方式很不合理,数据库大小会激增会导致简单的查询都及其缓慢。

Method2:采用文本格式存储图片。

虽然也不怎么合理,因为关系型数据库本身就不太适合存巨长的大数据量的东西。

但是由于只涉及到base64加密和解码,且可以都写入后台部分,减轻前端负担。

Method3:将图片单独存放在某个服务器上,数据库只存放他们的url地址。

最高效也是最常用的方法。

后面有展示两种示例。

详细代码示例

Method1详细代码示例:

由于目前做的这个项目,同学A之前一直使用的这种方式将文件中的图片读取到数据库表,所以我只写了对BloB类型图片的取数据部分的代码。且过程较繁琐,可用性不强,就不贴了。

这个代码是A给我发的,实在太久了,她也忘了出处了。有人知道请艾特我一下,我标上链接。

package org.springboot.wechatcity.utill;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

/**
* 存入和读取Blob类型的JDBC数据
*/
public class BlobUtill {

public void getBlob() {//读取Blob数据
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
con = JDBCTools.getConnection();
String sql = \”SELECT id,name,age,picture FROM animal WHERE id=5\”;
ps = con.prepareStatement(sql);
rs = ps.executeQuery();
if (rs.next()) {
int id = rs.getInt(1);
String name = rs.getString(2);
int age = rs.getInt(3);

Blob picture = rs.getBlob(4);//得到Blob对象
//开始读入文件
InputStream in = picture.getBinaryStream();
OutputStream out = new FileOutputStream(\”cat.png\”);
byte[] buffer = new byte[1024];
int len = 0;
while ((len = in.read(buffer)) != -1) {
out.write(buffer, 0, len);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}

public void insertBlob() {//插入Blob
Connection con = null;
PreparedStatement ps = null;
try {
con = JDBCTools.getConnection();
String sql = \”INSERT INTO animal(name,age,picture) VALUES(?,?,?)\”;
ps = con.prepareStatement(sql);
ps.setString(1, \”TheCat\”);
ps.setInt(2, 8);
InputStream in = new FileInputStream(\”J:/test1/TomCat.png\”);//生成被插入文件的节点流
//设置Blob
ps.setBlob(3, in);

ps.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCTools.release(con, ps);
}
}

}

package org.springboot.wechatcity.utill;

import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

/**
* JDBC工具类 用来建立连接和释放连接
*/
public class JDBCTools {

public static Connection getConnection() throws Exception {//连接数据库
String driverClass = \”com.mysql.cj.jdbc.Driver\”;
String url = \”jdbc:mysql://IP号:端口号/hmCity?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai\”;
String user = \”\”;
String password = \”\”;

Properties properties = new Properties();

InputStream in = Review.class.getClassLoader().getResourceAsStream(\”jdbc.properties\”);
properties.load(in);

driverClass = properties.getProperty(\”driver\”);
url = properties.getProperty(\”jdbcurl\”);
user = properties.getProperty(\”user\”);
password = properties.getProperty(\”password\”);
Class.forName(driverClass);
return DriverManager.getConnection(url, user, password);
}

public static void release(Connection con, Statement state) {//关闭数据库连接
if (state != null) {
try {
state.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (con != null) {
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}

}

public static void release(ResultSet rs, Connection con, Statement state) {//关闭数据库连接
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (state != null) {
try {
state.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (con != null) {
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}

Method2 详细代码示例:包括存和取的代码

示例:前端以表单形式提交数据信息和图片,后台以MultipartFile类型接收图片,并对图片进行BASE64编码,存储在mysql数据库中。

1.BASE64存图片。

note:建议图片处理部分单独写在service层,比较符合分层规则。

//头部信息
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Encoder;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
* TODO 将用户上传的信息存入数据库中
* 图片以MultipartFile格式上传
* @return
*/
@CrossOrigin(origins = {\”*\”, \”3600\”}) //跨域注解,所有域名都可访问,且cookie的有效期为3600秒
@RequestMapping(value = \”/pushMessageParam\”, method = RequestMethod.POST)
public int pushMessageBody(@RequestParam String id, MultipartFile file1, MultipartFile file2, MultipartFile file3) throws IOException{//若参数为map或json格式,必须写@RequestBody

List<MultipartFile> files =new ArrayList<>();//保存用户上传的所有图片,最多三张。
files.add(file1);
files.add(file2);
files.add(file3);

//****给上传的所有jpg、jpeg格式的图片添加头部header(这样取得时候不用解码,直接拿值就行),并进行转码。****
BASE64Encoder base64Encoder = new BASE64Encoder();//BASE64de 解码工具

try {

List<String> base64EncoderImgs = new ArrayList<>();//存放转码后的图片
String header = \”\”;//为转码后的图片添加头部信息

for (int i = 0; i < files.size(); i++) {//遍历所有文件
if (files.get(i) != null) {
if (!files.get(i).getOriginalFilename().endsWith(\”.jpg\”) && !files.get(i).getOriginalFilename().endsWith(\”.jpeg\”)) {
System.out.println(\”文件格式非法!\”);
} else if (\”jpg\”.equals(files.get(i).getOriginalFilename())) {//files.get(i).getOriginalFilename() 获取文件的扩展名.jpg .jpeg
header = \”data:image/jpg;base64,\”;
} else if (\”jpeg\”.equals(files.get(i).getOriginalFilename())) {
header = \”data:image/jpeg;base64,\”;
}
base64EncoderImgs.add(header + base64Encoder.encode(files.get(i).getBytes()));//转码
} else {
base64EncoderImgs.add(null);
}
}
} catch (IOException e) {
e.printStackTrace();
}

subMessageService.saveSubMessage(new SubMessage(id, base64EncoderImgs.get(0),
base64EncoderImgs.get(1), base64EncoderImgs.get(2));
System.out.println(\”用户消息已存入数据库!\”);

return 0;
}

2.BASE64取图片及前端显示测试

//直接取值返给前端就行
@RequestMapping(value = \”/getCrowdInfoById\”, method = RequestMethod.GET)
public String getCrowdInfoById() {
CrowdInfo crowdInfo = new CrowdInfo();
crowdInfo.setId(3);

return crowdInfoService.getCrowdInfoById(crowdInfo).getPicBase64();//直接返回前端base64编码后的图片
}

<!DOCTYPE html>
<html lang=\”en\”>
<head>
<meta charset=\”UTF-8\”>
<title>Title</title>
</head>
<!–<script src=\”base64.js\”></script>–>
<body>

<img src=\”\” width=\”350px\” height=\”500px\” id=\”kk\”>

<!–测试base64取图片的方式–>
<script src=\”https://code.jquery.com/jquery-3.1.1.min.js\”></script>
<script type=\”text/javascript\”>
function getCode() {
$.ajax({
url: \’/getCrowdInfoById\’,
type: \’get\’,
dataType:\’text\’,
data: {},
success: function (result) {
document.getElementById(\”kk\”).setAttribute(\”src\”, result);
}
})
}

window.onload = function () {
getCode();
}

</script>
</body>
</html>

result如下:

关于MySQL存取图片的三种方式(含源码示例)

Method3 详细代码示例:

示例1:前端以form表单上传图片时,可以采取以下这种方法存储。

@RequestMapping(value = \”/upDrugImg.htm\”, method = RequestMethod.POST)
public ModelAndView upDrugImg(@RequestParam(value = \”imgFile\”, required = false) MultipartFile file, HttpServletRequest request) {
//file是imgFile的别名,只能上传一张图
String path = request.getSession().getServletContext().getRealPath(\”drugIMG\”);
String fileName = file.getOriginalFilename();
// 获取上传文件类型的扩展名,先得到.的位置,再截取从.的下一个位置到文件的最后,最后得到扩展名
String ext = fileName.substring(fileName.lastIndexOf(\”.\”) + 1,fileName.length());
// 对扩展名进行小写转换
ext = ext.toLowerCase();
// 定义一个数组,用于保存可上传的文件类型
List fileTypes = new ArrayList();
fileTypes.add(\”jpg\”);
fileTypes.add(\”jpeg\”);
fileTypes.add(\”bmp\”);
fileTypes.add(\”gif\”);
if (!fileTypes.contains(ext)) { // 如果扩展名属于允许上传的类型,则创建文件
System.out.println(\”文件类型不允许\”);
return new ModelAndView(\”errorpage/404\”);
}
// String fileName = new Date().getTime()+\”.jpg\”;
File targetFile = new File(path, fileName);
if (!targetFile.exists()) {
targetFile.mkdirs();
}
// 保存
try {
//使用此方法保存必须要绝对路径且文件夹必须已存在,否则报错
file.transferTo(targetFile);
} catch (Exception e) {
// e.printStackTrace();
return new ModelAndView(\”errorpage/500\”);
}

//******************这部分根据自己需求写******************
//将图片名存入数据库
String drugImg = \”/drugIMG/\” + fileName;
Drug drug = (Drug) request.getSession().getAttribute(\”currentDrug\”);
drug.setDrug_picture(drugImg);
int flag = drugService.upDrugImg(drug);
if (flag != 1) {
// System.out.println(\”info:upload image failed!\”);
return new ModelAndView(\”redirect:./goUpDrugImg.htm\”);
}
return new ModelAndView(\”redirect:./goAllDrugByHouse.htm\”, \”updown\”, \”down\”);
}

前端jsp页面及后台实体类。

关于MySQL存取图片的三种方式(含源码示例)

示例2:小程序前端以upload()方式上传图片,后台接收将图片存储到服务器,并随机生成不重复的图片名,最后将图片名存入mysql数据库。

1.SpringContextUtil工具类,直接copy就行

package org.springboot.wechatcity.utill;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

/**
* Spring工具类
* 在非spring生命周期的地方使用javabean
* @author _Yuan
*/
@SuppressWarnings(\”unchecked\”)
@Component
public class SpringContextUtil implements ApplicationContextAware {
private static ApplicationContext appContext;

@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
appContext = applicationContext;
}

public static ApplicationContext getApplicationContext() {
return appContext;
}

//通过name,以及Clazz返回指定的Bean
public static <T> T getBean(String name, Class<T> clazz) throws BeansException {
return (T) appContext.getBean(name);
}

//通过name获取 Bean.
public static Object getBean(String name){
return getApplicationContext().getBean(name);
}

//通过class获取Bean.
public static <T> T getBean(Class<T> clazz){
return getApplicationContext().getBean(clazz);
}

}

2.上传图片类

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.CrossOrigin;
import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.*;
import java.io.File;
import javax.servlet.http.HttpServlet;

/**
* 图片上传到服务器,并将图片名存入数据库
*
* @author _Yuan
* @since 2020年6月10日00:14:45
*/

@CrossOrigin(origins = {\”*\”, \”3600\”}) //跨域注解,所有域名都可访问,且cookie的有效期为3600秒
@WebServlet(name = \”firstServlet\”, urlPatterns = \”/uploadPicture\”) //标记为servlet,以便启动器扫描。
public class UploadPictureController extends HttpServlet {

private static final Logger logger = LoggerFactory.getLogger(UploadPictureController.class);//日志

@Override
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

Map<String, Object> resultMap = new HashMap<>();//存返回信息,建议写,较规范

//获取文件需要上传到的路径
@SuppressWarnings(\”deprecation\”)
String path = request.getRealPath(\”/upload\”) + \”/\”;

// 判断存放上传文件的目录是否存在(不存在则创建)
File dir = new File(path);
if (!dir.exists()) {
dir.mkdir();
}
logger.debug(\”path=\” + path);

try {
//使用Apache文件上传组件处理文件上传步骤:
//1、创建一个DiskFileItemFactory工厂
DiskFileItemFactory factory = new DiskFileItemFactory();
//2、创建一个文件上传解析器
ServletFileUpload upload = new ServletFileUpload(factory);
//3、使用ServletFileUpload解析器解析上传数据,解析结果返回的是一个List<FileItem>集合,每一个FileItem对应一个Form表单的输入项
List<FileItem> list = upload.parseRequest(request);

//****看需求,我是一次只能传一张图,其实可以不用写成List***
List<String> names = new ArrayList<>();//用于存放所有图片名

for (FileItem item : list) {
//如果fileitem中封装的是普通输入项的数据
if (item.isFormField()) {
String name = item.getFieldName();
//解决普通输入项的数据的中文乱码问题
String value = item.getString(\”UTF-8\”);
System.out.println(name + \”=\” + value);
} else {//如果fileitem中封装的是上传文件
//得到上传的文件名称,
String uuid = UUID.randomUUID().toString().replace(\”-\”, \”\”);//UUID生成不重复的一串数字
String filename = uuid + \”.\” + \”jpg\”;
names.add(filename);
System.out.println(\”文件名:\” + filename);

//获取item中的上传文件的输入流
InputStream in = item.getInputStream();
//创建一个文件输出流
FileOutputStream out = new FileOutputStream(path + \”\\\\\” + filename);
//创建一个缓冲区
byte buffer[] = new byte[1024];
//判断输入流中的数据是否已经读完的标识
int len = 0;
//循环将输入流读入到缓冲区当中,(len=in.read(buffer))>0就表示in里面还有数据
while ((len = in.read(buffer)) > 0) {
//使用FileOutputStream输出流将缓冲区的数据写入到指定的目录(savePath + \”\\\\\” + filename)当中
out.write(buffer, 0, len);
}
//关闭输入流
in.close();
//关闭输出流
out.close();
//删除处理文件上传时生成的临时文件
item.delete();
System.out.println(\”文件上传服务器成功!\”);
}
}

//上传所有文件名
System.out.println(\”图片名正在上传…请稍等\”);
//******非spring生命周期用注解需要用到SpringContextUtil工具类*****
SubMessageService subMessageService = SpringContextUtil.getBean(\”sub\”, SubMessageService.class);

GetInfoId id = new GetInfoId();//为了获取ID,专门写的类
int ID = id.getID();
if (names.size() != 0) {//上传了图片
try {
subMessageService.uploadAllPictureNames(new PicturesNames(ID, names.get(0), null, null));//根据Id更新所有图片
System.out.println(\”消息ID为:\” + ID);
System.out.println(\”图片名已上传数据库成功~\”);
}catch (Exception e){
e.printStackTrace();
}
} else {
System.out.println(\”未上传图片\”);
}

} catch (Exception e) {
System.out.println(\”文件上传失败!\”);
e.printStackTrace();

}

resultMap.put(\”code\”, 0);
resultMap.put(\”msg\”, \”图片上传成功\”);
return resultMap;
}

结果:

关于MySQL存取图片的三种方式(含源码示例)

关于MySQL存取图片的三种方式(含源码示例)

以上就是关于MySQL存取图片的三种方式(含源码示例)的详细内容,更多关于MySQL存取图片的资料请关注悠久资源网其它相关文章!

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

悠久资源 Mysql 关于MySQL存取图片的三种方式(含源码示例) https://www.u-9.cn/database/mysql/185197.html

常见问题

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务