一. 认识JavaBean
Bean:翻译是豆子,表示是一个颗粒
在 JavaBean 中,可以将控制逻辑、值、数据库访问和其他对象进行封装,并且其可以被其他应用来调用。实际上,JavaBean 就是一种 Java 的组件技术
JavaBean 支持两种组件:可视化组件和非可视化组件。对于可视化组件,开发人员可 以在运行的结果中看到界面效果;而非可视化组件一般不能观察到,其主要用在服务器端。 JSP 只支持非可视化组件。
二. JavaBean的概述
我们将JSP中登录操作的代码,转移到LoginDao.java;其中LoginDao类就称为JavaBean。
login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>通过数据库登录界面</title>
</head>
<body>
<form action="check.jsp" method="post">
用户名:<input type="text" name="uname"><br/>
密码:<input type="password" name="upwd"><br/>
<input type="submit" value="登录"><br/>
</form>
</body>
</html>
check.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="dao.LoginDao"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>检验数据库是否存在登录用户</title>
</head>
<body>
<%
String name = request.getParameter("uname");
String pwd = request.getParameter("upwd");
LoginDao dao = new LoginDao();
int result = dao.login(name, pwd);
if(result>0){
out.print("登录成功!");
}
else if(result == 0){
out.print("用户名或密码有误!");
}
else{
out.print("系统异常!");
}
%>
</body>
</html>
JavaBean
package dao;
import java.sql.*;
public class LoginDao {
public int login(String name, String pwd) //返回值1:登录成功,0:登录失败(用户名或密码有误),-1:系统异常
{
String URL = "jdbc:mysql://localhost:3306/userdb?serverTimezone=GMT%2B8";
String username = "root";
String password = "root";
Connection con = null;
Statement stmt = null;
ResultSet rs = null;
try {
// 1. 导入驱动,加载具体的驱动类
Class.forName("com.mysql.cj.jdbc.Driver"); //加载具体的驱动类
// 2. 与数据库建立连接(通过DriverManager)
con = DriverManager.getConnection(URL, username, password);
// 3. 发送sql,执行命令(查询)
stmt = con.createStatement();
// String name = request.getParameter("uname");
// String pwd = request.getParameter("upwd");
String sql = "select count(*) from tb_admins where fd_username='"+name+"' and fd_password='"+pwd+"'";
//有这个人返回值就是1,没有返回值就是0
// 4. 执行SQL语句
rs = stmt.executeQuery(sql); //返回值表示查询的结果集
// 5. 处理结果
int count = -1;
if(rs.next()) //表示结果集的第一行
{
count = rs.getInt(1);//返回值就1个,所以只需要拿第一个就行
}
// if(count>0){
// out.println("登录成功");
// }
// else{
// out.println("登录失败");
// }
return count;
}
catch(ClassNotFoundException e)
{
e.printStackTrace();
return -1;
}
catch(SQLException e)
{
e.printStackTrace();
return -1;
}
catch(Exception e)
{
e.printStackTrace();
return -1;
}
finally {
try {
// 6. 关闭连接
if(rs!=null)
rs.close();
if(stmt!=null)
stmt.close();
if(con!=null)
con.close();
}catch(SQLException e) {
e.printStackTrace();
}
}
}
}
1. JavaBean的作用
- 减轻了JSP的复杂度
- 提高代码复用(以后任何地方的登录操作,都可以通过调用LoginDao实现)
2. Javabean的定义
本质就是一个Java类
满足以下2点,就可以称为Javabean
- public修饰的类,public无参构造
- 所有属性(如果有)都是private,并且提供了set/get(如果boolean则get可以替换成is)
3. Javabean分类
从使用层面分类:
从以下来看:使用Javabean可以简化代码(jsp->jsp+java)和提高代码复用(LoginDao.java)
(1). 封装业务逻辑的Javabean(LoginDao.java封装了登录逻辑)
处理逻辑
用于操作一个封装数据的Javabean(注:封装数据的Javabean是表示数据库中表对应的实体类)
可以将JSP中的JDBC代码,封装到Login.java类中(Login.java)
通常将该Java类叫做DAO(Data Access Object/数据访问对象)类,它专门负责对数据库的访问
1. 举例理解
封装业务逻辑的Javabean
package bean;
import java.sql.*;
public class LoginDao {
public int login(String name, String pwd) //返回值1:登录成功,0:登录失败(用户名或密码有误),-1:系统异常
{
String URL = "jdbc:mysql://localhost:3306/userdb?serverTimezone=GMT%2B8";
String username = "root";
String password = "root";
Connection con = null;
Statement stmt = null;
ResultSet rs = null;
try {
// 1. 导入驱动,加载具体的驱动类
Class.forName("com.mysql.cj.jdbc.Driver"); //加载具体的驱动类
// 2. 与数据库建立连接(通过DriverManager)
con = DriverManager.getConnection(URL, username, password);
// 3. 发送sql,执行命令(查询)
stmt = con.createStatement();
// String name = request.getParameter("uname");
// String pwd = request.getParameter("upwd");
String sql = "select count(*) from tb_admins where fd_username='"+name+"' and fd_password='"+pwd+"'";
//有这个人返回值就是1,没有返回值就是0
// 4. 执行SQL语句
rs = stmt.executeQuery(sql); //返回值表示查询的结果集
// 5. 处理结果
int count = -1;
if(rs.next()) //表示结果集的第一行
{
count = rs.getInt(1);//返回值就1个,所以只需要拿第一个就行
}
// if(count>0){
// out.println("登录成功");
// }
// else{
// out.println("登录失败");
// }
return count;
}
catch(ClassNotFoundException e)
{
e.printStackTrace();
return -1;
}
catch(SQLException e)
{
e.printStackTrace();
return -1;
}
catch(Exception e)
{
e.printStackTrace();
return -1;
}
finally {
try {
// 6. 关闭连接
if(rs!=null)
rs.close();
if(stmt!=null)
stmt.close();
if(con!=null)
con.close();
}catch(SQLException e) {
e.printStackTrace();
}
}
}
}
(2). 封装数据的Javabean(实体类)
例如:Student.java Person.java
对应于数据库中的一张表
通常将该类称为VO(Value Object)类,来配合DAO来使用,在DAO中每查询到一条记录就将其封装为Student对象,该Student对象属于VO,最后将所有实例化的VO存放在集合内返回。
package entity;
public class Person { //实体类
private int id;
private String name;
private boolean isChina;
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 boolean isChina() { //boolean类型的属性isXxx()等价于getXxx();
return isChina;
}
public void setChina(boolean isChina) {
this.isChina = isChina;
}
}
当出现了很多的字段,check页面就需要传递很多的字段,太乱不易管理
解决办法:
将需要传递的数据,封装成一个类,封装完成之后只需要传递一个就行(本质:方法传参)
例如:
1. 举例理解
Fd_students login = new Fd_students(uname,upwd); //即用Login对象,封装了2个数据(用户名和密码)
chack.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="bean.LoginDao"%>
<%@ page import="entity.*"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>检验数据库是否存在登录用户</title>
</head>
<body>
<%
String name = request.getParameter("uname");
String pwd = request.getParameter("upwd");
Fd_students login = new Fd_students(name,pwd);
LoginDao dao = new LoginDao();
// int result = dao.login(name, pwd);
int result = dao.login(login);
if(result>0){
out.print("登录成功!");
}
else if(result == 0){
out.print("用户名或密码有误!");
}
else{
out.print("系统异常!");
}
%>
</body>
</html>
封装数据的Javabean
Fd_students.java
对应于数据库中的Fd_students的表
package entity;
public class Fd_students {
private int id;
private String name;
private String pwd;
public Fd_students() { //无参构造
}
public Fd_students(String name, String pwd) {
this.name = name;
this.pwd = pwd;
}
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 getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
}
封装业务逻辑的Javabean
LoginDao.java
package bean;
import java.sql.*;
import entity.Fd_students;
public class LoginDao {
// public int login(String name, String pwd) //返回值1:登录成功,0:登录失败(用户名或密码有误),-1:系统异常
public int login(Fd_students login)
{
String URL = "jdbc:mysql://localhost:3306/userdb?serverTimezone=GMT%2B8";
String username = "root";
String password = "root";
Connection con = null;
Statement stmt = null;
ResultSet rs = null;
try {
// 1. 导入驱动,加载具体的驱动类
Class.forName("com.mysql.cj.jdbc.Driver"); //加载具体的驱动类
// 2. 与数据库建立连接(通过DriverManager)
con = DriverManager.getConnection(URL, username, password);
// 3. 发送sql,执行命令(查询)
stmt = con.createStatement();
// String name = request.getParameter("uname");
// String pwd = request.getParameter("upwd");
String sql = "select count(*) from tb_admins where fd_username='"+login.getName()+"' and fd_password='"+login.getPwd()+"'";
//有这个人返回值就是1,没有返回值就是0
// 4. 执行SQL语句
rs = stmt.executeQuery(sql); //返回值表示查询的结果集
// 5. 处理结果
int count = -1;
if(rs.next()) //表示结果集的第一行
{
count = rs.getInt(1);//返回值就1个,所以只需要拿第一个就行
}
// if(count>0){
// out.println("登录成功");
// }
// else{
// out.println("登录失败");
// }
return count;
}
catch(ClassNotFoundException e)
{
e.printStackTrace();
return -1;
}
catch(SQLException e)
{
e.printStackTrace();
return -1;
}
catch(Exception e)
{
e.printStackTrace();
return -1;
}
finally {
try {
// 6. 关闭连接
if(rs!=null)
rs.close();
if(stmt!=null)
stmt.close();
if(con!=null)
con.close();
}catch(SQLException e) {
e.printStackTrace();
}
}
}
}
三. 解决部分错误的方法
1. 出现的问题
如果jsp出现错误:The import Xxx cannot be resolved …
2. 解决的办法
尝试解决步骤:
(1). a. 可能是JDK、tomcat版本问题
(2). b. 清空各种缓存
清除tomcat缓存
清除项目缓存
清除项目缓存
(3). c. 删除之前的tomcat,重新解压缩,配置tomcat,重启计算机
(4). d. 如果类之前没有包,则将该类加入包中
四. 在JSP中使用JavaBean
1. 定义Javabean
(1). 方法一
直接在 JSP 中实例化 JavaBean
<%
Student student = new Student();
//使用 student
%>
(2). 方法二
使用<jsp:useBean>标签
<jsp:useBean id="idName" class="package.class" scope="page|session|"> </jsp:useBean>
id:指定Javabean对象的名称
class:指定用哪个类来实例化Javabean对象
scope:指定对象的作用范围
等价于:
<jsp:useBean id="student" class="beans.Student"></jsp:useBean>
2. 设置Javabean属性
在定义了Javabean之后,需要在jsp页面中设置Javabean组件的属性,也就是调用setter方法
(1). 方法一:直接编写 Java 代码
<jsp:useBean id="student" class="beans.Student"></jsp:useBean>
<%
student.setStuname("张华");
%>
(2). 方法二:
使用<jsp:setProperty>标签
1. 当属性值来源为字符串
语法:
<jsp:setProperty property="属性名称" name="bean 对象名" value="常量"/>
举例:
<jsp:useBean id="student" class="beans.Student"></jsp:useBean>
<jsp:setProperty property="stuname" name="student" value="张华" />
2. 当值的来源为request参数时
语法:
<jsp:setProperty property="属性名称" name="bean 对象名" param="参数名"/>
3. 获取Javabean属性
(1). 方法一:使用 JSP 表达式或者 JSP 程序段
举例:
<%@ page language="java" import="beans.Student" contentType="text/html; charset=gb2312"%>
<jsp:useBean id="student" class="beans.Student"></jsp:useBean>
<jsp:setProperty property="name" name="student" value="rose" />
<%=student.getStuname()%>
(2). 方法二:使用 jsp:getProperty 动作
语法:
<jsp:getProperty property="属性名称" name="bean 对象名" />
举例:
<jsp:getProperty property="stuname" name="student" />
五. JavaBean的范围
scope属性指定其作用范围
1. page
page 范围表示 JavaBean 对象的作用范围只是在实例化其的页面上,只在当前页面可用,在别的页面中不能被认识
2. request
request 范围表示 JavaBean 实例除了可以在当前页面上可用之外,还可以在通过 forward 方法跳转的目标页面中被认识到
3. session
session 范围表示 JavaBean 对象可以存在 session 中,该对象可以被同一个用户同一次会话的所有页面认识到
4. application
当 scope 的属性值为 application 时,该对象可以被所有用户的所有页面认识到
jsp:useBean 动作所实例化的对象就会保存在服务器的内存空间中,直到服务器关闭,才会被移除。在此期间如果有其他的 JSP 程序需要调用到该 JavaBean,jsp:useBean 动作不会创建新的实例