软件开发应具有较高的可维护性,以方便后续的代码维护,而实现高可维护性的有效途径是要实现软件的低耦合、高内聚。软件设计分层的概念主要就是将软件各部分进行解耦合设计,对于JSP动态开发技术而言, JavaBean是最基础的分层技术。Bean是一种软件组件, 在JSP开发中经常用来封装事务逻辑、数据库操作等。本章将介绍JSP中Bean的使用。
java bean的基本概念
在开发软件过程中,应尽量将业务逻辑和表现层分开,从而达到完全解耦,这是软件分层设计的基本理念。在JSP中, 经常利用Java Bean实现核心的业务逻辑, 而JSP页面用于表现层。
JavaBean完全符合Java语言编码规范的要求和特性, 形式上就是纯Java代码, 它是可以重复使用的一个组件。在这种设计模式下, JSP页面只用于接收用户的输入以及显示处理之后的结果,因此不再需要在JSP页面中嵌入大量的Java代码, 不但提高了系统的可维护性, 而且方便工作的分工。
根据Java规范, JavaBean具有以下特性。
- 支持反射机制:利用反射机制可以分析出JavaBean是如何运行的。
- 支持事件:事件是一种简单的通信机制, 利用它可以将相应的信息通知给JavaBean。
- 支持属性:可以自定义属性, 利用标准标签与JSP页面交互数据。
- 支持持久性:持久性是指可以将JavaBean进行保存, 在需要的时候又可以重新载入。
package com.wujialiang;
import java.io.Serializable;
public class User implements Serializable {
private String username;
private String passwd;
private String sex;
private String address;
public User() {
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPasswd() {
return passwd;
}
public void setPasswd(String passwd) {
this.passwd = passwd;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
}
以上就是新建一个Java Bean的基本结构,其要遵循的规范大致如下:
- Java Bean类必须是public类。
- 提供给JSP页面调用的方法,必须赋予public访问权限。
- Java Bean类中的属性,提供给JSP页面调用时必须提供public的get和set方法。
- 必须拥有不带参数的构造方法。
jsp中使用bean
在JSP页面中,要正确使用Bean, 应注意以下3个问题:
- 按照规范定义Bean类, 并给出类属性的相应get和set方法。
- 在页面中要导入相应的Bean类。
- 在JSP页面中利用<jsp:use Bean>标签使用Bean类。
按照规范定义bean类
定义Bean类与定义普通的Java类相同, 如果在IntelliJ IDEA中, 则在包中新增一个类就可以,软件会自动编译。如果是记事本或者其他编辑器, 那么编辑完后需要手动进行编译。Bean类文件有两种部署方法:一种是将Bean的Class文件部署在Web服务器的公共目录中; 另一种是将Bean 的Class文件部署在Web服务器的特定项目的目录中, 即将Bean类的Class文件部署在Web项目的Web-INF文件夹的classes目录内的指定文件夹下, 例如\Web-INF\classes s\com\e shore\pojo\User.class。在实际项目开发中, 后一种情况比较常见。
在页面中要导入相应的Bean类,并用<jsp:useBean>标签获取Bean对象
<jsp:useBean
id="beanInstanceName"
scope="page|request|session|application"
class="package.class"
type="package.class"
beanName="package.class|<%=expression%>"
></jsp:useBean>
属性如下表:
属性值 | 说明 |
---|---|
id | Bean的变量名, 可以在指定的范围中使用该变量名 |
class | Bean的类路径, 必须是严格的package.class,不能指定其父类 |
Scope | Bean的有效范围, 取值有page、request、session、application |
beanName | 实例化的类名称或序列化模板的名称,指定的名称可以为其接口、父类 |
type | 指定其父类或接口的类型, 例如想实例化HashMap,但是type可以填为Map |
在使用<jsp:useBean>标签时需要注意以下几点:
class或beanName不能同时存在,若JavaBean对象已存在, class和beanName属性可以不指定, 只需指定type属性
class可省去type独立使用, 但beanName必须和type一起使用
class指定的类必须包含public、无参数的构造方法
class或beanName指定的类必须包括包名称, 而type可以省去包名, 通过<%@page import=“”%>指定所属包。
class通过new创建JavaBean对象, beanName由java.beans.Beans.instantiate初始化JavaBean对象。
<jsp:useBean>标签中Bean的作用域有4个:page、request、session、application。JSP引擎会根据作用域给用户分配不同的Bean,运行多个用户拥有相同的Bean,每个客户的Bean是相互独立的。
- 当指定的范围为request时, 针对同一用户的不同请求, JSP引擎都会给用户分配不同的Bean对象。当响应结束时, 取消分配的Bean Bean的生命周期就是从客户请求开始到响应结束这段时间。
- 当指定的范围为page时, 针对同一用户访问不同的页面, JSP引擎都会给用户分配不同的Bean对象。当客户进入当前页时, JSP引擎给用户分配一个Bean对象, 当用户离开当前页时, 取消分配的Bean对象。因此, 该Bean的生命周期就位于当前页。
- 当指定的范围为session时, 针对同一用户访问同一Web项目下的不同页面时, JSP引擎都会给用户分配不同的Bean对象。当客户访问Web项目中某一目录下的页面时, JSP引擎给用户分配一个Bean对象, 当用户离开Web目录时, 取消分配的Bean对象, 因此, 该Bean的生命周期是Web项目的一个Session时间。
- 当指定的范围为application时, JSP引擎为访问用户分配同一个Bean对象。它的生命周期就是该Web应用的存在时间, 即Web应用在服务器中存在的时间。
访问bean属性
设置属性
使用标签<jsp:setProperty>可以设置Bean的属性值。其语法形式如下:
<jsp:setProperty name="beanInstanceName"
property="*|propertyName [param='parameterName']|propertyName value='{String|<%=expression%>}'">
</jsp:setProperty>
在使用该标签时, 注意必须使用<jsp:useBean>标签创建一个Bean。<jsp:setProperty>标签的属性说明如表所示。
属性 | 说明 |
---|---|
name | Bean的名字, 用来指定被使用的Bean,它的值必须是<jsp:useBean>标签中的id值 |
property | Bean的属性名, 也就是Bean类中的属性, 将值赋给Bean类的属性 |
param | 表单参数名称 |
value | 要设定的属性值 |
从语法形式中可以看出, 使用<jsp:setProperty>标签有3种方式:
- 使用字符串或者表达式给Bean属性赋值, 其要求是表达式的值与Bean属性的值类型相同。
- 使用表单参数形式给Bean属性赋值, 其要求是表单中提供的参数名字与Bean属性的名字相同。这种形式不用具体指定每个Bean属性的名字, 系统会自动根据表单的参数名字与Bean属性名字进行一一对应。该形式不用value属性, 因此其语法形式为:
<jsp:setProperty property="" name="">
- 使用表单参数值给Bean属性赋值, 其要求是表单中提供的参数名字与<jsp:setProperty>标签中的param属性值名字相同。其语法形式为:
<jsp:setProperty property="Bean类中的属性名" param="表单参数名" name="Bean的变量名">
直接利用表达式设置Bean属性值
<%@page language="java" import="java.util.*" pageEncoding="UTF-8" %>
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>利用表达式设置bean属性</title>
</head>
<body>
<jsp:useBean id="product" class="com.wujialiang.Product" scope="page"></jsp:useBean>
<jsp:setProperty name="product" property="product_id" value="00001"></jsp:setProperty>
<jsp:setProperty name="product" property="product_name" value="Stuts开发教程"></jsp:setProperty>
<%
double price = 68.21;
%>
<jsp:setProperty name="product" property="price" value="<%=price+10.0%>"></jsp:setProperty>
<jsp:setProperty name="product" property="info" value="Stuts开发教程简介。。。"></jsp:setProperty>
<h1>产品信息</h1>
<p>产品编号:<%=product.getProduct_id()%>
</p>
<p>产品名称:<%=product.getProduct_name()%>
</p>
<p>产品价格:<%=product.getPrice()%>
</p>
<p>产品信息:<%=product.getInfo()%>
</p>
</body>
</html>
通过表单参数名设置Bean属性值
<%@page language="java" import="java.util.*,com.wujialiang.Product" pageEncoding="UTF-8" %>
<%
request.setCharacterEncoding("UTF-8");
%>
<jsp:useBean id="product" class="com.wujialiang.Product" scope="page"></jsp:useBean>
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>通过表单参数名设置Bean属性值</title>
</head>
<body>
<form action="" method="post">
<p>
<span>输入产品名称:</span>
<input type="text" name="product_name">
</p>
<p>
<span>输入产品编号:</span>
<input type="text" name="product_id">
</p>
<p>
<span>输入产品价格:</span>
<input type="text" name="price">
</p>
<p>
<span>输入产品信息:</span>
<input type="text" name="info">
</p>
<input type="submit" value="提交">
</form>
<%--设定product属性值--%>
<jsp:setProperty name="product" property="*"/>
<%--展示产品信息--%>
<h1>产品信息</h1>
<p>产品编号:<%=product.getProduct_id()%>
</p>
<p>产品名称:<%=product.getProduct_name()%>
</p>
<p>产品价格:<%=product.getPrice()%>
</p>
<p>产品信息:<%=product.getInfo()%>
</p>
</body>
</html>
取得属性
<%@page language="java" import="java.util.*" pageEncoding="UTF-8" %>
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>获取属性</title>
</head>
<body>
<jsp:useBean id="product" class="com.wujialiang.Product" scope="page"></jsp:useBean>
<jsp:setProperty name="product" property="product_id" value="00001"></jsp:setProperty>
<jsp:setProperty name="product" property="product_name" value="Stuts开发教程"></jsp:setProperty>
<%
double price = 68.21;
%>
<jsp:setProperty name="product" property="price" value="<%=price+10.0%>"></jsp:setProperty>
<jsp:setProperty name="product" property="info" value="Stuts开发教程简介。。。"></jsp:setProperty>
<h1>产品信息</h1>
<p>产品编号:
<jsp:getProperty name="product" property="product_id"/>
</p>
<p>产品名称:
<jsp:getProperty name="product" property="product_name"/>
</p>
<p>产品价格:<jsp:getProperty name="product" property="price"/>
</p>
<p>产品信息:<jsp:getProperty name="product" property="info"/>
</p>
</body>
</html>
Bean的作用域
前面讲过Bean的作用域有4个,分别是page、request、session和application。Bean的作用范围是由标签中的scope属性指定的,默认是page范围,即该Bean在当前页有效。设置为request时,表示该Bean对当前用户的当前请求有效。设置为session时,表示该Bean在当前用户的session范围内有效。设置为application时,表示该Bean对该系统的所有页面有效。scope属性决定了在使用<jsp:useBean>标签时是否要重新创建新的对象。如果某个Bean在其有效的范围内又出现一个id和scope都相同的Bean,那么就可以重用已经被实例化的Bean,而不是重新新建。
request生命周期
新建circle
package com.wujialiang;
import java.io.Serializable;
public class Circle implements Serializable {
private static final long serialVersionUID = 1L;
private double radius = 1.0d;
private double circleArea = 0.0d;
private double circumference = 0.0d;
public double getRadius() {
return radius;
}
public void setRadius(double radius) {
this.radius = radius;
}
public double getCircleArea() {
circleArea = Math.PI * radius * radius;
return circleArea;
}
public void setCircleArea(double circleArea) {
this.circleArea = circleArea;
}
public double getCircumference() {
circumference = Math.PI * 2 * radius;
return circumference;
}
public void setCircumference(double circumference) {
this.circumference = circumference;
}
public Circle() {
}
}
新建index.jsp
<%@page language="java" import="java.util.*" pageEncoding="UTF-8" isELIgnored="false" %>
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>获取属性</title>
</head>
<body>
<jsp:useBean id="circle" class="com.wujialiang.Circle" scope="request"></jsp:useBean>
<%
//获取圆半径如果没有则默认为1
String radius = request.getParameter("radius");
if(radius==null||radius.equals("")){
radius="1";
}
double rad = Double.parseDouble(radius);
circle.setRadius(rad);
%>
<form action="" method="post">
<p>
<label for="radius">请输入圆的半径</label>
<input type="text" id="radius" name="radius">
</p>
<input type="submit" value="提交">
</form>
<h1>Bean信息:<%=circle.toString()%></h1>
<p>
<span>圆的半径为</span>
<jsp:getProperty name="circle" property="radius"/>
</p>
<p>
<span>圆的周长为</span>
<jsp:getProperty name="circle" property="circumference"/>
</p>
<p>
<span>圆的面积为</span>
<jsp:getProperty name="circle" property="circleArea"/>
</p>
</body>
</html>
每次提交请求都不一样
page生命周期
page范围的JavaBean生命周期是最短的,当一个网页由JSP产生并传送到客户端后,属于page范围的JavaBean也被清除。当JSP程序执行完成,并把结果传给客户端后,属于page范围的JavaBean对象就会被清除。
修改index.jsp
<%@page language="java" import="java.util.*" pageEncoding="UTF-8" isELIgnored="false" %>
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>获取属性</title>
</head>
<body>
<jsp:useBean id="circle" class="com.wujialiang.Circle" scope="page"></jsp:useBean>
<h1>Bean信息:<%=circle.toString()%></h1>
<%
circle.setRadius(20);
%>
<p>
<span>圆的半径为</span>
<jsp:getProperty name="circle" property="radius"/>
</p>
<p>
<span>圆的周长为</span>
<jsp:getProperty name="circle" property="circumference"/>
</p>
<p>
<span>圆的面积为</span>
<jsp:getProperty name="circle" property="circleArea"/>
</p>
<a href="<%=request.getContextPath()%>/index.jsp?v=2023001">新页面</a>
</body>
</html>
session生命周期
修改index.jsp
<%@page language="java" import="java.util.*" pageEncoding="UTF-8" isELIgnored="false" %>
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>获取属性</title>
</head>
<body>
<jsp:useBean id="circle" class="com.wujialiang.Circle" scope="session"></jsp:useBean>
<h1>Bean信息:<%=circle.toString()%></h1>
<%
circle.setRadius(20);
%>
<p>
<span>圆的半径为</span>
<jsp:getProperty name="circle" property="radius"/>
</p>
<p>
<span>圆的周长为</span>
<jsp:getProperty name="circle" property="circumference"/>
</p>
<p>
<span>圆的面积为</span>
<jsp:getProperty name="circle" property="circleArea"/>
</p>
<a href="<%=request.getContextPath()%>/index.jsp?v=2023001">新页面</a>
</body>
</html>
无论怎么刷新都是当前的值
跳转新页面也是
重新请求一个页面也是,关闭浏览器重新打开会是新的
application生命周期
修改index.jsp
<%@page language="java" import="java.util.*" pageEncoding="UTF-8" isELIgnored="false" %>
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>获取属性</title>
</head>
<body>
<jsp:useBean id="circle" class="com.wujialiang.Circle" scope="application"></jsp:useBean>
<h1>Bean信息:<%=circle.toString()%></h1>
<%
circle.setRadius(20);
%>
<p>
<span>圆的半径为</span>
<jsp:getProperty name="circle" property="radius"/>
</p>
<p>
<span>圆的周长为</span>
<jsp:getProperty name="circle" property="circumference"/>
</p>
<p>
<span>圆的面积为</span>
<jsp:getProperty name="circle" property="circleArea"/>
</p>
<a href="<%=request.getContextPath()%>/index.jsp?v=2023001">新页面</a>
</body>
</html>
无论怎么刷新关闭浏览器都不会变,除非重启服务器
用户登录验证
在前面的章节中曾经介绍过用户登录验证,本节将介绍利用Java Bean的方式进行登录验证。用户在表单中填入用户名与密码。如果存在用户,就跳转到欢迎界面,否则显示错误信息。
在本程序中Java Bean是极其重要的一部分,不仅要完成数据的校验,还要进行错误信息的显示。本例子为了简单,所有的错误信息均存放在Map容器中。
package com.wujialiang;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
public class User implements Serializable {
private String username = "";
private String passwd = "";
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPasswd() {
return passwd;
}
public void setPasswd(String passwd) {
this.passwd = passwd;
}
Map<String, String> userMap = null;
Map<String, String> errorsMap = null;
public User() {
super();
this.username = "";
this.passwd = "";
userMap = new HashMap<String, String>();
errorsMap = new HashMap<String, String>();
userMap.put("zhangsan", "123456");
userMap.put("lisi", "123456");
userMap.put("wangwu", "123456");
}
public boolean isValidate() {
boolean flag = true;
if (!this.userMap.containsKey(this.username)) {
flag = false;
errorsMap.put("username", "用户不存在");
this.username = "";
}
String password = this.userMap.get(this.username);
if (password == null || !password.equals(this.passwd)) {
flag = false;
errorsMap.put("passwd", "密码错误");
this.passwd = "";
this.username = "";
}
return flag;
}
public String getErrors(String key) {
String errorV = this.errorsMap.get(key);
return errorV == null ? "" : errorV;
}
}
在登录页面index.jsp中引用User类, 并用表单提交的方式设定User属性值。其源代码如下:
<%@page pageEncoding="UTF-8" language="java" import="java.util.*" %>
<jsp:useBean id="user" class="com.wujialiang.User" scope="session"/>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>用户登录</title>
</head>
<body>
<form action="check.jsp" method="post">
<%
if (user.getErrors("username") != null && user.getErrors("username") != "") {
%>
<p>
<span style="color: red;">
<%=user.getErrors("username")%>
</span>
</p>
<%}%>
<%
if (user.getErrors("passwd") != null && user.getErrors("passwd") != "") {
%>
<p>
<span style="color: red;">
<%=user.getErrors("passwd")%>
</span>
</p>
<%}%>
<p>
<input type="text" name="username" id="username">
<jsp:setProperty name="user" property="username"/>
</p>
<p>
<input type="password" name="passwd" id="passwd">
<jsp:setProperty name="user" property="passwd"/>
</p>
<input type="submit" value="提交">
<input type="reset" value="重置">
</form>
</body>
</html>
在检验页面check.jsp中, 同样定义一个范围为session的User, 对调用类的验证方法进行判断,其源代码如下:
<%@ page import="java.util.*" contentType="text/html;charset=UTF-8" language="java" pageEncoding="utf-8" %>
<jsp:useBean id="user" class="com.wujialiang.User" scope="session"/>
<html>
<head>
<title>Title</title>
</head>
<body>
<jsp:setProperty name="user" property="*"/>
<%
if (user.isValidate()) {
%>
<jsp:forward page="success.jsp"></jsp:forward>
<%} else {%>
<jsp:forward page="index.jsp"></jsp:forward>
<%}%>
</body>
</html>
success.jsp页面用于显示欢迎信息, 其源代码如下:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<jsp:useBean id="user" class="com.wujialiang.User" scope="session"/>
<html>
<head>
<title>登录成功</title>
</head>
<body>
<h1>欢迎你:<jsp:getProperty name="user" property="username"/></h1>
</body>
</html>
输入错误密码
DAO设计模式
DAO设计模式简介
信息系统的开发架构如图所示。
对各层级的介绍分别如下。
- 客户层:实际上就是客户端浏览器。
- 显示层:利用JSP和Servlet进行页面显示。
- 业务层:对数据层的原子性DAO操作进行整合。
- 数据层:对数据库进行原子操作,例如增加、删除、修改等。数据库:顾名思义就是保存数据库的信息。
DAO是Data Access Object的简称, 主要是对数据进行操作, 对应上面的层级就是数据层。在数据操作过程中, 主要是以面向接口编程为主。一般将DAO划分为以下几个部分。
- VO(Value Object) :一个用于存放网页的数据, 比如网页要显示一条用户的信息, 则这个类就是用户类, 主要由属性以及属性的setter和getter方法组成, VO类中的成员变量与表中的字段是相对应的。
- Database Connection:用于打开和关闭数据库操作的类。
- DAO接口:用于声明数据库的操作, 定义对数据库的原子性操作, 例如增加、修改、删除等。
- DAO Impl:实现DAO接口的类, 但是不负责数据库的打开和关闭。DAO Proxy:也是实现DAO接口, 主要完成数据库的打开和关闭。
- DAO Factory:工厂类, 通过getInstance() 取得DAO的实例化对象。
DAO命名规则
在开发过程中, 命名规范非常重要。命名必须具有可读性、可维护性。DAO命名规则如下:
- DAO命名为XxxDao, 有的开发人员喜欢在其前加一个Ⅰ表示是接口类, 例如UserDao或者IUserDao。
- DAOImpl命名为XxxDaoImpl, 表示是接口实现类, 例如UserDaoImpl。
- DAOProxy命名为XxxDaoProxy或者XxxService, 例如UserDaoProxy或者UserService。
- DAOFactory命名为XxxFactory, 例如UserDaoFactory。
- VO的命名与表名一致,VO中的属性与表字段一致。
DAO开发
DAO开发是指对数据的增、删、改、查操作。在MySQL中新建一个产品表product,建表脚本如下:
DROP TABLE IF EXISTS product;
CREATE TABLE product(
product_id varchar(20) not null,
product_name varchar(50) default null,
price decimal(6,2),
info varchar(100) default null,
PRIMARY key (product_id)
) ENGINE=INNODB DEFAULT CHARSET=utf8;
新建web项目,然后pom.xml新增依赖
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.wujialiang</groupId>
<artifactId>web05</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>web05 Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-servlet-api</artifactId>
<version>9.0.74</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.32</version>
</dependency>
</dependencies>
<build>
<finalName>web05</finalName>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.3.1</version>
</plugin>
</plugins>
</pluginManagement>
</build>
<properties>
<!-- maven 编译代码使用的jdk版本 -->
<maven.compiler.source>17</maven.compiler.source>
<!-- maven 执行代码使用的jdk版本 -->
<maven.compiler.target>17</maven.compiler.target>
<!-- maven 编译使用的编码 -->
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
<!-- maven 进行项目构建使用的编码,避免中文乱码 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- maven 生成项目报告使用的编码 -->
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
</properties>
</project>
根据上述内容,分别新建Product、ProductDao、ProductDaolmpl、ProductService、DaoFactory、DBConnection。建完的目录结构如下图:
- Product
package com.wujialiang.model;
import java.io.Serializable;
public class Product implements Serializable {
private static final long serialVersionUID=1L;
private String product_id;
private String product_name;
private double price;
private String info;
public Product() {
}
public String getProduct_id() {
return product_id;
}
public void setProduct_id(String product_id) {
this.product_id = product_id;
}
public String getProduct_name() {
return product_name;
}
public void setProduct_name(String product_name) {
this.product_name = product_name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public String getInfo() {
return info;
}
public void setInfo(String info) {
this.info = info;
}
}
- DBConnection
package com.wujialiang.db;
import java.sql.Connection;
import java.sql.DriverManager;
public class DBConnection {
private static final String Driver = "com.mysql.cj.jdbc.Driver";//"com.mysql.jdbc.Driver";
private static final String URL = "jdbc:mysql://localhost:3306/study01";
private static final String USER = "root";
private static final String PASSWORD = "root";
private Connection conn = null;
public DBConnection() throws Exception {
try {
Class.forName(Driver);
this.conn = DriverManager.getConnection(URL, USER, PASSWORD);
} catch (Exception e) {
throw e;
}
}
public Connection getConnection() {
return this.conn;
}
public void close() throws Exception {
if (this.conn != null) {
try {
this.conn.close();
} catch (Exception e) {
throw e;
}
}
}
}
- ProductDao
package com.wujialiang.dao;
import com.wujialiang.model.Product;
import java.util.List;
public interface ProductDao {
/**
*新增产品
* @param product
* @return
* @throws Exception
*/
public boolean addProduct(Product product) throws Exception;
/**
* 铲鲟圈的产品
* @param productName
* @return
* @throws Exception
*/
public List<Product> findAll(String productName) throws Exception;
/**
* 根据id查询产品
* @param product_id
* @return
* @throws Exception
*/
public Product findByProductId(String product_id) throws Exception;
}
- ProductDaoImpl
package com.wujialiang.dao;
import com.wujialiang.model.Product;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
public class ProductDaoImpl implements ProductDao {
private Connection conn = null;
private PreparedStatement pstmt = null;
public ProductDaoImpl(Connection conn) {
this.conn = conn;
}
@Override
public boolean addProduct(Product product) throws Exception {
boolean flag = false;
String sql = "insert into product(product_id,product_name,price,info) values(?,?,?,?)";
this.pstmt = this.conn.prepareStatement(sql);
this.pstmt.setString(1, product.getProduct_id());
this.pstmt.setString(2, product.getProduct_name());
this.pstmt.setDouble(3, product.getPrice());
this.pstmt.setString(4, product.getInfo());
if (this.pstmt.executeUpdate() > 0) {
flag = true;
}
return flag;
}
@Override
public List<Product> findAll(String productName) throws Exception {
List<Product> list = new ArrayList<Product>();
String sql = "select product_id,product_name,price,info from product ";
if (productName != null && !productName.equals("")) {
sql += " where product_name like ?";
this.pstmt = this.conn.prepareStatement(sql);
this.pstmt.setString(1, "%" + productName + "%");
}else{
this.pstmt = this.conn.prepareStatement(sql);
}
ResultSet rs=this.pstmt.executeQuery();
Product product =null;
while (rs.next()){
product = new Product();
product.setProduct_id(rs.getString(1));
product.setProduct_name(rs.getString(2));
product.setPrice(rs.getDouble(3));
product.setInfo(rs.getString(4));
list.add(product);
}
this.pstmt.close();
return list;
}
@Override
public Product findByProductId(String product_id) throws Exception {
String sql = "select product_id,product_name,price,info from product where product_id=?";
this.pstmt = this.conn.prepareStatement(sql);
this.pstmt.setString(1, product_id);
ResultSet rs=this.pstmt.executeQuery();
Product product =null;
if (rs.next()){
product = new Product();
product.setProduct_id(rs.getString(1));
product.setProduct_name(rs.getString(2));
product.setPrice(rs.getDouble(3));
product.setInfo(rs.getString(4));
}
this.pstmt.close();
return product;
}
}
- ProductService
package com.wujialiang.service;
import com.wujialiang.dao.ProductDao;
import com.wujialiang.dao.ProductDaoImpl;
import com.wujialiang.db.DBConnection;
import com.wujialiang.model.Product;
import java.util.List;
public class ProductService implements ProductDao {
private DBConnection dbConnection=null;
private ProductDao dao = null;
public ProductService() throws Exception {
this.dbConnection = new DBConnection();
this.dao = new ProductDaoImpl(this.dbConnection.getConnection());
}
@Override
public boolean addProduct(Product product) throws Exception {
boolean flag =false;
try{
if(this.dao.findByProductId(product.getProduct_id())==null){
flag =this.dao.addProduct(product);
}
}catch (Exception e){
throw e;
}finally {
this.dbConnection.close();
}
return flag;
}
@Override
public List<Product> findAll(String productName) throws Exception {
List<Product> all =null;
try{
all = this.dao.findAll(productName);
}catch (Exception e){
throw e;
}finally {
this.dbConnection.close();
}
return all;
}
@Override
public Product findByProductId(String product_id) throws Exception {
Product product=null;
try{
product = this.dao.findByProductId(product_id);
}catch (Exception e){
throw e;
}finally {
this.dbConnection.close();
}
return product;
}
}
- DAOFactory
package com.wujialiang.factory;
import com.wujialiang.dao.ProductDao;
import com.wujialiang.service.ProductService;
public class DAOFactory {
public static ProductDao getIempDaoInstance() throws Exception {
return new ProductService();
}
}
进行测试TestInsertProduct
package com.wujialiang;
import com.wujialiang.factory.DAOFactory;
import com.wujialiang.model.Product;
public class TestInsertProduct {
public static void main(String[] args) {
Product product = null;
try {
for (int i = 0; i < 5; i++) {
product = new Product();
product.setProduct_id("222222" + i);
product.setPrice(12.01);
product.setProduct_name("杯子_" + i);
product.setInfo("这是一个杯子_" + i);
DAOFactory.getIempDaoInstance().addProduct(product);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
新建index.jsp
<%@ page import="java.util.*" contentType="text/html;charset=UTF-8" language="java" %>
<html>
<body>
<a href="product_add.jsp">添加产品</a>
<a href="product_list.jsp">查询产品</a>
</body>
</html>
新建product_add.jsp
<%@ page import="java.util.*" contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="product_insert.jsp" method="post">
<p>
<label for="product_id">产品编号:</label>
<input id="product_id" type="text" name="product_id">
</p>
<p>
<label for="product_name">产品名称:</label>
<input id="product_name" type="text" name="product_name">
</p>
<p>
<label for="price">产品编号:</label>
<input id="price" type="text" name="price">
</p>
<p>
<label for="info">产品编号:</label>
<input id="info" type="text" name="info">
</p>
<input type="submit" value="提交">
<input type="reset" value="重置">
</form>
</body>
</html>
新建product_insert.jsp
<%@ page import="java.util.*,com.wujialiang.model.Product" contentType="text/html;charset=UTF-8" language="java" %>
<%@ page import="com.wujialiang.factory.DAOFactory" %>
<%
request.setCharacterEncoding("utf-8");
%>
<html>
<head>
<title>执行添加产品</title>
</head>
<body>
<%
Product product = new Product();
product.setProduct_id(request.getParameter("product_id"));
product.setProduct_name(request.getParameter("product_name"));
product.setPrice(Double.parseDouble(request.getParameter("price")));
product.setInfo(request.getParameter("info"));
boolean flag = DAOFactory.getIempDaoInstance().addProduct(product);
if (flag) {
%>
<h4>添加产品信息成功</h4>
<%
} else {
%>
<h4>添加产品信息失败</h4>
<%}%>
</body>
</html>
新建product_list.jsp
<%@ page import="java.util.*,com.wujialiang.model.Product" contentType="text/html;charset=UTF-8" language="java" %>
<%@page import="com.wujialiang.factory.DAOFactory" %>
<%
request.setCharacterEncoding("utf-8");
%>
<html>
<head>
<title>查询商品列表</title>
</head>
<body>
<%
String product_name = request.getParameter("product_name");
List<Product> list = DAOFactory.getIempDaoInstance().findAll(product_name);
%>
<form action="product_list.jsp" method="post">
<label for="product_name">请输入产品名称</label>
<input type="text" name="product_name" id="product_name">
<br>
<input type="submit" value="提交">
</form>
<table>
<tr>
<td>产品编号</td>
<td>产品名称</td>
<td>产品价格</td>
<td>产品信息</td>
</tr>
<%
for (int i = 0; i < list.size(); i++) {
Product p = list.get(i);
%>
<tr>
<td><%=p.getProduct_id()%>
</td>
<td><%=p.getProduct_name()%>
</td>
<td><%=p.getPrice()%>
</td>
<td><%=p.getInfo()%>
</td>
</tr>
<% }%>
</table>
</body>
</html>