【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}"/>


 

相关文章
|
5月前
|
负载均衡 算法 关系型数据库
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
本文聚焦 MySQL 集群架构中的负载均衡算法,阐述其重要性。详细介绍轮询、加权轮询、最少连接、加权最少连接、随机、源地址哈希等常用算法,分析各自优缺点及适用场景。并提供 Java 语言代码实现示例,助力直观理解。文章结构清晰,语言通俗易懂,对理解和应用负载均衡算法具有实用价值和参考价值。
大数据大厂之MySQL数据库课程设计:揭秘MySQL集群架构负载均衡核心算法:从理论到Java代码实战,让你的数据库性能飙升!
|
11天前
|
安全 Java
使用Java多态性进行数据类型转换
以上示范了如何通过多态性来执行安全有效地对于Java对象间相互之间进行正确方式与场合下正确格式与条件限定内对于各个层级关系内部成员及其功能调取与应有操作处理过程,并通过 `instanceof`关键字确保了程序运行期间遵循逻辑合理并符合预设规则条件限定内正常工作流程而无需担忧潜藏风险问题出现可能带来影响结果质量问题情况存在可能。
50 12
|
14天前
|
监控 Java 关系型数据库
HikariCP 高性能数据库连接池技术详解与实践指南
本文档全面介绍 HikariCP 高性能数据库连接池的核心概念、架构设计和实践应用。作为目前性能最优异的 Java 数据库连接池实现,HikariCP 以其轻量级、高性能和可靠性著称,已成为 Spring Boot 等主流框架的默认连接池选择。本文将深入探讨其连接管理机制、性能优化策略、监控配置以及与各种框架的集成方式,帮助开发者构建高性能的数据访问层。
70 8
|
13天前
|
监控 Java 关系型数据库
HikariCP 高性能数据库连接池技术详解与实践指南
本文档全面介绍 HikariCP 高性能数据库连接池的核心概念、架构设计和实践应用。作为目前性能最优异的 Java 数据库连接池实现,HikariCP 以其轻量级、高性能和可靠性著称,已成为 Spring Boot 等主流框架的默认连接池选择。本文将深入探讨其连接管理机制、性能优化策略、监控配置以及与各种框架的集成方式,帮助开发者构建高性能的数据访问层。
56 1
|
26天前
|
SQL 数据管理 BI
数据库操作三基石:DDL、DML、DQL 技术入门指南
本文围绕数据库操作核心语言 DDL、DML、DQL 展开入门讲解。DDL 作为 “结构建筑师”,通过CREATE(建库 / 表)、ALTER(修改表)、DROP(删除)等命令定义数据库结构;DML 作为 “数据管理员”,以INSERT(插入)、UPDATE(更新)、DELETE(删除)操作数据表记录,需搭配WHERE条件避免误操作;DQL 作为 “数据检索师”,通过SELECT结合WHERE、ORDER BY、LIMIT等子句实现数据查询与统计。三者相辅相成,是数据库操作的基础,使用时需注意 DDL 的不可撤销性、DML 的条件约束及 DQL 的效率优化,为数据库学习与实践奠定基础。
|
2月前
|
存储 缓存 算法
Java数据类型与运算符深度解析
本文深入解析Java中容易混淆的基础知识,包括八大基本数据类型(如int、Integer)、自动装箱与拆箱机制,以及运算符(如&与&&)的使用区别。通过代码示例剖析内存布局、取值范围及常见陷阱,帮助开发者写出更高效、健壮的代码,并附有面试高频问题解析,夯实基础。
|
2月前
|
缓存 关系型数据库 MySQL
MySQL数据库性能调优:实用技术与策略
通过秉持以上的策略实施具体的优化措施,可以确保MySQL数据库的高效稳定运行。务必结合具体情况,动态调整优化策略,才能充分发挥数据库的性能潜力。
117 0
|
3月前
|
存储 人工智能 JavaScript
Java中的数据类型转换
本文介绍了 Java 中常见的数据类型转换方法,涵盖字符串与整型、长整型、浮点型、布尔型及日期类型的相互转换,并讲解了可能出现的异常和处理方式。
136 0
|
4月前
|
存储 人工智能 关系型数据库
诚邀您参加《智启云存:AI时代数据库RDS存储新突破》线上闭门技术沙龙!
诚邀您参加6月11日(周三)14:00在线上举行的《智启云存:AI时代数据库RDS存储新突破》闭门活动。免费报名并有机会获得精美礼品,快来报名吧:https://hd.aliyun.com/form/6162
|
5月前
|
人工智能 关系型数据库 分布式数据库
媒体声音|从亚太到欧美,阿里云瑶池数据库凭何成为中企出海的技术底气?
在中企出海的时代浪潮中,瑶池数据库正凭借其技术创新、场景化解决方案、智能化能力、全球化布局,成为企业跨越挑战、构建全球竞争力的关键伙伴;同时也以硬核的技术实力证明了中国数据库的国际竞争力。