JavaEE-通过浏览器实现数据库的增加和查询
使用的工具
Java
Tomcat8.5
MySQL
Eclipse IDE for Enterprise
注:有的代码块中可能会有包没有导入全的情况, 建议通过eclipse的报错机制添加
工程初始设置
建立Java动态web工程,项目名称为"Demo-Prj-20201010work",程序名称设置为"hairdryerwork"
将用来连接MySQL的JDBC包复制到工程中的WebContent中的WEB-INF中的lib文件夹中
设置相应对象用来存放数据
按照名命规范,建立一个包,包名为"mju.edu.hairdryerwork.domain",包中建立一个类,名为"Hairdryer",用于存储需要的数据
因为当中的数据设置为private,外部无法直接修改和读取数据,因此需要设置get和set函数,方便数据读写
并设置将所有数据格式化输出的函数(转化为字符串), 方便之后数据的返回
/**
*
*/
package mju.edu.hairdryerwork.domain;
/**
* @author XKF
*
*/
public class Hairdryer{
private String hairdryerType;
private int hairdryerPower;
private double hairdryerPrice;
public String getHairdryerType() {
return hairdryerType;
}
public void setHairdryerType(String hairdryerType) {
this.hairdryerType = hairdryerType;
}
public int getHairdryerPower() {
return hairdryerPower;
}
public void setHairdryerPower(int hairdryerPower) {
this.hairdryerPower = hairdryerPower;
}
public double getHairdryerPrice() {
return hairdryerPrice;
}
public void setHairdryerPrice(double hairdryerPrice) {
this.hairdryerPrice = hairdryerPrice;
}
@Override
public String toString() {
return "Hairdryer [hairdryerType=" + hairdryerType + ",\t hairdryerPower=" + hairdryerPower + ",\t hairdryerPrice="
+ hairdryerPrice + "]";
}
}
建立建表所需的.sql文件
在工程中新建文件夹,名称为"docs",在文件夹中新建名称为"db"的sql文件(注:在已经选择新建sql文件选项的情况下,文件后缀名自动添加)
create table tbl_hairdryer(
hairdryer_type varchar(30) primary key;
hairdryer_power int no null;
hairdryer_price decimal(5,1) no null;
);
在cmd打开MySQL目录,使用mysql -u root -p输入密码登录数据库, 输入use 你想要进入的数据库名称例如:use mydb进入数据库后, 将上述sql文件粘贴进cmd中运行,新建表成功后即可输入exit退出
Mysql在win10(64位)上安装:
MySQL安装(Windows10)_qq_46026718的博客-CSDN博客
设置连接数据库工具部分
新建一个包,名称为"mju.edu.hairdryerwork.utils",在该包下新建一个类,名称为"DButils".
设置隐私常量,用于连接数据库时,查找到要连接的数据库,并向数据库提供身份验证信息.
private static final String CONN_STR = "jdbc:mysql://192.168.19.137:3306/mydb?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=UTC";
private static final String USER = "root";
private static final String PWD = "123456";
接下来在该类中新建一个函数用于获取连接对象
先声明一个Connection对象,并将其设为空值(初始化)
通过Class.forName函数加上try/catch对异常进行处理,Class.forName函数中粘贴上一个路径如下图所示:
接下来对conn进行赋值,将连接数据库所需要的常量传入DirverManager.getConnection中,并赋值给conn,用于数据库连接
(此代码需要添加到try块中,在原有的Class.forName语句下面, (逻辑上:检查jdbc包是否存在后才能执行jdbc包中的文件) 添加后eclipse会报错,利用报错机制添加catch即可)
最后返回conn,代码如下:
/**
*
*/
package mju.edu.hairdryerwork.utils;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
/**
* @author XKF
*
*/
public class DButils {
/**
*连接数据库所需要的隐私常量
*/
private static final String CONN_STR = "jdbc:mysql://192.168.19.137:3306/mydb?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=UTC";
private static final String USER = "root";
private static final String PWD = "123456";
/**
* 获取连接部分
* @return
*/
public static Connection getConn() {
Connection conn = null;
try {
Class.forName("com.mysql.cj.jdbc.Driver");
conn = DriverManager.getConnection(CONN_STR, USER, PWD);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return conn;
}
}
开始设置测试类,用于测试程序
建立名称为"mju.edu.hairdryerwork.test"的包,包中添加名称为"Tester"的类,选择自动生成注释,自动生成主函数
并向当中添加用于测试的语句
/**
*
*/
package mju.edu.hairdryerwork.test;
import mju.edu.hairdryerwork.utils.DButils;
/**
* @author XKF
*
*/
public class Tester {
/**
* @param args
*/
public static void main(String[] args) {
System.out.println(DButils.getConn());
}
}
测试成功,如下图所示
向DButils中添加释放资源的函数
public static void releaseRes(Connection conn, PreparedStatement pstmt, ResultSet rset) {
try {
if (rset != null)
rset.close();
if (pstmt != null)
pstmt.close();
if (conn != null)
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
添加上述代码后:
/**
*
*/
package mju.edu.hairdryerwork.utils;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* @author XKF
*
*/
public class DButils {
/**
* 连接数据库所需要的隐私常量
*/
private static final String CONN_STR = "jdbc:mysql://192.168.19.137:3306/mydb?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=UTC";
private static final String USER = "root";
private static final String PWD = "123456";
/**
* 获取连接部分
*
* @return
*/
public static Connection getConn() {
Connection conn = null;
try {
Class.forName("com.mysql.cj.jdbc.Driver");
conn = DriverManager.getConnection(CONN_STR, USER, PWD);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return conn;
}
/**
* 释放资源部分
* @param conn
* @param pstmt
* @param rset
*/
public static void releaseRes(Connection conn, PreparedStatement pstmt, ResultSet rset) {
try {
if (rset != null)
rset.close();
if (pstmt != null)
pstmt.close();
if (conn != null)
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
将文件保存
开始设置程序的增加和查询业务
首先建立名称为"mju.edu.hairdryerwork.dao"的包,之后先在包里新建一个接口,接口中设置需要的函数名
/**
*
*/
package mju.edu.hairdryerwork.dao;
import mju.edu.hairdryerwork.domain.Hairdryer;
/**
* @author XKF
*
*/
public interface HairdryerDao {
void addHdr(Hairdryer hdr);
Hairdryer searchHdr(Hairdryer hdr);
}
保存(不保存的话,在后面重写方法的时候,eclipse会报错)
接下来新建一个类,名称为"HairdryerDaoJDBCImpl",并将接口"HairdryerDao"添加到其中,选择自动添加注释,文件生成之后开始对方法进行重写
设置SQL查询语句,将语句设置为常量, 要填入的值先用?(英文字符)替代
private static final String SQL_ADD_HDR = "insert into tbl_hairdryer values(?,?,?);";
注意:如上代码对常量的赋值应该放在函数外
开始重写增函数
接下来首先利用DButils获得连接声明PreparedStatement变量pstmt用来进行sql语句的操作,pstmt赋值null初始化
最后使用finally进行释放资源,因为此处只是更细数据,没有返回值,因此返回值部分设置为null
public void addHdr(Hairdryer hdr) {
Connection conn = DButils.getConn();
PreparedStatement pstmt = null;
try {
pstmt = conn.prepareStatement(SQL_ADD_HDR);
pstmt.setString(1, hdr.getHairdryerType());
pstmt.setInt(2, hdr.getHairdryertPower());
pstmt.setDouble(3, hdr.getHairdryerPrice());
pstmt.executeUpdate();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
DButils.releaseRes(conn, pstmt, null);
}
}
开始重写查询函数
首先在函数外添加需要使用的sql语句
private static final String SQL_SEARCH_HDR = "select * from tbl_hairdryer"
+ " where `hairdryer_type` = ? and `hairdryer_power` = ? and `hairdryer_price`" + " = ?";
此处通过使用sql语句中的like与%配合来达到输入值为空值时能够继续查询的效果
注:此处语句中属性名称是使用 “`” (键盘tab键往上,英文模式下) 而不是使用单引号括起来, 千万注意,否则在对SQL语句中的"?"赋值时可能出现各种问题
之后在查询函数中同样首先获取连接,之后将存放预处理语句的pstmt进行初始化(赋值为null)
然后将sql语句填入pstmt,将数值传入pstmt
最后进行释放资源
之后代码如下:
public String searchHdr(Hairdryer hdr) {
Connection conn = DButils.getConn();
PreparedStatement pstmt = null;
ResultSet rset = null;
boolean flag = true;
String hdrString = "";
//int i = 0;
try {
pstmt = conn.prepareStatement(SQL_SEARCH_HDR);
if (hdr.getHairdryerType() == null)
pstmt.setString(1, "%");
else
pstmt.setString(1, hdr.getHairdryerType()+"%");
if (hdr.getHairdryerPower() == 0)
pstmt.setString(2, "%");
else
pstmt.setInt(2, hdr.getHairdryerPower());
if (hdr.getHairdryerPrice() == 0)
pstmt.setString(3, "%");
else
pstmt.setDouble(3, hdr.getHairdryerPrice());
rset = pstmt.executeQuery();
while (flag) {
if (rset.next()) {
hdr.setHairdryerType(rset.getString(rset.findColumn("hairdryer_type")));
hdr.setHairdryerPower(rset.getInt(rset.findColumn("hairdryer_power")));
hdr.setHairdryerPrice(rset.getInt(rset.findColumn("hairdryer_price")));
hdrString = hdrString + hdr.toString()+"\n";
} else {
flag = false;
}
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
DButils.releaseRes(conn, pstmt, rset);
}
//return null;
return hdrString;
}
对pstmt(预处理语句)进行初始化后
pstmt.setString(1, "%");可以将字符串"%“填入变量中第1个”?"的位置
对象rset(返回结果)通过
rset = pstmt.executeQuery();赋值后, 查询结果就被存入了rset中
rset.findColumn("hairdryer_type")可以返回指定列名的序号
rset.getInt(index)可以将指定序列号的数据转化为你想要的数据形态
rset.next()会将指针向后移动,
指针移动后, 将会来到查询结果中的下一行数据
再次测试
将主函数中用于之前的代码注释掉
新建一个对象hdr,使用Hairdryer类初始化,并使用该类中的函数对hdr中的变量进行赋值
之后调用Dao包中的类生成对象,调用对象中的增函数和查询函数
/**
*
*/
package mju.edu.hairdryerwork.test;
import mju.edu.hairdryerwork.dao.HairdryerDao;
import mju.edu.hairdryerwork.dao.HairdryerDaoJDBCImpl;
import mju.edu.hairdryerwork.domain.Hairdryer;
/**
* @author XKF
*
*/
public class Tester {
/**
* @param args
*/
public static void main(String[] args) {
//System.out.println(DButils.getConn());
Hairdryer hdr = new Hairdryer();
hdr.setHairdryerType("NKS3-98");
hdr.setHairdryertPower(1200);
hdr.setHairdryerPrice(50);
HairdryerDao hdrDao = new HairdryerDaoJDBCImpl();
hdrDao.addHdr(hdr);
System.out.println(hdrDao.searchHdr(hdr));
}
}
注意:add部分不能使用重复的数据,添加过后建议注释掉
创建网页文件
Insert title here电风吹信息记录
电风吹型号
电风吹功率
电风吹价格
网页当中的表单中的action暂时写为"#", 之后建立servlet之后, 再根据映射地址进行修改
注: 修改时前面加"/“就是使用绝对路径, 不加”/"就是使用相对路径
表单中的input,当type为submit时, 形态为提交按钮, value表示的时返回给后端的值,在servlet中可以用request.getParameter("name")
来获取, 括号中用""包起来的name指的是, 表单中的元素的name, 用于对指定取值目标
添加servlet
按照企业习惯,servlet放在controller包中,因此新建一个包,在包中建立servlet
package mju.edu.hairdryerwork.controller;
import java.io.IOException;
import java.io.PrintWriter;
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 mju.edu.hairdryerwork.domain.Hairdryer;
import mju.edu.hairdryerwork.service.HairdryerService;
import mju.edu.hairdryerwork.service.HairdryerServiceImpl;
/**
* Servlet implementation class HairdryerInfoServlt
*/
@WebServlet("/hdrInfo")
public class HairdryerInfoServlt extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public HairdryerInfoServlt() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
response.getWriter().append("Served at: ").append(request.getContextPath());
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
servlet创建成功后首先打开刚才新建的网页, 将建立servlet时设置好的映射地址,填入html文件中表单中的"#“位置(将”#"替换)
servlet的映射地址在建好的servlet中可以查看
注意:servlet的映射地址一般为"/***"
html中的表单地址前面没有"/“表示相对路径,前面添加”/"表示的是绝对路径,映射地址就不相同,产生404时请查看这两个地址的设置
建立service服务包
servlet一般不直接调用Dao类来对数据库进行增删改查,一般调用service,经由service调用Dao进行增删改查
首先建立一个接口,接口对需要使用的函数的函数名, 需要的形参进行设置
/**
*
*/
package mju.edu.hairdryerwork.service;
import mju.edu.hairdryerwork.domain.Hairdryer;
/**
* @author XKF
*
*/
public interface HairdryerService {
void addHairdryer(Hairdryer hdr);
String searchHairdryer(Hairdryer hdr);
}
之后建立一个类,对接口进行引用, 对函数进行重写, 与Tester中类似,调用Dao进行数据的增查
/**
*
*/
package mju.edu.hairdryerwork.service;
import mju.edu.hairdryerwork.dao.HairdryerDao;
import mju.edu.hairdryerwork.dao.HairdryerDaoJDBCImpl;
import mju.edu.hairdryerwork.domain.Hairdryer;
/**
* @author XKF
*
*/
public class HairdryerServiceImpl implements HairdryerService {
@Override
public void addHairdryer(Hairdryer hdr) {
HairdryerDao hdrDao = new HairdryerDaoJDBCImpl();
hdrDao.addHdr(hdr);
}
@Override
public String searchHairdryer(Hairdryer hdr) {
HairdryerDao hdrDao = new HairdryerDaoJDBCImpl();
String hdrString = hdrDao.searchHdr(hdr);
return hdrString;
}
}
对servlet进行设置
通过request.getPreadParameter函数对表单中的数据进行抓取
注意网页中name和value的设置
函数使用格式为request.getParameter("name")此函数会返回指定元素(name用来指定)的value
package mju.edu.hairdryerwork.controller;
import java.io.IOException;
import java.io.PrintWriter;
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 mju.edu.hairdryerwork.domain.Hairdryer;
import mju.edu.hairdryerwork.service.HairdryerService;
import mju.edu.hairdryerwork.service.HairdryerServiceImpl;
/**
* Servlet implementation class HairdryerInfoServlt
*/
@WebServlet("/hdrInfo")
public class HairdryerInfoServlt extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* @see HttpServlet#HttpServlet()
*/
public HairdryerInfoServlt() {
super();
// TODO Auto-generated constructor stub
}
/**
* @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
//response.getWriter().append("Served at: ").append(request.getContextPath());
request.setCharacterEncoding("utf-8");
Hairdryer hdr = new Hairdryer();
if(request.getParameter("hdrtype")!="")
hdr.setHairdryerType(request.getParameter("hdrtype"));
if(request.getParameter("hdrpower")!="")
hdr.setHairdryerPower(Integer.parseInt(request.getParameter("hdrpower")));
if(request.getParameter("hdrprice")!="")
hdr.setHairdryerPrice(Double.parseDouble(request.getParameter("hdrprice")));
//System.out.println(hdr.getHairdryerType());
//System.out.println(hdr.getHairdryerPower());
//System.out.println(hdr.getHairdryerPrice());
//System.out.println(request.getParameter("test"));
//System.out.println(request.getParameter("add_search"));
//final String UP_STR = "提交信息";
HairdryerService hdrService = new HairdryerServiceImpl();
response.setCharacterEncoding("gbk");
PrintWriter writer = response.getWriter();
writer.flush();
if(request.getParameter("add_search").equals("提交信息")) {
//System.out.println("add");
hdrService.addHairdryer(hdr);
writer.println("信息添加完成");
writer.flush();
writer.close();
}
if(request.getParameter("add_search").equals("查询信息")) {
//System.out.println("search");
writer.println("以下时查询到的相关信息");
writer.println(hdrService.searchHairdryer(hdr));
writer.flush();
writer.close();
}
System.out.println("end!");
}
/**
* @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
doGet(request, response);
}
}
由于网页中传回来的所有数据都是字符串,因此需要通过相应函数转化为其本来的数据类型才能存入数据库或进行查询
但有时会出现部分数据没有填入表单的情况,此时,servlet中将字符串转化为其他形态的函数就会出错, 因此我们设置if,出现这种情况时我们不对其进行赋值(此处不用担心不存入数据在使用sql语句时出错, 因为所有Hairdryer类中的数据已经经过初始化, 例如int型数据默认值一般为0, double默认值一般为0.0)
函数中设置了两个提交按钮,name相同, 但value不相同, 通过对value值的抓取, 以及.equals()(字符串比较函数)的使用, 对value值进行判断, 进而确定应该使用何种服务函数(服务函数中会调用Dao, 一般不在servlet中直接调用Dao)
最后通过输出流将结果返回网页
最终通过在tomcat上运行网页进行测试,完成.