当前位置: 代码网 > it编程>数据库>Mysql > 关于MySQL存取图片的三种方式(含源码示例)

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

2024年05月15日 Mysql 我要评论
method1:采用blob数据格式存图片。其实这种方式很不合理,数据库大小会激增会导致简单的查询都及其缓慢。method2:采用文本格式存储图片。虽然也不怎么合理,因为关系型数据库本身就不太适合存巨

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存取图片的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com