基于jsp、servlet、MySQL 实现读取显示数据库中的图片

web 专栏收录该内容
2 篇文章 0 订阅
  1. 首先介绍mysql数据库表的信息:
CREATE TABLE `imgtest` (
  `id` int(10) NOT NULL AUTO_INCREMENT COMMENT '图片id',
  `name` varchar(20) NOT NULL COMMENT '名称',
  `image` blob NOT NULL COMMENT '照片',
  PRIMARY KEY (`id`)
) 

注意:图片存储为 blob格式,直接存储在数据库中,而没有选择存储路径


2.介绍项目文件结构,我使用的是 MyEclipse

这里写图片描述

3.解析主要代码
ImageBean.java 为与表结构对应的bean类:

public class ImageBean {
    private int id;                // 图片id
    private String name;           // 图片名字
    private InputStream inStream;  // 图片字节流
    .....此处省略getset方法
}

JDBCUtil.java 类包含数据库的连接操作和关闭操作,此处省略,详见附件代码


GeneralDao.java 包含通用的增删查改操作,这里只给出两个用到的查询函数:

// 查询,返回一个对象
public static Object query(String sql, Object[] values, RowMapper rowMapper) {
    Object object = null;
    Connection conn = JDBCUtil.getConn();
    PreparedStatement preStmt = null;
    ResultSet rs = null;  // 查询结果集
    try {
        preStmt= conn.prepareStatement(sql);
        for(int i =0;i<values.length;i++)
            preStmt.setObject(i+1, values[i]); // 将查询参数放入sql语句中
        rs = preStmt.executeQuery();
        object = rowMapper.rowMapping(rs);  // 映射为一个对象
    } catch (SQLException e) {
        e.printStackTrace();
    }finally{
        JDBCUtil.closeConn(rs,preStmt,conn);
    }
    return object;
}

    // 查询,返回一组对象
    public static List query(String sql, Object[] values, RowMapperList rowMapperList) {
        List list = null;
        Connection conn = JDBCUtil.getConn();
        PreparedStatement preStmt = null;
        ResultSet rs = null;
        try {
            preStmt= conn.prepareStatement(sql);
            for(int i =0;i<values.length;i++)
                preStmt.setObject(i+1, values[i]);
            rs = preStmt.executeQuery();
            list = rowMapperList.rowMapping(rs);  // 映射为一个list
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            JDBCUtil.closeConn(rs,preStmt,conn);
        }
        if (list == null || list.isEmpty() || list.size() == 0) {
            return null;    
        }
        return list;
    }

RowMapper.java 和 RowMapperList.java 分别是两个接口,供内部类实现
RowMapper.java :

public interface RowMapper {
    public Object rowMapping(ResultSet rs) throws SQLException;

}

RowMapperList.java :

public interface RowMapperList {

    public List rowMapping(ResultSet rs) throws SQLException;
}

ImageDao.java 里面是对数据库表的详细操作:

public class ImageDao {

    // 查询所有记录
    public static List<ImageBean> query(String sql) {
        Object[] values = new Object[] {};
        ImageRML rowMapperList = new ImageRML();
        List<ImageBean> list = GeneralDao.query(sql, values, rowMapperList);
        return list;
    }

    // 根据id,查询图片字节流
    public static InputStream queryImgStream(int id) {
        String sql = "select image from imgtest where id = ?";
        Object[] values = new Object[] {id};
        ImageRM rowMapper = new ImageRM();
        ImageBean imageBean = (ImageBean)GeneralDao.query(sql, values, rowMapper);
        // 如果查询结果为空
        if (imageBean.equals(null)) {
            return null;
        }
        return imageBean.getInStream();
    }
}

// 一条记录映射
class ImageRM implements RowMapper {

    @Override
    public Object rowMapping(ResultSet rs) throws SQLException {
        if (rs.next()) {
            ImageBean imageBean = new ImageBean();
            // 获取图片字节
            imageBean.setInStream(rs.getBinaryStream("image"));
            return imageBean;
        }

        return null;
    }

}

// 一组记录映射
class ImageRML implements RowMapperList {

    public List<ImageBean> rowMapping(ResultSet rs) throws SQLException 
    {
        List<ImageBean> list = new ArrayList<ImageBean>();
        // 如果rs有数据
        if (rs.next()) {
            do {
                ImageBean imageBean = new ImageBean();
                imageBean.setId(rs.getInt("id"));
                imageBean.setName(rs.getString("name"));
                list.add(imageBean);
            } while (rs.next());
        }
        else {
            return null;
        }
        return list;
    }
}

ImageOutServlet.java 为显示图片的servlet:

public class ImageOutServlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        doPost(request, response);
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 获取请求传过来的id,对应的就是图片的id
        String temp = request.getParameter("id");
        int id = Integer.parseInt(temp);
        // 获取图片字节流
        InputStream inStream = ImageDao.queryImgStream(id);
        // 建立图片输出的输出流
        ServletOutputStream soutStream = response.getOutputStream();
        if (inStream.equals(null)) {
            soutStream.println("图片无法显示 !<br>");
        } else {
            // 定义字节流缓冲数组
            byte[] buffer = new byte[1024];

            // 循环输出字节流, 为空时,read()返回 -1
            while (inStream.read(buffer) != -1) {
                soutStream.write(buffer);
            }
            // 输入完毕,清楚缓冲
            soutStream.flush();
            soutStream.close();
        }
    }
}

4.jsp显示页面:

<body>
  <%
    String sql = "select id,name from imgtest";
    List<ImageBean> list = ImageDao.query(sql);
    // 如果结果集不为空
    if (list.size() > 0) {
   %>
    <table>
        <th>id</th><th>名称</th><th>图片</th>
    <%
        for (ImageBean bean : list) {
    %>
        <tr>
        <td><%=bean.getId() %></td>
        <td><%=bean.getName() %></td>
        <!-- 通过bean.getId() 将图片id传给servlet,然后返回显示 -->
        <!-- 这里 src 路径,要根据目录结构来确定,如果图片显示个X,大多是路径问题 -->
        <td><img style="width:50px;height:50px" src="servlet/ImageOutServlet?id=<%=bean.getId()%>"></td>
        </tr>
    <%      
        } // for 
    }// if    
     %>

    </table>
  </body>

5.最后把项目部署到服务器(tomcat)上,然后启动,在浏览器地址栏输入:http://localhost:8089/ImageShow/ShowImg.jsp,我的端口为8089,你们根据自己的端口来。显示结果为:
这里写图片描述


辛苦大家看到最后,可能之间的数据库操作略显麻烦,但那是为了我项目的所有表的操作的方便,以及代码复用,没有涉及到什么框架。
如果为了尽快看到效果,也可以直接将数据库查询操作放在jsp中和servlet中,根据自己需要来。
代码还存在很多不足,还请见谅,普通学生水平。有什么意见,尽管提出,大家互相交流。
过几天会接着贴上项目地址

这里附上 码云地址,里面包含了两种图片上传方式,由于能力有限,难免会有错误和局限的地方,请多包含
https://gitee.com/sys_code/ImageShow

©️2021 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值