书店管理系统(Servlet+MySQL)
这个工程主要是对之前的一些总结吧,尽可能地用上所学的所有功能来实现,具体代码稍后也会上传到Github上。
在前端上并没有用上CSS等技术,只用上了基础的HTML和部分JavaScript,这是因为这一篇文章注重于功能的具体实现而不是美观。在美观方面,我更倾向于在完成所有的工作之后,再一点点优化。而且我对于CSS的了解也不是很深,就不在这里献丑了。
这个小练习应用的主要技术是Servlet,当然还有与Servlet紧密结合,密不可分的JSP,MySQL只涉及最基础的语法和应用,而且为了方便操作,我主要是使用DBeaver客户端对MySQL进行操作,这样的操作大大提升了效率,而且更为直观。
其他工具是EclipseEE(2021.9)+JDK14+Tomcat9.0。Tomcat10.0以后的版本变化太大,和我从图书馆借来的教材区别过多,所以没有采用最新的技术。
总体上是跟着教材<电子工业出版社>出版的《JavaWeb程序设计》的设计思路,这本书的作者是张磊和丁香乾老师。这本教材给我的感受颇深,尤其要感谢这两位老师。
1.数据库设计
建立一个数据库bookshop,数据库中实现两个表,表中的数据分别如下
表1:主要用于实现用户的登录和注册(名字主键)
表2:实现图书的信息输入,是系统的主体部分,主要实现图书的展示,线上的下单,还有后台的处理.
2.先实现数据库连接,JDBC的基石,DAO类
"D:\Friedrich Hsing’s Documents\JDBC配置文件\数据库操作类(实现).txt"
我把这个文件的代码复制了一份,放置在这个地址下,方便之后取用。
数据库相关的代码放置在包com.db中。包括DAO,UserDao及其BookDao
主要实现四个方法
这些方法的具体运行原理并不重要,重要的是应用并根据这个文件写出个性化配置的数据库连接类
-
public Connection getConn(String server, String dbname, String user, String pwd)
这个方法实现数据库和程序之间的关系
这些参数的内容都将在web.xml文件中进行声明,
key value在JDBC类中通过
ServletContext ctx=this.getServletContext(); String value=ctx.getInitParameter("key");
这两句代码实现,实现将这些信息传递到JDBC类的代码中。
-
public int executeUpdate(String prepareSql, String[] param)
实现数据的删改增操作,其中prepareSql指的是SQL语法,param数组指的是替换掉SQL语句中的“?”字符
返回一个int数据,executeUpdate 的返回值是一个整数,指示受影响的行数。
一般返回数字>0时,我们默认为操作成功
-
public ResultSet executeQuery(String preparedSql, String[] param)
实现数据的查询,返回这个数据库查询中的结果。
-
public void closeAll()
资源释放
至此,完成了数据库连接类,下面开始进行第一个功能的实现
3.注册与登录功能实现
第一步,实现对象封装:User类
主要参数:对应数据库userdetail的属性一一对应,再实现getting方法和setting方法。
第二步,实现数据库连接类个性化配置,UserDao类
UserDao类实现对DAO类的继承extends。在这个基础上,先构思一下UserDao具体操作的流程和功能。
注意所有操作的逻辑归根两个:删改增+查找
- 添加新用户
- 通过名字查找用户所有信息
- 通过确认名字删除用户
- 更改已注册用户信息
- 获得所有用户数据
注意:所有的方法都要记得最后实现closeAll
资源关闭,推荐使用try-catch-finally
结构最后实现closeAll
实现功能1:添加新用户
对应方法:public boolean AddUser(User user)
SQL指令:INSERT INTO userdetail(username,userpass,role,regtime)values(?,?,?,?)
具体步骤:this.executeUpdate(sql, new String[] {user.getUsername(), user.getUserpass(),""+ user.getRole(), user.getRegtime()});
前面的sql代表SQL指令,后面的数组将具体的值(value)取代前面的“?”字符实现机器识别的SQL指令。然后连接数据库实现具体功能。
注意:String与String数据之间用“,”隔开,但是int数据前需要添加""+
结构才可以被识别
实现功能2:查找用户
对应方法:public User getUserByName(String name)
SQL指令:SELECT * FROM userdetail WHERE username=?
具体步骤:ResultSet rs=this.executeQuery(sql, new String[] {name});
rs是Java中的通用结果集,需要通过方法getString或者getInt
转换成通用数据结构,再将这些数据进行封装,得到一个User对象user
要点:数据类型转化+数据封装
最后将这个user返回。
实现功能3:删除用户
原理基本和新增一样,就是SQL指令要修改一下
对应方法:public boolean delUser(String name)
SQL指令:DELETE FROM userdetail WHERE username=?
具体步骤:this.executeUpdate(sql, new String[] {name});
实现功能4:修改用户信息
(通过名字先获得用户初始信息)
对应方法:public boolean editUser(User user)
对应指令:UPDATE userdetail SET userpass=?,role=?,regtime=?,lognum=?WHERE username=?
具体步骤:this.executeUpdate(sql, new String[] {user.getUsername(), user.getUserpass(), ""+user.getRole(),user.getRegtime()});
注意:这里的”?“与param数组的参数不是一一对应的了,而是存在一定的顺序。名字(获取信息的来源)是放在第一位的
由于总体上的设计,我认为通过姓名实现对用户的查找是比较科学的(其实还可以通过ID账号,但是这只是个联系,实验的范围原则上不会太大),所以再数据库的设计上,我就实现了设置名字为表主键操作逻辑。
返回所有用户的操作逻辑和后面书籍操作一致,所以一并放在后面写。
那现在,第一个功能的数据库设置基本告一段落,现在马上进行Servlet的编写和配置
第三步,在Servlet之前,先写一个拦截器,实现一些基础设置
这个系统中有很多的Servlet文件,所以写一个拦截器实现一些重叠的功能。典型的就是设置response和request的字符类型为UTF-8的操作。这样的操作基本上每一个Servlet文件都需要应用到,一个一个的写效率太过低下,所以统一写一个拦截器效果比较好。
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// TODO Auto-generated method stub
// place your code here
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html; charset=utf-8");
// pass the request along the filter chain
chain.doFilter(request, response)