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