|
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如下:
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页面及后台实体类。
示例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存取图片的资料请关注脚本之家其它相关文章!
来源:https://www.jb51.net/database/319112kvn.htm
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作! |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|