【JAVA秒会技术之搞定BLOB数据类型】如何读取及展示数据库中BLOB类型的图片

简介: 如何读取及展示数据库中BLOB类型的图片    【前言】最近在做某一需求时,需要从Oracle数据库读取图片。本以为数据库存储的会是一个简单的url,前台可以直接展示,结果却发现是BLOB二进制类型,于是乎,百度/Google了关键字“二进制图片读取及展示”,发现有很多“抄来抄去”的文章或博客,但是文章的质量都很低,而且结构比较混乱,看完之后仍然是“不明所以”。     最后,花了近2

如何读取及展示数据库中BLOB类型的图片

   【前言】最近在做某一需求时,需要从Oracle数据库读取图片。本以为数据库存储的会是一个简单的url,前台可以直接展示,结果却发现是BLOB二进制类型,于是乎,百度/Google了关键字“二进制图片读取及展示”,发现有很多“抄来抄去”的文章或博客,但是文章的质量都很低,而且结构比较混乱,看完之后仍然是“不明所以”。

    最后,花了近2个小时,耐心研究了一下,终于成功。于是总结如下,供大家参考,也作为自己积累备份所用!

      【核心点

       1.在PO类中用byte[]类型直接接受BLOB类型;

       2.将二进制转为Base64格式字符串(不要用sun.misc.BASE64Encoder类);

       3.前台html页面通过<img src="data:image/png;base64,{图片字段}"/>标签展示。

        1.需求概述

        ①从Oracle数据库的表中读取BLOB类型图片;

        ②在前端页面将图片展示出来。

        2.创建PO类,PO类中用byte[]类型直接接受BLOB类型 

package com.netease.numen.plus.netease.model;
import java.io.Serializable;
/**
 * 读取二进制blob类型图片
 * <p>Title: PhotoBytes</p>
 * @author  Liyan
 * @date    2017年3月6日 下午5:02:22
 */
public class PhotoBytes implements Serializable {
	private static final long serialVersionUID = -8775612234303127935L;
	/**二进制图片*/
	private byte[] photoBytes;
	public byte[] getPhotoBytes() {
		return photoBytes;
	}
	public void setPhotoBytes(byte[] photoBytes) {
		this.photoBytes = photoBytes;
	}	
}

        3.编写Mapper.xml文件

<?xml version="1.0" encoding="UTF-8" ?>  
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.**.netease.mapper.WorkCardMapper">

	<resultMap id="photoBytes" type="com.**.netease.model.PhotoBytes">
		<result column="PHOTO" property="photoBytes" />
	</resultMap>

	<!-- 根据员工工号查询照片 -->
	<select id="getPhoto" resultMap="photoBytes">
		SELECT
			PHOTO as photoBytes
		FROM
			EHRINBOUND.EHR_EMPLOYEE_PHOTO_V
		<where>
			<if test="jobNumber!=null">
				AND EHR_EMPLOYEE_CODE = #{jobNumber} 
			</if>
		</where>
	</select>
	
</mapper>

        4.编写Mapper.java文件

@Repository
public interface WorkCardMapper {
	public PhotoBytes getPhoto(Map<String, Object> param) throws Exception;
}

        5.编写Service.java文件

public interface WorkCardService {	
	public PhotoBytes getPhoto(final String jobNumber) throws Exception;
}

        6.编写ServiceImpl.java文件

@Service("workCardService")
public class WorkCardServiceImpl implements WorkCardService{
	@Inject
	WorkCardMapper mapper;
	@Override
	public  PhotoBytes getPhoto(String jobNumber) throws Exception {
        Map<String, Object> param = new HashMap<String, Object>(0);
	    param.put("jobNumber", jobNumber);
	}
}

        7.编写二进制流转Base64字符串的工具类

package com.netease.numen.plus.netease.util;
import java.io.IOException;
import org.apache.commons.codec.binary.Base64;
public class Base64ImageUtil {
	/**
	 * 二进制流转Base64字符串
	 * <p>Title: byteArr2String</p>
	 * @author Liyan
	 * @date   2017年3月6日 下午3:04:47
	 * @param data
	 * @return String
	 * @throws IOException    
	 */
	public static String byteArr2String(byte[] byteArr) throws Exception {
		String stringBase64 = null;		
		try {
			 Base64 encoder = new Base64();
			 stringBase64 =(byteArr != null ? encoder.encodeToString(byteArr) : "");
		} catch (Exception e) {
			throw new Exception("byteArr2String转换异常:"+e);
		}
		return stringBase64;
    }
}

      【引申:为什么不要使用sun.misc.BASE64Encoder类?

      很多人在使用Base64进行加密解密时,都是使用sun.misc包下的BASE64Encoder及BASE64Decoder。但是,可能会出现这样的状况:换了JDK后发现提示找不到该类!

      网上有办法说重新配置jre就行了。但事实上不是这么简单的,这是要看配置的jre的类型是execution environment(执行环境),还是alternate jre(替代jre)。

      这两种方法中,如果是第一种就不行,因为是执行环境,也就是不会含JDK的一些额外类,rt.jar中的很多包都会因为jre与jdk权限不同而导致被限定权限,其中就包含了sun包。

     如果是第二种方法,即JDK替代jre,这就没问题,因为使用的是jdk的权限,所以不会报这类的错误。

     但是,事实上,这两个方法都是sun公司的内部方法,并没有在java api中公开过,所以使用这些方法是不安全的,将来随时可能会从中去除,所以应该使用相应的替代对象及方法!【参考:http://fableking.iteye.com/blog/1426410】

       8.编写Controller.java文件

   以下为简写,主要步骤是将byte[]型转Base64的字符串,并返回给前端。实际还需要加上参数校验,异常处理,记录日志等逻辑。

package com.netease.numen.plus.netease.controller;
@Controller
@RequestMapping(value = "/workcard")
public class WorkCardController {
	@Inject
	WorkCardService service;
	
	@RequestMapping(value = "/getWorkCardInfo" )
	public String getWorkCardInfo(String jobNumber) {
		//根据员工工号,获取照片(byte[]类型)	
		PhotoBytes photoBytes = service.getPhoto(jobNumber);
		byte[] photoBytes2 = photoBytes.getPhotoBytes();
		//将二进制转为Base64格式字符串
		String photo64 = Base64ImageUtil.byteArr2String(photoBytes2);
		result = new ResultInf(200, "获取照片信息成功", photo64);
		SpringMvcUtil.renderJson(response, result);
		return null;
	}
}

       9.前台html页面展示

<img src="data:image/png;base64,{photo}"/>


 

相关文章
|
13天前
|
存储 监控 安全
单位网络监控软件:Java 技术驱动的高效网络监管体系构建
在数字化办公时代,构建基于Java技术的单位网络监控软件至关重要。该软件能精准监管单位网络活动,保障信息安全,提升工作效率。通过网络流量监测、访问控制及连接状态监控等模块,实现高效网络监管,确保网络稳定、安全、高效运行。
43 11
|
23天前
|
XML Java 编译器
Java注解的底层源码剖析与技术认识
Java注解(Annotation)是Java 5引入的一种新特性,它提供了一种在代码中添加元数据(Metadata)的方式。注解本身并不是代码的一部分,它们不会直接影响代码的执行,但可以在编译、类加载和运行时被读取和处理。注解为开发者提供了一种以非侵入性的方式为代码提供额外信息的手段,这些信息可以用于生成文档、编译时检查、运行时处理等。
59 7
|
1月前
|
XML Java 数据库连接
性能提升秘籍:如何高效使用Java连接池管理数据库连接
在Java应用中,数据库连接管理至关重要。随着访问量增加,频繁创建和关闭连接会影响性能。为此,Java连接池技术应运而生,如HikariCP。本文通过代码示例介绍如何引入HikariCP依赖、配置连接池参数及使用连接池高效管理数据库连接,提升系统性能。
64 5
|
5天前
|
移动开发 前端开发 Java
Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML)
JavaFX是Java的下一代图形用户界面工具包。JavaFX是一组图形和媒体API,我们可以用它们来创建和部署富客户端应用程序。 JavaFX允许开发人员快速构建丰富的跨平台应用程序,允许开发人员在单个编程接口中组合图形,动画和UI控件。本文详细介绍了JavaFx的常见用法,相信读完本教程你一定有所收获!
Java最新图形化界面开发技术——JavaFx教程(含UI控件用法介绍、属性绑定、事件监听、FXML)
|
1月前
|
JSON Java 关系型数据库
Java更新数据库报错:Data truncation: Cannot create a JSON value from a string with CHARACTER SET 'binary'.
在Java中,使用mybatis-plus更新实体类对象到mysql,其中一个字段对应数据库中json数据类型,更新时报错:Data truncation: Cannot create a JSON value from a string with CHARACTER SET 'binary'.
84 4
Java更新数据库报错:Data truncation: Cannot create a JSON value from a string with CHARACTER SET 'binary'.
|
23天前
|
JavaScript 安全 Java
java版药品不良反应智能监测系统源码,采用SpringBoot、Vue、MySQL技术开发
基于B/S架构,采用Java、SpringBoot、Vue、MySQL等技术自主研发的ADR智能监测系统,适用于三甲医院,支持二次开发。该系统能自动监测全院患者药物不良反应,通过移动端和PC端实时反馈,提升用药安全。系统涵盖规则管理、监测报告、系统管理三大模块,确保精准、高效地处理ADR事件。
|
1月前
|
监控 前端开发 Java
【技术开发】接口管理平台要用什么技术栈?推荐:Java+Vue3+Docker+MySQL
该文档介绍了基于Java后端和Vue3前端构建的管理系统的技术栈及功能模块,涵盖管理后台的访问、登录、首页概览、API接口管理、接口权限设置、接口监控、计费管理、账号管理、应用管理、数据库配置、站点配置及管理员个人设置等内容,并提供了访问地址及操作指南。
|
6天前
|
存储 Oracle 关系型数据库
数据库传奇:MySQL创世之父的两千金My、Maria
《数据库传奇:MySQL创世之父的两千金My、Maria》介绍了MySQL的发展历程及其分支MariaDB。MySQL由Michael Widenius等人于1994年创建,现归Oracle所有,广泛应用于阿里巴巴、腾讯等企业。2009年,Widenius因担心Oracle收购影响MySQL的开源性,创建了MariaDB,提供额外功能和改进。维基百科、Google等已逐步替换为MariaDB,以确保更好的性能和社区支持。掌握MariaDB作为备用方案,对未来发展至关重要。
24 3
|
6天前
|
安全 关系型数据库 MySQL
MySQL崩溃保险箱:探秘Redo/Undo日志确保数据库安全无忧!
《MySQL崩溃保险箱:探秘Redo/Undo日志确保数据库安全无忧!》介绍了MySQL中的三种关键日志:二进制日志(Binary Log)、重做日志(Redo Log)和撤销日志(Undo Log)。这些日志确保了数据库的ACID特性,即原子性、一致性、隔离性和持久性。Redo Log记录数据页的物理修改,保证事务持久性;Undo Log记录事务的逆操作,支持回滚和多版本并发控制(MVCC)。文章还详细对比了InnoDB和MyISAM存储引擎在事务支持、锁定机制、并发性等方面的差异,强调了InnoDB在高并发和事务处理中的优势。通过这些机制,MySQL能够在事务执行、崩溃和恢复过程中保持
29 3
|
6天前
|
SQL 关系型数据库 MySQL
数据库灾难应对:MySQL误删除数据的救赎之道,技巧get起来!之binlog
《数据库灾难应对:MySQL误删除数据的救赎之道,技巧get起来!之binlog》介绍了如何利用MySQL的二进制日志(Binlog)恢复误删除的数据。主要内容包括: 1. **启用二进制日志**:在`my.cnf`中配置`log-bin`并重启MySQL服务。 2. **查看二进制日志文件**:使用`SHOW VARIABLES LIKE &#39;log_%&#39;;`和`SHOW MASTER STATUS;`命令获取当前日志文件及位置。 3. **创建数据备份**:确保在恢复前已有备份,以防意外。 4. **导出二进制日志为SQL语句**:使用`mysqlbinlog`
33 2