引入Dao

1.crm和数据库的结合

我们先前实现的crm项目的数据都是自定义的 而非数据库获取 因此现在我们应该实现crm和数据库的集成

  • ListServlet.java
    • doPost方法中在处理异常的选项中 并没有发现throws方式 而只有try-catch方式 这是因为子类throws的异常必须和父类throws异常一致或者是父类throws异常的子类型异常 显然子类throws异常超出了父类throws异常的范围
    • ResultSet属于资源 需要关闭以释放资源 所以我们需要通过try-with-resources对其自动关闭
    • 我们在写sql语句的时候 尽量写明字段名以代替*
    • 转发操作可以保证attribute的共享 具体是为了在ListServlet和list.jsp之间进行共享 重定向则不然 并且我们的转发操作一定不要忽略forward方法
package com.axihh.servlet;import com.axihh.bean.Customer;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;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;@WebServlet("/list")
public class ListServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 通过变量保存url、用户名、密码String url = "jdbc:mysql://localhost:3306/crm?serverTimezone=UTC";// 由于是新版的驱动包 所以我们需要指定时区String username = "root";String password = "root";try {Class.forName("com.mysql.cj.jdbc.Driver");try (Connection conn = DriverManager.getConnection(url, username, password);// 连接数据库(注意获取Connection对象的时候会抛出异常 处理异常的方式却只有一种 即try-catch 并没有throws方式 很奇怪 这是因为我们的doPost方法是继承自HttpServlet的doPost 而父类的该方法限制了子类throws的对象只能是ServletException/IOException或者他们的子类型异常 而当前获取连接操作所抛出的异常超出了这个范围 所以他不允许你通过throws手段对异常进行处理 只能通过try-catch进行处理)PreparedStatement pstmt = conn.prepareStatement("SELECT id, name, age, height FROM customer");// 创建语句(注意创建语句需要同时传入要执行的sql语句 同时他属于资源 所以也要放置在try-with-resources的()中 sql语句中的*尽量写清楚具体的字段名)ResultSet rs = pstmt.executeQuery())// 执行sql语句 将sql语句的返回值用ResultSet进行保存){// 定义一个集合 用于存放用户beanList<Customer> customers = new ArrayList<>();// 循环遍历数据库中的用户 并且将用户存入集合中while (rs.next()) {// 创建一个bean实例 用于存放当前用户的字段Customer customer = new Customer();Integer id = rs.getInt("id");String name = rs.getString("name");Integer age = rs.getInt("age");Double height = rs.getDouble("height");customer.setId(id);customer.setName(name);customer.setAge(age);customer.setHeight(height);customers.add(customer);}// 将集合存放到attribute中request.setAttribute("customers", customers);// 转发到list.jsp中request.getRequestDispatcher("page/list.jsp").forward(request, response);}}catch (Exception e) {e.printStackTrace();}}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doPost(request, response);}
}
  • list.jsp
<%--Created by IntelliJ IDEA.User: 19938Date: 2024/5/25Time: 9:51To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head><title>Title</title><style>th, td {border: 1px solid red;}</style>
</head>
<body>
<a href="page/add.html">添加</a>
<table><thead><tr><th>id</th><th>姓名</th><th>年龄</th><th>身高</th></tr></thead><tbody><%-- 我们在获取存储在attribute中的customers时 我们应该通过el表达式去获取 具体的格式就是${} 而本质上就是在调用getAttribute --%><c:forEach items="${customers}" var="customer"><tr><%-- 我们以下的el表达式的本质是调用getter获取属性 --%><td>${customer.id}</td><td>${customer.name}</td><td>${customer.age}</td><td>${customer.height}</td></tr></c:forEach></tbody>
</table></body>
</html>
  • add.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<form action="/crm5/save" method="post"><div>姓名 <input type="text" name="name"></div><div>年龄 <input type="text" name="age"></div><div>身高 <input type="text" name="height"></div><div><button>保存</button></div>
</form>
</body>
</html>
  • SaveServlet
package com.axihh.servlet;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;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;@WebServlet("/save")
public class SaveServlet extends HttpServlet {protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 变量保存url username passwordString url = "jdbc:mysql://localhost:3306/crm?serverTimezone=UTC";String username = "root";String password = "root";try{// 注册驱动Class.forName("com.mysql.cj.jdbc.Driver");try(Connection conn = DriverManager.getConnection(url, username, password);PreparedStatement pstmt = conn.prepareStatement("INSERT INTO customer(name, age, height) VALUES (?, ?, ?)")){// 为pstmt设置参数pstmt.setString(1, request.getParameter("name"));pstmt.setInt(2, Integer.parseInt(request.getParameter("age")));pstmt.setDouble(3, Double.parseDouble(request.getParameter("height")));// 执行sql语句int i = pstmt.executeUpdate();// 重定向到指定的页面response.sendRedirect("/crm5/list");}}catch(Exception e) {e.printStackTrace();}}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doPost(request, response);}
}
  • 值得注意的是 有些时候 我们在启动Tomcat以后 会出现资源无法找到的现象 这时候 有可能是某个文件未及时编译打包到out/artifacts目录中(实际上部署到Tomcat上的项目是存放在out/artifacts中的 其中web-inf目录用于存放我们的src文件以及关联的函数库 而其他的一些html、jsp文件则存放在web-inf同目录下) 我们可以将out/artifacts目录下的contextPath文件删除 然后重启Tomcat以重新生成contextPath文件 或者说有更快速的手段 即idea->build->build artifacts->指定的contextPath文件->build/clean

2.项目缺陷

对于上述这个项目 实现至此 仍然存在着许多的问题

  • 数据库访问代码大量重复
    • 解决方法:将数据库访问代码抽取出来 放置在Dao类(即Database Access Object 该类用于专门负责数据库的访问)中 里面内置save、list等提供调用的方法
    • 需要注意的是 我们在进行保存操作的时候 如果某个字段以unique修饰 说明不能重复 我们要对重复添加做出反应 即转发到失败页面 为此 我们可以定义一个error.jsp展示失败信息 反之则执行重定向操作
    • 当然 我们也可以将常量单独抽取到一个Constant类 这边 我们就直接将其放置在dao中
    • CustomerDao
    package com.axihh.dao;import com.axihh.bean.Customer;import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.util.ArrayList;
    import java.util.List;public class CustomerDao {// 定义私有成员private static final String URL = "jdbc:mysql://localhost:3306/crm?serverTimezone=UTC";private static final String USERNAME = "root";private static final String PASSWORD = "root";public boolean save(Customer customer){try {// 注册驱动Class.forName("com.mysql.cj.jdbc.Driver");try(// 连接数据库Connection conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);// 创建语句PreparedStatement pstmt = conn.prepareStatement("INSERT INTO customer(name, age, height) VALUES (?, ?, ?)")) {// 设置参数pstmt.setString(1, customer.getName());pstmt.setInt(2, customer.getAge());pstmt.setDouble(3, customer.getHeight());// 执行sql语句int a = pstmt.executeUpdate();// 如果a的值大于0的话 那么说明dml语句执行成功return a > 0;}}catch(Exception e) {// 打印报错信息e.printStackTrace();// 返回false 表示执行失败return false;}}public List<Customer> list() {try {// 注册驱动Class.forName("com.mysql.cj.jdbc.Driver");try(// 建立连接Connection conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);// 创建语句PreparedStatement pstmt = conn.prepareStatement("SELECT id, name, age, height FROM customer" );// 执行sql语句ResultSet rs = pstmt.executeQuery()) {// 接着将数据库中的用户信息存入到customer bean类中 并且将customer bean类储存到customer集合中List<Customer> customers = new ArrayList<>();while(rs.next()) {Customer customer = new Customer();customer.setId(rs.getInt("id"));customer.setName(rs.getString("name"));customer.setAge(rs.getInt("age"));customer.setHeight(rs.getDouble("height"));customers.add(customer);}// 返回用户信息集合return customers;}} catch(Exception e) {// 打印报错信息e.printStackTrace();// 返回空值return null;}}
    }
    
    • ListServlet
    package com.axihh.servlet;import com.axihh.bean.Customer;
    import com.axihh.dao.CustomerDao;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.awt.*;
    import java.io.IOException;
    import java.sql.*;
    import java.util.ArrayList;
    import java.util.List;@WebServlet("/list")
    public class ListServlet extends HttpServlet {// 定义一个客户数据库访问类对象private final CustomerDao cd = new CustomerDao();protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {List<Customer> customers = cd.list();// 将customers储存到attribute中request.setAttribute("customers", customers);// 转发request.getRequestDispatcher("/page/list.jsp").forward(request, response);}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doPost(request, response);}
    }
    
    • SaveServlet
    package com.axihh.servlet;import com.axihh.bean.Customer;
    import com.axihh.dao.CustomerDao;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;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;@WebServlet("/save")
    public class SaveServlet extends HttpServlet {private final CustomerDao cd = new CustomerDao();protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {// 定义一个Customer bean对象Customer customer = new Customer();customer.setName(request.getParameter("name"));customer.setAge(Integer.parseInt(request.getParameter("age")));customer.setHeight(Double.parseDouble(request.getParameter("height")));if(cd.save(customer)) {// 表明添加成功 执行重定向操作response.sendRedirect("/crm5/list");}else {// 表明添加失败或者出现异常 需要执行转发操作request.setAttribute("error", "添加失败 请重新添加");request.getRequestDispatcher("/page/error.jsp").forward(request, response);}}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {doPost(request, response);}
    }
    
    • list.jsp
    <%--Created by IntelliJ IDEA.User: 19938Date: 2024/5/25Time: 9:51To change this template use File | Settings | File Templates.
    --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
    <html>
    <head><title>Title</title><style>th, td {border: 1px solid red;}</style>
    </head>
    <body>
    <a href="page/add.html">添加</a>
    <table><thead><tr><th>id</th><th>姓名</th><th>年龄</th><th>身高</th></tr></thead><tbody><%-- 我们在获取存储在attribute中的customers时 我们应该通过el表达式去获取 具体的格式就是${} 而本质上就是在调用getAttribute --%><c:forEach items="${customers}" var="customer"><tr><%-- 我们以下的el表达式的本质是调用getter获取属性 --%><td>${customer.id}</td><td>${customer.name}</td><td>${customer.age}</td><td>${customer.height}</td></tr></c:forEach></tbody>
    </table></body>
    </html>
    
    • error.jsp
    <%--Created by IntelliJ IDEA.User: 19938Date: 2024/5/25Time: 17:05To change this template use File | Settings | File Templates.
    --%>
    <%@ page contentType="text/html;charset=UTF-8" language="java" %>
    <html>
    <head><title>Title</title>
    </head>
    <body>
    <h1>${error}</h1>
    </body>
    </html>
    
    • add.html
    <!DOCTYPE html>
    <html lang="en">
    <head><meta charset="UTF-8"><title>Title</title>
    </head>
    <body>
    <form action="/crm5/save" method="post"><div>姓名 <input type="text" name="name"></div><div>年龄 <input type="text" name="age"></div><div>身高 <input type="text" name="height"></div><div><button>保存</button></div>
    </form>
    </body>
    </html>
    
  • 每一次请求都对应着一个Servlet
  • 存在繁杂的异常处理代码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/841498.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【电子元件】TL431 电压基准

TL431(C23892)是一种常用的可调节精密电压基准和电压调节器。它广泛应用于电源管理、精密参考电压和稳压电路等领域。以下是TL431的一些关键特点和使用方法&#xff1a; 关键特点 可调输出电压&#xff1a;TL431的输出电压可以通过外部电阻网络在2.495V到36V范围内调整。精度高…

淘宝x5sec

声明 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01;wx a15018601872 本文章未…

vuedraggable插件 修改元素首次拖拽进入占位样式

vuedraggable是一款适用于vue3 的可拖拽插件。 通过配置ghost-class“ghost” 属性&#xff0c;可以对组件内元素拖拽过程中的占位符进行修改。但是无法根据ghost这一class对元素首次拖拽进组件内的占位元素进行样式修改 解决方法&#xff1a;元素首次拖拽进vuedraggable 中时…

python 面对对象 类 继承

继承 继承就是为了解决两个有大量重复性代码的类&#xff0c;抽象出一个更抽象的类放公共代码&#xff0c;主要是代码复用&#xff0c;方便代码的管理与修改 类的继承包括属性和方法&#xff0c;私有属性也可继承 class Person(): # 默认是继承object超类pass…

【数据结构(邓俊辉)学习笔记】二叉树03——重构

0 .概述 介绍下二叉树重构 1. 遍历序列 任何一棵二叉树我们都可以导出先序、中序、后序遍历序列。这三个序列的长度相同&#xff0c;他们都是由树中的所有节点依照相应的遍历策略所确定的次序&#xff0c;依次排列而成。 若已知某棵树的遍历序列是否可以忠实地还原出这棵树…

ic基础|时钟篇05:芯片中buffer到底是干嘛的?一文带你了解buffer的作用

大家好&#xff0c;我是数字小熊饼干&#xff0c;一个练习时长两年半的ic打工人。我在两年前通过自学跨行社招加入了IC行业。现在我打算将这两年的工作经验和当初面试时最常问的一些问题进行总结&#xff0c;并通过汇总成文章的形式进行输出&#xff0c;相信无论你是在职的还是…

图片AI高效生成惊艳之作,一键解锁无限创意,轻松打造概念艺术新纪元!

在数字化时代&#xff0c;图片已经成为我们表达创意、传递信息的重要载体。然而&#xff0c;传统的图片生成方式往往耗时耗力&#xff0c;无法满足我们对于高效、创意的需求。幸运的是&#xff0c;现在有了图片AI&#xff0c;它以其高效、智能的特点&#xff0c;为我们带来了全…

微服务-系统架构

微服务&#xff1a; 系统架构的演变 单一应用架构 早期的互联网应用架构&#xff0c;大量应用服务 功能 集中在一个包里&#xff0c;把大量的应用打包为一个jar包&#xff0c;部署在一台服务器&#xff0c;例如tomcat上部署Javaweb项目 缺点:耦合度高&#xff0c;一台服务器…

一千题,No.0014(素数对猜想)

让我们定义dn​为&#xff1a;dn​pn1​−pn​&#xff0c;其中pi​是第i个素数。显然有d1​1&#xff0c;且对于n>1有dn​是偶数。“素数对猜想”认为“存在无穷多对相邻且差为2的素数”。 现给定任意正整数N(<105)&#xff0c;请计算不超过N的满足猜想的素数对的个数。…

分布式缓存:探讨如何在Java中使用分布式缓存解决方案,比如Redis或Hazelcast等

分布式缓存简介 分布式缓存是一种数据管理策略,它可以帮助我们更有效地使用网络中多台服务器的存储资源,从而提高数据获取的速度。我们可以把数据(如数据库查询结果、计算结果等)存储在这种缓存中,从而提供更快的数据访问速度,减少对原始数据源的访问并降低网络负载。 …

Point-Nerf 理论笔记和理解

文章目录 什么是point nerf 和Nerf 有什么区别Point Nerf 核心结构有哪些&#xff1f;什么是point-based radiance field? 点云位置以及置信度是怎么来Point pruning 和 Point Growing 什么是point nerf 和Nerf 有什么区别 基本的nerf 是通过过拟合MLP来完成任意视角场景的重…

缓存穿透、击穿、雪崩的解决方法

一、缓存穿透指的是查询一个不存在的数据&#xff0c;由于缓存中没有对应的值&#xff0c;每次请求都要查询数据库&#xff0c;容易导致数据库压力过大。 解决方法&#xff1a; 使用布隆过滤器等手段可以在请求到达后台处理之前就过滤掉这些不存在的请求&#xff0c;避免了对数…

gazebo中通过编写插件发布随动关节的角度值到话题

1. cpp 编写 #include <gazebo/gazebo.hh> #include <gazebo/physics/physics.hh> #include <gazebo/common/common.hh> #include <ros/ros.h> #include <std_msgs/Float64.h>namespace gazebo {class PoleJointAnglePublisher : public ModelP…

KAFKA消费者-进阶用法

Apache Kafka 是一个分布式流处理平台&#xff0c;用于构建实时流数据管道和应用程序。在 Kafka 中&#xff0c;消费者&#xff08;Consumer&#xff09;用于从 Kafka 主题&#xff08;Topic&#xff09;中读取消息并进行处理。本文将介绍 Kafka 消费者的进阶用法&#xff0c;包…

Linux(六)

Linux&#xff08;六&#xff09; 自定义头文件自定义头文件中写什么如何引入头文件条件编译条件编译作用 gcc工作原理Make 工作管理器什么是Make什么是Makefile/makefileMakefile假目标Makefile中的变量自定义变量预定义变量自动变量 Makefile中变量展开方式递归展开方式简单展…

正运动机器视觉运动控制一体机应用例程

机器视觉运动控制一体机应用例程-多目标形状匹配-正运动技术 (zmotion.com.cn) 机器视觉运动控制一体机应用例程&#xff08;二&#xff09; 颜色识别-正运动技术 (zmotion.com.cn) 机器视觉运动控制一体机应用例程&#xff08;三&#xff09; 基于BLOB分析的多圆定位-正运动…

2024攻防演练利器之必修高危漏洞合集

随着网络安全的发展和攻防演练工作的推进&#xff0c;红蓝双方的技术水平皆在实践中得到了很大的提升&#xff0c;但是数字化快速发展也导致了企业的影子资产增多&#xff0c;企业很多老旧系统依旧存在历史漏洞&#xff0c;与此同时&#xff0c;在攻防演练期间&#xff0c;往往…

TalkingData 数据统计详解

一、引言 在现代数据驱动的商业环境中&#xff0c;准确、及时的数据统计与分析对于企业的决策具有至关重要的作用。TalkingData 是中国领先的独立第三方数据智能服务平台&#xff0c;专注于提供专业的数据统计和分析解决方案。本文将详细介绍 TalkingData 的基本概念、主要功能…

利用EAS自动生成数据模型和sql脚本

EAS适用于敏捷开发中小系统,这节主要讲解EAS对应的模型和数据库脚本输出应用。 在这个应用程序中,用户可自定义实体模型和枚举模型,只要选择相应的实体或者枚举进行右击添加即可。 解决方案参数设定,在解决方案的设定中可设置项目名称、通用语言,命名空间和输出位置。 连…

C语言系列文章 | 函数 (共 10209 字)

目前主要分为三个专栏&#xff0c;后续还会添加&#xff1a; 专栏如下&#xff1a; C语言刷题解析 C语言系列文章 我的成长经历 感谢阅读&#xff01; 初来乍到&#xff0c;如有错误请指出&#xff0c;感谢&#xff01; 目录 函数的概念库函数自…