JSP-04JSP数据访问

8 篇文章 0 订阅

一、学习目标

  1. 会使用include指令
  2. 掌握application对象的原理和应用
  3. 掌握对象的作用域
  4. 会使用JSP访问数据库
  5. 掌握JavaBean的概念和应用

二、include指令

问题:

同一项目中多个页面中含有大量相同代码。重复内容:页面头部、页面尾部、权限验证、…;存在问题:代码冗余、修改不便、开发工作量大

分析:

提取相同部分内容,统一维护

在原页面中加载==提取出的公共代码==

JSP提供了include指令,可以静态加载其他JSP页面

在翻译JSP文件时,插入一个包含文本或代码的文件

语法:

<%@ include file="应用文件路径" %>

使用include指令减少重复代码示例:

  1. 创建公共代码页面(authentication.jsp
  2. 提取登录权限验证的公共代码,放入其中
  3. 在首页( index.jsp )中引入公共代码页面

创建公共代码页面(authentication.jsp)提取登录权限验证的公共代码,放入其中

<%@ page import="com.aiden.entity.User" %>
<%@ page import="com.aiden.utils.Constants" %>
<%@ page import="com.aiden.utils.CookieUtils" %>
<%@ page import="java.util.Date" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
    //验证用户访问权限
    User user = (User) session.getAttribute(Constants.SESSION_USER);
    if (user == null) {
        //检查Cookie
        String loginPwd = CookieUtils.getCookieValue(request, "loginPwd");
        String loginName = CookieUtils.getCookieValue(request, "loginName");
        //判断非空与用户名密码验证
        if (loginName != null && loginPwd != null && "yunGe".equals(loginName) && "123456".equals(loginPwd)) {
            User userInfo = new User(10001, loginName, loginPwd, "男", new Date());
            session.setAttribute(Constants.SESSION_USER, userInfo);
            session.setMaxInactiveInterval(60);//设置失效时间为60秒
        } else {
            response.sendRedirect("login.jsp");
            return;
        }
    }
%>

在首页( index.jsp )中引入公共代码页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>首页</title>
</head>
<body>
	<%@include file="authentication.jsp" %>
	<h1>欢迎【<%=user.getUserName()%>】登录后台首页</h1>
</body>
</html>

二、application内置对象

需求:

在微博系统的用户登录页面,统计并显示网站访问人数

分析:

在application对象中添加一个数字类型属性用于统计登录人数,有用户登录时,属性值+1

在这里插入图片描述

使用application对象统计登录人数示例代码:

Integer count = (Integer) application.getAttribute("visitorCount");
if(count != null) {
    count = count + 1;
} else { 
    count = 1; 
}
application.setAttribute("visitorCount",count);
【您是本网站第<%= (Integer)application.getAttribute("visitorCount")%>位到访用户】

小结:

application 对象可将信息保存在服务器中,直到服务器关闭,否则application对象中保存的信息会在整个应用中都有效。与session对象相比,application对象生命周期更长,类似于系统的“全局变量”。

存储数据类型:Object

作用域:整个网站

销毁时间:关闭服务器

获取值:application.getAttribute(“key”)

存储值:application.setAttribute(“key”,value);


三、JSP对象作用域

JSP中包含四大作用域

1、page作用域: 当前页面

2、request作用域: 当前请求

3、session作用域: 当前会话

4、application作用域: 当前Web应用

作用域从小到大范围排序:

page < request < session < application

3.1page作用域

page作用域

作用域范围:当前页面
作用域对象:pageContext 对象

本页面读取pageContext对象中的数据

<%
	//pageA.jsp
    String pageName = "This is pageA";
    pageContext.setAttribute("pageName",pageName);
    System.out.println("控制台输出pageName:"+ pageContext.getAttribute("pageName"));
	//转发跳转pageB.jsp
    request.getRequestDispatcher("pageB.jsp").forward(request,response);
 %>

其他页面读取pageContext对象中的数据

<!--pageB.jsp-->
pageName: <%= pageContext.getAttribute("pageName")%>

观察pageB.jsp页面发现 pageName:Null

在这里插入图片描述

控制台运行结果正常输出 “控制台输出pageName:This is pageA”

在这里插入图片描述

结论: page作用域范围只在当前页有效


3.2request作用域

request作用域

作用域范围:当前请求

作用域对象: request对象

观察请求转发过程中,request对象中的数据

创建count.jsp页面,设置countPage属性并赋值

Integer countPage= (Integer)request.getAttribute("countPage");
if(countPage==null){
    countPage = 1;
}else{
    countPage++;
}
request.setAttribute("countPage",countPage);

one.jsp页面通过include指令引入count.jsp页面,并转发至two.jsp

<%@ include file="count.jsp" %>
<%
     request.getRequestDispatcher("two.jsp").forward(request,response);
%>

two.jsp页面通过include指令引入count.jsp页面,并输出request对象中的countPage属性

<%@ include file="count.jsp" %>
<h3>count in request: <%= request.getAttribute("countPage")%></h3>

运行结果:

在这里插入图片描述


3.2session作用域

session作用域

作用域范围:当前会话

作用域对象: session对象

观察请求过程中, session对象中的数据

修改count.jsp页面,在request对象和session对象中分别设置不同属性

Integer countInRequest = (Integer)request.getAttribute("countInRequest");
Integer countInSession = (Integer)session.getAttribute("countInSession");

countInRequest = (countInRequest==null)?1:countInRequest+1;
countInSession = (countInSession==null)?1:countInSession+1;

request.setAttribute("countInRequest",countInRequest);
session.setAttribute("countInSession",countInSession);

one.jsp页面通过include指令引入count.jsp页面,并重定向至two.jsp页面

<%@ include file="count.jsp" %>
<%
    response.sendRedirect("two.jsp");
%>

two.jsp页面通过include指令引入count.jsp页面,并输出request对象和session对象中的属性

<%@ include file="count.jsp" %>
<h3>count in request: <%= request.getAttribute("countInRequest")%></h3>
<h3>count in session: <%= session.getAttribute("countInSession")%></h3>

运行结果

在这里插入图片描述

3.2application作用域

application作用域

作用域范围:当前Web应用

作用域对象: application对象

观察请求过程中, application对象中的数据

修改count.jsp页面,在session对象和application对象中分别设置不同属性

Integer countInSession = (Integer) session.getAttribute("countInSession");
Integer countInApplication = (Integer) application.getAttribute("countInApplication");

countInSession = (countInSession == null) ? 1 : countInSession + 1;
countInApplication = (countInApplication == null) ? 1 : countInApplication + 1;

session.setAttribute("countInSession", countInSession);
application.setAttribute("countInApplication", countInApplication);

one.jsp页面通过include指令引入count.jsp页面,并重定向至two.jsp

<%@ include file="count.jsp" %>
<%
    response.sendRedirect("two.jsp");
%>

two.jsp页面通过include指令引入count.jsp页面,并输出session对象和application对象中的属性

<%@ include file="count.jsp" %>
<h3>count in session: <%= session.getAttribute("countInSession")%></h3>
<h3>count in application: <%= application.getAttribute("countInApplication")%></h3>

运行结果

在这里插入图片描述


四、JavaBean

将基础模块组件化,通过简单的组装,可以快速组成成品

在这里插入图片描述

JavaBean是可以跨平台的重用组件,本质是一个特殊的Java类

4.1JavaBean的特点

JavaBean的功能分类

  1. 封装数据
  2. 封装业务

JavaBean的规范

  1. 提供无参的公有构造方法
  2. 实现Serializable接口
  3. 属性私有
  4. 属性的getter、setter方法公有

JavaBean的优势

  1. 解决代码重复编写,减少代码冗余
  2. 功能区分明确
  3. 提高了代码的维护性

4.2使用JavaBean封装数据

在JSP中使用JavaBean : 按照JavaBean的规范修改User实体类

getter 、 setter方法命名规范

属性首字母大写,名为xxx的属性对应setXxx()方法

特殊属性的getter、setter方法命名规范

属性第二个字母大写,该属性名直接用作getter、setter方法的后半部分

属性名:uName,方法:getuNamesetuName

属性前两个字母大写,该属性名直接用作getter 、setter方法的后半部分

属性名:URL ;方法:getURLsetURL

属性首字母大写;该属性名直接用作getter 、setter方法的后半部分

属性名:Name;方法:getNamesetName

public class User implements Serializable {//1.实现序列化接口
    
    private static final long serialVersionUID = -6890038231098895941L;
    //2.属性私有化
    private int id;
    private String userId;//账户
    //省略其他属性
   
    public int getId() { //3.提供公有的getter、setter方法
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    //省略其他属性的getter和setter方法
}

五、在JSP中访问数据库

在JSP中可以借助JSP小脚本实现数据库连接

Java部分

  1. 数据控制、业务处理
  2. DAO接口:把对数据库的所有操作定义成抽象方法
  3. DAO实现类:给出DAO接口中定义方法的具体实现
  4. 实体类:用于存放、传输对象数据
  5. 工具类:配置文件读取类

JSP部分

数据展示


5.1JDBC回顾

第一步:加载JDBC驱动

​ 使用Class.forName( )方法加载JDBC驱动类到Java虚拟机中

第二步:与数据库建立连接

​ 调用DriverManager 类的getConnection()方法,获取数据库连接

第三步:发送SQL语句,得到返回结果

第四步:处理返回结果

第五步:数据库访问结束后,进行资源释放

JDBC编程模板

在这里插入图片描述

5.2DAO模式与业务层回顾

回顾数据访问层与业务层

  1. 数据库工具类 BaseDao =>位于 dao 包下
  2. 实体类 =>位于 entity 包下
  3. DAO接口 =>位于 dao 包下
  4. DAO实现类 =>位于 dao.impl 包下
  5. 业务接口 =>位于 service包下
  6. 业务接口实现类 =>位于 service.impl包下

5.3搭建三层架构

需求: 实现第三波书店首页图书类型导航菜单数据动态加载。

5.3.1添加maven依赖和database.properties

maven中添加依赖包

<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>8.0.26</version>
</dependency>
<dependency>
  <groupId>javax.servlet.jsp</groupId>
  <artifactId>jsp-api</artifactId>
  <version>2.2</version>
</dependency>
<dependency>
  <groupId>javax.servlet</groupId>
  <artifactId>javax.servlet-api</artifactId>
  <version>4.0.1</version>
</dependency>

resources根资源文件夹下添加database.properties配置文件

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/bookshopplus?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
user=root
password=root

5.3.2添加工具类BaseDao与ConfigManager

BaseDao

package com.bookshop.dao;


import com.bookshop.utils.ConfigManager;

import java.sql.*;

/**
 * 操作数据库的基类--静态类
 * @author Aiden
 */
public class BaseDao {
    //构造函数私有化
    private BaseDao() { }

    //在该类的内部提供一个静态的实例对象
    private static BaseDao baseDao = new BaseDao();//饿汉模式

    //提供一个对外获取实例对象的静态方法
    public static BaseDao getInstance() {
        return baseDao;
    }

    /**
     * 获取数据库连接对象
     *
     * @return
     */
    public static Connection getConnection() {
        Connection connection = null;
        String driver = ConfigManager.getInstance().getProperty("driver");
        String url = ConfigManager.getInstance().getProperty("url");
        String user = ConfigManager.getInstance().getProperty("user");
        String password = ConfigManager.getInstance().getProperty("password");
        try {
            Class.forName(driver);//加载驱动
            connection = DriverManager.getConnection(url, user, password);//建立连接
        } catch (Exception e) {
            e.printStackTrace();
        }
        return connection;
    }

    /**
     * 查询操作
     */
    public static ResultSet execute(Connection connection, PreparedStatement stmt, ResultSet rs,String sql, Object... params) throws SQLException {
        stmt = connection.prepareStatement(sql);
        for (int i = 0; i < params.length; i++) {
            stmt.setObject(i + 1, params[i]);
        }
        rs = stmt.executeQuery();
        return rs;
    }

    /**
     * 更新操作
     */
    public static int execute(Connection connection, PreparedStatement stmt,String sql, Object... params) throws SQLException {
        int updateRows = 0;
        stmt = connection.prepareStatement(sql);
        for (int i = 0; i < params.length; i++) {
            stmt.setObject(i + 1, params[i]);
        }
        updateRows = stmt.executeUpdate();
        return updateRows;
    }

    /**
     * 释放资源
     */
    public static boolean closeResource(Connection connection, PreparedStatement stmt, ResultSet rs) {
        boolean flag = true;
        if (rs != null) {
            try {
                rs.close();
                rs = null;//GC回收
            } catch (SQLException e) {
                e.printStackTrace();
                flag = false;
            }
        }
        if (stmt != null) {
            try {
                stmt.close();
                stmt = null;//GC回收
            } catch (SQLException e) {
                e.printStackTrace();
                flag = false;
            }
        }
        if (connection != null) {
            try {
                connection.close();
                connection = null;//GC回收
            } catch (SQLException e) {
                e.printStackTrace();
                flag = false;
            }
        }
        return flag;
    }
}

ConfigManager

package com.bookshop.utils;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

/**
 * @author Aiden
 * 读取配置文件的工具类-单例模式
 */
public class ConfigManager {

    //1.定义静态的实例属性
    private static ConfigManager configManager;
    //Properties操作配置文件的实例属性
    private static Properties properties;

    //2.将构造函数私有化
    private ConfigManager() {
        String configFile = "database.properties";
        InputStream is = null;
        properties = new Properties();
        try {
            is = ConfigManager.class.getClassLoader().getResourceAsStream(configFile);
            properties.load(is);
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (is != null) {
                try {
                    is.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    //3.静态内部类
    public static class ConfigManagerHelper {
        //final修饰
        private static final ConfigManager CONFIG_MANAGER = new ConfigManager();
    }

    //4.对外提供的获取ConfigManager实例的方法
    public static ConfigManager getInstance() {
        configManager = ConfigManagerHelper.CONFIG_MANAGER;
        return configManager;
    }
	//5.提供根据key获取对应value值的方法
    public static String getProperty(String key) {
        return properties.getProperty(key);
    }
}

5.3.3添加实体类

package com.bookshop.entity;

import java.io.Serializable;

/**
 * 图书类型实体类
 * @author Aiden
 */
public class Categorie implements Serializable {
    private static final long serialVersionUID = 3646156839950581681L;
    private Integer id;
    private String name;

    public Categorie() {}

    public Categorie(Integer id, String name) {
        this.id = id;
        this.name = name;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

5.3.4添加DAO接口

package com.bookshop.dao;

import com.bookshop.entity.Categorie;

import java.sql.SQLException;
import java.util.List;

/**
 * @author Aiden
 */
public interface CategorieDao {
    /**
     * 查询所有图书分类
     */
    List<Categorie> findAll() throws SQLException;
}

5.3.5添加DAO实现

package com.bookshop.dao.impl;

import com.bookshop.dao.BaseDao;
import com.bookshop.dao.CategorieDao;
import com.bookshop.entity.Categorie;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * 图书分类DAO实现
 *
 * @author Aiden
 */
public class CategorieDaoImpl implements CategorieDao {
    
    private Connection connection;

    public CategorieDaoImpl(Connection connection) {
        this.connection = connection;
    }

    @Override
    public List<Categorie> findAll() throws SQLException {
        List<Categorie> list = new ArrayList<>();
        String sql = "SELECT id,name FROM `categorie`";
        PreparedStatement stmt = null;//执行对象
        ResultSet rs = null;//结果集
        rs = BaseDao.execute(connection, stmt, rs, sql);//调用查询方法
        while (rs.next()) {
            Categorie categorie = new Categorie(rs.getInt("id"), rs.getString("name"));
            list.add(categorie);
        }
        BaseDao.closeResource(null, stmt, rs);
        //释放资源
        return list;
    }
}

5.3.6添加业务接口

package com.bookshop.service;

import com.bookshop.entity.Categorie;

import java.util.List;

/**
 * 图书分类业务接口
 *
 * @author Aiden
 */
public interface CategorieService {
    /**
     * 查询所有图书分类
     */
    List<Categorie> findAll();
}

5.3.7添加业务实现

package com.bookshop.service.impl;

import com.bookshop.dao.BaseDao;
import com.bookshop.dao.CategorieDao;
import com.bookshop.dao.impl.CategorieDaoImpl;
import com.bookshop.entity.Categorie;
import com.bookshop.service.CategorieService;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

/**
 * 图书类型业务实现类
 * @author Aiden
 */
public class CategorieServiceImpl implements CategorieService {

    @Override
    public List<Categorie> findAll() {
        List<Categorie> list = null;
        Connection connection = BaseDao.getConnection();
        CategorieDao dao = new CategorieDaoImpl(connection);
        try {
            list = dao.findAll();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            //关闭连接对象
            BaseDao.closeResource(connection, null, null);
        }
        return list;
    }
}

5.3.8在JSP页面显示加载数据

<%@ page import="com.bookshop.entity.Categorie" %>
<%@ page import="com.bookshop.service.CategorieService" %>
<%@ page import="com.bookshop.service.impl.CategorieServiceImpl" %>
<%@ page import="java.util.List" %>
<%@ page language="java" pageEncoding="UTF-8" %>
<div id="basket"><a href="#">目前您的购物篮是空的</a></div>
<div id="search">
    <form action="" method="post" target="_blank">
        <input type="text" class="search_key"/>
        <input type="submit" class="search_sub" value=""/>
    </form>
</div>
<div id="alltype">
    <h1 class="all_type black"><a href="#">查看所有分类>></a></h1>
    <div id="subnav">
        <ul class="black">
            <%
            	//实例化图书类型业务对象
                CategorieService categorieService = new CategorieServiceImpl();
            	//查询所有图书类型列表
                List<Categorie> list = categorieService.findAll();
                if (list != null) {
                    for (Categorie categorie : list) {
            %>
            <li>
                <a href="#"><%=categorie.getName()%></a>
            </li>
            <%
                    }
                }
            %>
        </ul>
    </div>
    <!--subnav end-->
</div>
<!--link start-->
<div id="choice_pub">
    <select name="publishs" id="publishs" class="n_select">
        <option>>>根据出版社选择图书</option>
        <option>北京师范大学出版社</option>
        <option>电子工业出版社</option>
    </select>
    <select name="publishs" id="special" class="n_select">
        <option>>>根据专题选择图书</option>
        <option>国庆出游专题</option>
        <option>新年计划专题</option>
    </select>
</div>

<div id="s_b_03"><a href="#">赖世雄美语从头学</a><br/><a href="#">沪江团购 ,价格更优惠</a></div>

5.3.9运行结果

在这里插入图片描述


六、总结

思维导图

在这里插入图片描述
学习讨论群: 617530501

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

众生云海,一念初见

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值