黑马程序员Javaweb学习笔记03

该博客主要记录在学习黑马程序员Javaweb过程的一些笔记,方便复习以及加强记忆


系列文章

JavaWeb学习笔记01 BS架构 Maven Tomcat Servlet

JavaWeb学习笔记02 request和response

JavaWeb学习笔记03 JSP MVC
JavaWeb学习笔记04 待完善

文章目录

  • 一、JSP概述
    • 1.1 JSP快速入门
    • 1.2 JSP原理
    • 1.3 JSP脚本以及使用
    • 1.4 JSP缺点
  • 二、EL表达式
    • 2.1 概述
    • 2.2 用法展示
  • 三、JTSL
    • 3.1 JSTL快速入门-if
    • 3.2 JSTL快速入门-foreach
  • 四、MVC和三层架构
    • 4.1 MVC
    • 4.2 三层架构
    • 4.3 关系
  • 五、案例
    • 5.1 环境准备
    • 5.2 功能1-查询所有
    • 5.3 功能2-添加
    • 5.4 功能3-修改数据
    • 小提一句


一、JSP概述

JSP是什么?JSP有什么用?

简单来说,JSP中可以更方便书写Java和html代码,更好地编写网页使得动态和静态内容结合 假如没有JSP,则在httpServlet中书写Java和HTML代码,在网页中输出一个由数据库获取的变量或者是request中存储的变量就在httpServlet类中编写Java代码,同时html代码由writer.write方法去书写,会使得HTML代码书写困难且难阅读


黑马程序员Javaweb学习笔记03_第1张图片

下面这种形式就非常难阅读且难编写
黑马程序员Javaweb学习笔记03_第2张图片


使用JSP编写后
黑马程序员Javaweb学习笔记03_第3张图片

1.1 JSP快速入门

黑马程序员Javaweb学习笔记03_第4张图片


坐标代码:

    <dependency>
      <groupId>javax.servlet.jspgroupId>
      <artifactId>jsp-apiartifactId>
      <version>2.2version>
      <scope>providedscope>
    dependency>

当我们开启tomcat去访问jsp文件时:
黑马程序员Javaweb学习笔记03_第5张图片

1.2 JSP原理

黑马程序员Javaweb学习笔记03_第6张图片

1.3 JSP脚本以及使用

黑马程序员Javaweb学习笔记03_第7张图片
用法如下【由于jsp不常用,这里简单描述】:
黑马程序员Javaweb学习笔记03_第8张图片

效果:

黑马程序员Javaweb学习笔记03_第9张图片

案例
黑马程序员Javaweb学习笔记03_第10张图片
由于这里主要研究jsp,这些数据创建一个集合来模拟从数据库中获取到的数据

实体类代码:

package com.pojo;

/**
 * 品牌实体类
 */

public class brand {
    // id 主键
    private Integer id;
    // 品牌名称
    private String brandName;
    // 企业名称
    private String companyName;
    // 排序字段
    private Integer ordered;
    // 描述信息
    private String description;
    // 状态:0:禁用  1:启用
    private Integer status;


    public brand() {
    }

    public brand(Integer id, String brandName, String companyName, String description) {
        this.id = id;
        this.brandName = brandName;
        this.companyName = companyName;
        this.description = description;
    }

    public brand(Integer id, String brandName, String companyName, Integer ordered, String description, Integer status) {
        this.id = id;
        this.brandName = brandName;
        this.companyName = companyName;
        this.ordered = ordered;
        this.description = description;
        this.status = status;
    }

    public Integer getId() {
        return id;
    }

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

    public String getBrandName() {
        return brandName;
    }

    public void setBrandName(String brandName) {
        this.brandName = brandName;
    }

    public String getCompanyName() {
        return companyName;
    }

    public void setCompanyName(String companyName) {
        this.companyName = companyName;
    }

    public Integer getOrdered() {
        return ordered;
    }

    public void setOrdered(Integer ordered) {
        this.ordered = ordered;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public Integer getStatus() {
        return status;
    }

    public void setStatus(Integer status) {
        this.status = status;
    }

    @Override
    public String toString() {
        return "Brand{" +
                "id=" + id +
                ", brandName='" + brandName + '\'' +
                ", companyName='" + companyName + '\'' +
                ", ordered=" + ordered +
                ", description='" + description + '\'' +
                ", status=" + status +
                '}';
    }
}

动态jsp代码

<%--
  Created by IntelliJ IDEA.
  User: 边牧
  Date: 2023/1/4
  Time: 16:58
  To change this template use File | Settings | File Templates.
--%>
<%@ page import="com.pojo.brand" %>
<%@ page import="java.util.List" %>
<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>

<%
    // 查询数据库,假数据
    List<brand> brands = new ArrayList<brand>();
    brands.add(new brand(1,"三只松鼠","三只松鼠",100,"三只松鼠,好吃不上火",1));
    brands.add(new brand(2,"优衣库","优衣库",200,"优衣库,服适人生",0));
    brands.add(new brand(3,"小米","小米科技有限公司",1000,"为发烧而生",1));

%>


<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<input type="button" value="新增"><br>
<hr>
<table border="1" cellspacing="0" width="800">
    <tr>
        <th>序号</th>
        <th>品牌名称</th>
        <th>企业名称</th>
        <th>排序</th>
        <th>品牌介绍</th>
        <th>状态</th>
        <th>操作</th>
    </tr>
    <%
        for (int i = 0; i < brands.size(); i++) {
            brand brand = brands.get(i);
    %>
    <tr align="center">
        <td><%=brand.getId()%></td>
        <td><%=brand.getBrandName()%></td>
        <td><%=brand.getCompanyName()%></td>
        <td><%=brand.getOrdered()%></td>
        <td><%=brand.getDescription()%></td>
        <%
            if(brand.getStatus() == 1){
        %>
                <td><%="启用"%></td>
        <%    }else{
        %>
                <td><%="禁用"%></td>
        <%    }
        %>

        <td><a href="#">修改</a> <a href="#">删除</a></td>
    </tr>
    <%
        }
    %>
</table>
</body>
</html>

效果图:
黑马程序员Javaweb学习笔记03_第11张图片

1.4 JSP缺点

上面代码也可以看出JSP编写代码的弊端,使用for循环或if 时代码阅读也会非常困难
黑马程序员Javaweb学习笔记03_第12张图片
所以代码一般不是全写在jsp中的

由servlet和jsp结合来使用

下面将介绍两种技术来优化编码EL表达式以及JSTL

使用 EL表达式 和 JSTL 标签库来替换 JSP 中的 Java 代码

二、EL表达式

2.1 概述

在servlet中获取数据,可以把数据用键值对的形式存起来用请求转发到jsp中,然后在jsp中用el表达式把数据取出来

黑马程序员Javaweb学习笔记03_第13张图片

2.2 用法展示

在servlet中获取数据,把数据转发到jsp中

代码如下:

package com.web;

import com.pojo.brand;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.annotation.*;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@WebServlet(value = "/ServletDemo1")
public class ServletDemo1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
//        设置假数据 真正的数据需要从数据库获取,这里不一一展示
        List<brand> brands = new ArrayList<brand>();
        brands.add(new brand(1,"三只松鼠","三只松鼠",100,"三只松鼠,好吃不上火",1));
        brands.add(new brand(2,"优衣库","优衣库",200,"优衣库,服适人生",0));
        brands.add(new brand(3,"小米","小米科技有限公司",1000,"为发烧而生",1));

//        可以把这些数据存储到req域【键值对】中,可以使用请求转发到jsp中
        req.setAttribute("bra",brands);

//        请求转发,把数据转发过去
        req.getRequestDispatcher("/el.jsp").forward(req,res);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}

jsp代码如下:

倘若网页数据最后无法显示,在jsp中的page标签加上isELIgnored=“false”,表示不忽略el表达式即可

<%--
  Created by IntelliJ IDEA.
  User: 边牧
  Date: 2023/1/4
  Time: 17:48
  To change this template use File | Settings | File Templates.
--%>

<%@ page isELIgnored="false" contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>$Title$</title>
</head>
<body>

  ${bra}

</body>
</html>

JSP中写入 ${bra} 即可获取req转发来的数据

效果图:
黑马程序员Javaweb学习笔记03_第14张图片

三、JTSL

同样的

学习JSTL 标签库来替换 JSP 中的 Java 代码

黑马程序员Javaweb学习笔记03_第15张图片

3.1 JSTL快速入门-if

黑马程序员Javaweb学习笔记03_第16张图片

这里提供的坐标

<dependency>
    <groupId>jstlgroupId>
    <artifactId>jstlartifactId>
    <version>1.2version>
dependency>
<dependency>
    <groupId>taglibsgroupId>
    <artifactId>standardartifactId>
    <version>1.1.2version>
dependency>

标签库

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 

使用例子:

代码如下
黑马程序员Javaweb学习笔记03_第17张图片
JSP代码如下
黑马程序员Javaweb学习笔记03_第18张图片

效果:
黑马程序员Javaweb学习笔记03_第19张图片


若出现

无法在web.xml或使用此应用程序部署的jar文件中解析绝对uri:[http://java.sun.com/jsp/jstl/core]

参考
链接1
链接2
链接3
链接1,2都不行的话尝试链接3,亲测有效


3.2 JSTL快速入门-foreach

这里由两种用法,第一种用法相当于Java中的增强for循环,第二中相当于普通for循环

参数对应关系如下红线

黑马程序员Javaweb学习笔记03_第20张图片

下面将有代码来作为例子:
将数据发送到jstl2.jsp中

黑马程序员Javaweb学习笔记03_第21张图片

jstl2.jsp的代码如下

注意:brand.brandName中的brandName是调用getBrandName()方法去获取的,跟brand成员变量的名字无关

黑马程序员Javaweb学习笔记03_第22张图片
网页展示:
黑马程序员Javaweb学习笔记03_第23张图片

四、MVC和三层架构

4.1 MVC

黑马程序员Javaweb学习笔记03_第24张图片

4.2 三层架构

黑马程序员Javaweb学习笔记03_第25张图片

4.3 关系

黑马程序员Javaweb学习笔记03_第26张图片

可以将 MVC 模式 理解成是一个大的概念,而 三层架构 是对 MVC 模式 实现架构的思想。 那么我们以后按照要求将不同层的代码写在不同的包下,每一层里功能职责做到单一,将来如果将表现层的技术换掉,而业务逻辑层和数据访问层的代码不需要发生变化。

五、案例

结合上面内容以及利用三层架构模式去完成一个案例

5.1 环境准备

黑马程序员Javaweb学习笔记03_第27张图片
1.导入坐标

<dependencies>
    
    <dependency>
      <groupId>org.mybatisgroupId>
      <artifactId>mybatisartifactId>
      <version>3.5.5version>
    dependency>

    
    <dependency>
      <groupId>mysqlgroupId>
      <artifactId>mysql-connector-javaartifactId>
      <version>5.1.34version>
    dependency>

    
    <dependency>
      <groupId>javax.servletgroupId>
      <artifactId>javax.servlet-apiartifactId>
      <version>3.1.0version>
      <scope>providedscope>
    dependency>

    
    <dependency>
      <groupId>javax.servlet.jspgroupId>
      <artifactId>jsp-apiartifactId>
      <version>2.2version>
      <scope>providedscope>
    dependency>

    
    <dependency>
      <groupId>jstlgroupId>
      <artifactId>jstlartifactId>
      <version>1.2version>
    dependency>
    <dependency>
      <groupId>taglibsgroupId>
      <artifactId>standardartifactId>
      <version>1.1.2version>
    dependency>
  dependencies>

2.配置tomcat

PS:图中web03为知识点,web03_1为案例模块

黑马程序员Javaweb学习笔记03_第28张图片

3.创建包结构

  • mapper 【放brandmapper接口】
  • pojo 【放实体类】
  • service 【放业务类】
  • util 【放工具类,获取连接数据库工厂等】
  • web 【放servlet,充当控制器作用】

黑马程序员Javaweb学习笔记03_第29张图片

4.创建Brand实体类
代码如下

package pojo;

public class Brand {
    int id;
    String name;
    String company;
    int ordered;        //排名
    String des;         //描述
    int status;         //状态

    public Brand() {
    }

    public Brand(int id, String name, String company, int ordered, String des, int status) {
        this.id = id;
        this.name = name;
        this.company = company;
        this.ordered = ordered;
        this.des = des;
        this.status = status;
    }

    public int getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public String getCompany() {
        return company;
    }

    public void setCompany(String company) {
        this.company = company;
    }

    public int getOrdered() {
        return ordered;
    }

    public void setOrdered(int ordered) {
        this.ordered = ordered;
    }

    public String getDes() {
        return des;
    }

    public void setDes(String des) {
        this.des = des;
    }

    public int getStatus() {
        return status;
    }

    public void setStatus(int status) {
        this.status = status;
    }
}

5.创建mybatis核心配置文件,映射文件,创建mapper接口
【数据库建表提前准备好如下】
黑马程序员Javaweb学习笔记03_第30张图片
黑马程序员Javaweb学习笔记03_第31张图片

以上就是所有环境的准备

5.2 功能1-查询所有

效果图以及流程如下:
黑马程序员Javaweb学习笔记03_第32张图片

之前的代码是直接用web层直接调用数据访问层方法,加上业务层是为了提高代码复用性。如果用Servlet实现包含多个Dao层方法的业务,其他Servlet想使用这个业务就得重新写,不如直接调用业务层方法方便。【相当于多个函数封装起来,提高复用性】

1.在brandmapper接口中创建一个方法,查询所有

2.创建工具类

3.在业务层service包中包装调用brandmapper的方法

4.编写前端页面,创建一个名为【查询所有】的链接,链接到servletSelectAll中

5.编写servletSelectAll代码,调用service的方法查询,获取数据后请求转发到all.jsp

6.all.jsp是展示所有的界面

文件结构如下:
黑马程序员Javaweb学习笔记03_第33张图片
最后再提供代码

5.3 功能2-添加

黑马程序员Javaweb学习笔记03_第34张图片
流程

1.在brandmapper中创建add方法,使用注解编写增加代码

@Insert("insert into tb_brand values(null,#{name},#{company},#{ordered},#{des},#{status})")

2.在业务层封装代码

3.创建新增表单的jsp
黑马程序员Javaweb学习笔记03_第35张图片
4.创建ServletAdd,用于处理表单提交的数据,设置表单提交后跳转到"/ServletAdd"中,在ServletAdd中用req.getParameter获取数据

5.在ServletAdd中调用业务层的方法新增数据,并请求转发到servletSelectAll中再次查询所有


5.4 功能3-修改数据

修改数据分两步

第一步修改数据时需要回显数据,方便用户查看原本数据是什么

先根据商品ID查询出数据,而后回显

第二步修改数据的提交

第一步大体流程
黑马程序员Javaweb学习笔记03_第36张图片

  1. 老样子,先在brandMapper接口中创建方法,根据ID查询商品数据,用注解编写SQL语句

  2. 在service业务层中包装方法,获取sqlSession,调用刚刚接口中写的根据ID查询数据的方法,返回的是brand对象

  3. 设置路径,设置我们在点击修改按钮之后跳转的路径,注意路径带上参数值 【商品ID】
    ,跳转到servlet中【此时未创建】
    路径如下图
    黑马程序员Javaweb学习笔记03_第37张图片

  4. 创建servletSelectID类,用req.getParameter(“id”);获取ID,调用业务层封装的根据id查询的方法,存储数据并把数据请求转发到修改界面【此时未创建】

  5. 接下来,我们创建修改数据的界面,这里以update.jsp作为名字,用EL表达式获取上一步转发过来的数据,并展示出来
    注意下面禁用启用的用法
    黑马程序员Javaweb学习笔记03_第38张图片
    6.数据回显完成!


接下来是数据修改

  1. 同样的,在brandMapper中编写SQL代码,修改数据的代码如下
    这里有个坑点是占位符前后要加 ' ' 符号
@Update("update tb_brand set name='${name}',company='${company}',ordered='${ordered}',des='${des}',status='${status}' where id = ${id}")
   void update(Brand brand);
  1. 业务层代码,包装修改数据方法【这里参数是ID,因为需要根据ID修改】,同上面操作大同小异,这里不详细展开

  2. 创建servletUpdate类,用于接收update.jsp提交的数据,并调用业务层的方法修改数据

  3. 修改update.jsp中表单提交路径,提交到servletUpdate中,这里要留意!我们是需要根据id来修改数据的,我们需要设置一个隐藏的【不让用户看见】文本用于提交到servletUpdate,servletUpdate中包装数据时需要取出ID值包装
    黑马程序员Javaweb学习笔记03_第39张图片
    黑马程序员Javaweb学习笔记03_第40张图片

  4. 最后,在servletUpdate带上数据请求转发到servletSelectAll即可~

小提一句

  1. servlet类给前端提供数据是存储在req域中,然后请求转发

  2. 前端页面jsp给后端servlet类提供数据一般是通过表单,或是链接,链接中要拼接上 “?xxx”
    如 ?name = “张三”,然后后端用req去获取数据~


案例文件结构如下
黑马程序员Javaweb学习笔记03_第41张图片

部分代码如下
BrandMapper.java

package com.mapper;

import com.pojo.Brand;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import java.util.List;

public interface BrandMapper {

//    查询所有
    @Select("select * from tb_brand")
    List<Brand> selectAll();

//    添加操作,这里#{}占位符名字要和数据库的一致
    @Insert("insert into tb_brand values(null,#{name},#{company},#{ordered},#{des},#{status})")
    void add(Brand brand);

//    数据回显,根据id获取对应的商品值
    @Select("select * from tb_brand where id = #{id}")
    Brand selectID(int id);

//    数据修改
    @Update("update tb_brand set name='${name}',company='${company}',ordered='${ordered}',des='${des}',status='${status}' where id = ${id}")
    void update(Brand brand);

//    数据删除
    @Delete("delete from tb_brand where id = #{id}")
    void out(int id);
}

Brand.java在上文有
BrandService.java

package com.service;

import com.mapper.BrandMapper;
import com.pojo.Brand;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import package1.util.factory;

import java.util.List;

public class BrandService {
    //        调用brandmapper的方法
    SqlSessionFactory sqlSessionFactory = factory.getSqlSessionFactory();


//                    查询所有
    public List<Brand> selectAll(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
//        获取brandmapper
        BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
//          调用查询的方法
        List<Brand> brands = mapper.selectAll();

        return brands;
    }


//               添加数据
    public void add(Brand b){
        SqlSession sqlSession = sqlSessionFactory.openSession();
//        获取brandmapper
        BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
//        添加
        mapper.add(b);


        sqlSession.commit();
        sqlSession.close();
    }

//               根据id查询
    public Brand update(int id){
        SqlSession sqlSession = sqlSessionFactory.openSession();
//        获取brandmapper
        BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);

//        查询数据,作用,数据回显
        Brand brand = mapper.selectID(id);

        return brand;
    }


    //               修改数据
    public void update2(Brand b){
        SqlSession sqlSession = sqlSessionFactory.openSession();
//        获取brandmapper
        BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
//        修改
        mapper.update(b);

        sqlSession.commit();
        sqlSession.close();
    }

//    根据id删除
    public void delete(int id)
    {
        SqlSession sqlSession = sqlSessionFactory.openSession();
//        获取brandmapper
        BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);

        mapper.out(id);
        sqlSession.commit();
        sqlSession.close();
    }
}

factory.java

package package1.util;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;

public class factory {

    private static SqlSessionFactory sqlSessionFactory;

    static {
        //静态代码块会随着类的加载而自动执行,且只执行一次
        //静态代码块不能抛异常,要用try-catch
        try {
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public static SqlSessionFactory getSqlSessionFactory(){
        return sqlSessionFactory;
    }
}

servletAdd.java

package com.web;

import com.pojo.Brand;
import com.service.BrandService;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.ws.Service;
import java.io.IOException;
import java.util.List;

@WebServlet("/servletAdd")
public class servletAdd extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        String brandName = req.getParameter("brandName");
        String companyName = req.getParameter("companyName");
        String ordered = req.getParameter("ordered");
        String description = req.getParameter("description");
        String status = req.getParameter("status");

        Brand b = new Brand();
        b.setName(brandName);
        b.setCompany(companyName);
        b.setOrdered(Integer.parseInt(ordered));
        b.setDes(description);
        b.setStatus(Integer.parseInt(status));


        BrandService bs = new BrandService();
        bs.add(b);

        req.getRequestDispatcher("/servletSelectAll").forward(req,resp);
    }
    
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}

servletDelete.Java

package com.web;

import com.pojo.Brand;
import com.service.BrandService;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebServlet("/servletDelete")
public class servletDelete extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String id = req.getParameter("id");

        BrandService bs = new BrandService();
        bs.delete(Integer.parseInt(id));

        req.getRequestDispatcher("/servletSelectAll").forward(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doGet(req,resp);
    }
}

剩下代码将会上传到码云中



以上就是第三章的全部内容,感谢观看~~

你可能感兴趣的:(学习,servlet,java,web)