JSP链接数据库(代码优化及JavaBean初尝)
对之前的那个测试代码进行改进,JSP本身是在JS中嵌套Java代码,但是如果项目比较庞大,代码一多,放在一起就看着很繁杂,并且出错修改的话也很麻烦,那么我们就把Java代码放到.java文件中;
上代码:
首先是jsp文件:
Index.jsp:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="check.jsp" method="post">
<input type="text" name="uname"><br>
<input type="submit" name="提交"><br>
</form>
</body>
</html>
其次是check.jsp文件:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="SQLweb.*" %><!-- 导包 -->
<%@ page import="Entity.*" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
String names=request.getParameter("uname");
// Person person=new Person(names);//实例化一个Person对象
findDao ch=new findDao();
int num=1;
// num=ch.checks(person);//获取到返回的结果值;
num=ch.checks(names);
if(num>0)
{
out.print("查询成功!");
}else if(num==0)
{
out.print("对不起,查无此人!");
}else if(num<0)
{
out.print("系统异常!");
}
out.print(num);//用作查看返回的行号
%>
</body>
</html>
最后在项目目录下的Java Resources下的src下创建java项目
注:对于本次实验,由于是实现查询功能,是对数据库进行动作,那么建议在创建java的时候,对数据库动作的文件名称命名为XxxDao.java;
findDao.java:
package SQLweb;
import java.sql.*;
import Entity.*;
public class findDao {
// public int checks(Person person)
// {
public int checks(String name)
{
String driver = "com.mysql.cj.jdbc.Driver";
String url = "jdbc:mysql://localhost:3306/zxy?&useSSL=false&serverTimezone=UTF-8&useSSL=false&serverTimezone = GMT";
String username = "root";
String password = "zxy170518.";
Connection connection = null;//链接数据库
PreparedStatement pstmt=null;//执行sql语句
// Statement stmt=null;
ResultSet rs=null;//存放结果集(查询使用)
try {
Class.forName(driver);//建立连接mysql
connection=DriverManager.getConnection(url,username,password);
if(!connection.isClosed())
{System.out.print("数据库连接成功!");}//验证是否连接成功
String sql="select * from tb1 where name = ?";
pstmt=connection.prepareStatement(sql);//对sql语句进行预编译
// String names=request.getParameter("uname");//获取到index中的uname,传递方法是post
pstmt.setString(1, name);//对sql语句中的“?”进行定义
// pstmt.setString(1, person.getName());
rs=pstmt.executeQuery();//接收所查询到的结果集
int count=0;//判断是否查询成功的变量
if(rs.next())
{
count=rs.getInt(1);//这里要注意一下,这里只是将count获取到rs结果集里面的下标为1的属性的属性值,这个下标为1的对应我的数据库里面是id,所以并不是统计rs里面有多少个结果
}
return count;
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return -1;//因为有返回值,但是功能代码在try中,所以如果异常,就返回-1即可;
}catch(SQLException e)
{
e.printStackTrace();
return -1;
}finally {
try {
if(rs!=null)
{
rs.close();
}
if(pstmt!=null)
{
pstmt.close();
}
if(connection!=null)
{
connection.close();
}
}catch(SQLException e)
{
e.printStackTrace();
return -1;
}
}
}
}
这样一来,代码的复杂程度就稍微减小了,并且把jsp和java分开,各司其职,也方便自己查看和修改,需要注意的是,在整个过程中,需要注意导包。
同时我自己在做的时候,也重新认识到了ResultSet的定义,之前一直认为在做查询功能的时候,ResultSet实例化的对象存放的结果集,在后面我进行判断的时候是直接对结果集的个数进行判断,就直接导致我第一次做的时候进行故意输入错误用户名的时候,一直返回的是-1,一直以为程序有问题,后来才明白虽然是存放的结果,但是不是直接进行对结果集的个数的操作,而是对每一行结果进行操作,比如存放了三个结果,那么本身的光标从最开始的第一行的上面开始往下移动,每指一行就是对应改行的数据。
但是如果在结果集为空的情况下,我自己做了几次测试,返回值我都不能拿到,按理说应该是为0的,我不知道为什么每次我都拿到的是空的,应该是0。这里就先留一个小问题。
结果:
首先看mysql:
接着看第一次和第二次查询:
1.
2.
再看一下查询失败的:
这里会发现,后面输出了0,但是这个0不是结果集返回到的0,而是我findDao里面返回的count的值,因为count的值本事初始化的时候就是0,由于结果集里面没有东西,返回又为空(但应该是个0,因为i本身getInt返回值就是Int类型),所以在check中的num拿到的实际是count的初始化的值;
//-----------------------------------------------------------------------------------------------------------------------------------------
JavaBean:
JavaBean是一种可重用的Java组件,其本身满足两点:1.public 修饰的类;2.所有的属性都是private 并提供get/set方法;所以JavaBean可以理解为一个Java类;
JavaBean有两大类:
i.封装业务逻辑的JavaBean,诸如例子中的findDao这个类,封装查找逻辑;(处理逻辑)
ii.封装数据的JavaBean,现在进行对数据的封装;(处理数据)
上代码:
同样的,现在项目中新建一个包,分开放;
Person.java:
package Entity;
public class Person //跟数据库的属性一一对应
{
private int id;
private String name;
public Person()
{
}
public Person(String name)
{
this.name=name;
}
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;
}
}
相比之下索要改动的地方:
check:
对于findDao:
把类方法的参数改成Person对象,下面对sql语句的定义改成Person对象.getname()即可;
结果:
同样能够实现;
总结:
只是对之前测试代码的一个小优化而已,通过JavaBean实现对代码的分类存储,各司其职,让代码的复用率更高,如Person类后面如果想使用增删改功能也只需实例对象,然后.方法就行。本次的学习过程中也遇到一些小问题,但都不是大问题,最主要的还是ResultSet的定义,在之后的学习过程中,自己会加深对其的理解和学习。
//----------------------------------------------------------------------------------------------------------------------------------------------
2019.11.2更新:
对于之前这个ResultSet,我这个代码在测试的时候,我自己有个误区,结果集的处理上,有一些欠妥,我的逻辑层在处理返回值的时候,我的判断条件为rs.next(),可想而知,如果rs本身就没有数据,那么这个rs.next()的返回值就是false,那肯定进不去啊,但是我的返回值count又是放在这个判断语句块里面的,所以导致我最后实现查不到某项信息的时候,count的值一直没拿到rs返回来的0,导致我以为为空的时候是返回的空而不是0,总的来说还是对ResultSet对象的定义不够清晰导致的。