简易图书管理系统(主要是jsp+servlet的练习):https://blog.csdn.net/Biexiansheng/article/details/70240413
免费提供源码,有偿提供服务,支持项目定制。
自此,基于jsp+servlet开发的用户信息增删该查已经全部写完了,上面的链接是全部的代码,包含增删该查和数据库。
注意点:
1:删除操作使用的是伪删除。即只是不在页面显示了,但是还保存在数据库。
2:分页查询使用的是一个小工具,后面有时间把这些很实用的小工具详细介绍一下。
3:在提交的表单和后台数据交互的时候使用了一个封装好的小工具。后面有时间介绍。
下面先将删除操作的流程过一遍:
1:执行伪删除操作的流程:
1.1:点击删除按钮就是这一句话,提交到system/userinfodelete这个路径的servlet层,注意是doSet()方法。
<d:column href="system/userinfodelete" value="删除" title="删除"
paramId="userId" paramProperty="userId">
</d:column>
1.2:执行到servlet 层之后调用service业务逻辑层伪删除方法。
UserInfoService service=new UserInfoServiceImpl();
//调用业务逻辑层的删除方法
boolean mark=service.deleteUser(user);
1.3:service层(业务逻辑层)调用工具类的公共方法,
(由于修改和插入可以提取公共的方法,这里做的伪删除其实就是修改也可以使用工具类)
int count=DbUtils.addAndUpdate(sql, list.toArray());
1.4:执行工具类之后又返回到service层(业务逻辑层)
return ps.executeUpdate();
1.5:业务逻辑层又返回true或者false,返回到servlet层。
int count=DbUtils.addAndUpdate(sql, list.toArray());
if(count>0){
return true;
}else{
return false;
}
1.6:执行servlet层之后之后转发到user_info.jsp页面,并且提示信息
boolean mark=service.deleteUser(user);
if(mark){
request.setAttribute("info", "用户信息删除成功");
}else{
request.setAttribute("info", "用户信息删除失败");
}
request.getRequestDispatcher("/view/system/userinfo/user_info.jsp").forward(request, response);
1.7:执行到user_info.jsp页面之后又转到system/userinfoselect这个servlet层。
window.location="system/userinfoselect";
1.8:转到servlet层之后又转发到userinfo_list.jsp页面。显示当前删除之后的信息。
request.getRequestDispatcher("/view/system/userinfo/userinfo_list.jsp").forward(request, response);
至此删除信息已经完成了,不过需要注意的是删除操作到了上面1.8这个步奏的时候执行select语句很特殊,需要注意
StringBuffer sql=new StringBuffer("select * from user_info where user_mark!=-1 ");
即做了标识,-1作为伪删除的,所以查询出!=-1的信息,但是数据库里面的信息还是存在的。
下面将重要的代码按照流程写一下:
1:点击删除按钮,即下面此页面的代码。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%
//获取绝对路径路径
String path = request.getContextPath();
String basePath = request.getScheme() + "://"
+ request.getServerName() + ":" + request.getServerPort()
+ path + "/";
%>
<%@ taglib prefix="d" uri="http://displaytag.sf.net"%>
<!DOCTYPE html>
<html>
<head>
<base href="<%=basePath %>" />
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>用户管理-用户查询</title>
<link href="resource/css/bootstrap.min.css" rel="stylesheet" />
<script type="text/javascript" src="resource/js/jquery.min.js"></script>
<script type="text/javascript"
src="resource/js/bootstrap.min.js"></script>
</head>
<body>
<div>
<ul class="breadcrumb" style="margin: 0px;">
<li>系统管理</li>
<li>用户管理</li>
<li>用户查询</li>
</ul>
</div>
<form action="system/userinfoselect" class="form-inline" method="post">
<div class="row alert alert-info" style="margin: 0px; padding: 5px;">
<div class="form-group">
<label>账号:</label>
<input type="text" name="userAccount" value="${user.userAccount }" class="form-control" placeholder="请输入查询账号" />
<label>姓名:</label>
<input type="text" name="userName" value="${user.userName }" class="form-control" placeholder="请输入查询姓名" />
<select class="form-control" name="userMark">
<option value="">全部</option>
<option value="0" ${user.userMark=='0'?'selected':'' }>普通会员</option>
<option value="1" ${user.userMark=='1'?'selected':'' }>管理员</option>
</select>
</div>
<input type="submit" class="btn btn-danger" value="查询"> <a
href="view/system/userinfo/userinfo_add.jsp" class="btn btn-success">添加用户</a>
</div>
<div class="row" style="padding: 15px;">
<d:table name="list" pagesize="5" requestURI="system/userinfoselect" class="table table-hover table-condensed">
<d:column property="userId" title="用户编号"></d:column>
<d:column property="userAccount" title="用户账号"></d:column>
<d:column property="userPw" title="用户密码"></d:column>
<d:column property="userNumber" title="用户学号"></d:column>
<d:column property="userName" title="用户姓名"></d:column>
<d:column property="userAge" title="用户年龄"></d:column>
<d:column property="userSex" title="用户性别"></d:column>
<d:column property="userMark" title="用户标识"></d:column>
<d:column href="system/userinfoupdate" value="修改" title="修改" paramId="userId" paramProperty="userId"></d:column>
<!-- 这里提交到的是相对应的servlet的doSet方法里面 -->
<d:column href="system/userinfodelete" value="删除" title="删除" paramId="userId" paramProperty="userId"></d:column>
<!-- 需要注意的是删除做的是伪删除,数据库里面的信息依旧保存 -->
</d:table>
</div>
</form>
</body>
</html>
2:之后就到了删除的servlet层。
package com.bie.system.servlet; import java.io.IOException; 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 com.bie.po.UserInfo;
import com.bie.system.service.UserInfoService;
import com.bie.system.service.impl.UserInfoServiceImpl;
import com.my.web.servlet.RequestBeanUtils; @WebServlet("/system/userinfodelete")
public class UserInfoDeleteServlet extends HttpServlet{ private static final long serialVersionUID = 1L; @Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//将表单提交的数据封装到javabean中的用户信息表中
UserInfo user=RequestBeanUtils.requestToSimpleBean(request, UserInfo.class);
UserInfoService service=new UserInfoServiceImpl();
//调用业务逻辑层的删除方法
boolean mark=service.deleteUser(user);
if(mark){
request.setAttribute("info", "用户信息删除成功");
}else{
request.setAttribute("info", "用户信息删除失败");
}
request.getRequestDispatcher("/view/system/userinfo/user_info.jsp").forward(request, response);
} }
3:执行删除的servlet层之后调用service层(业务逻辑层)的伪删除方法
package com.bie.system.service.impl; import java.util.ArrayList;
import java.util.List; import com.bie.po.UserInfo;
import com.bie.system.dao.UserInfoDao;
import com.bie.system.dao.impl.UserInfoDaoImpl;
import com.bie.system.service.UserInfoService;
import com.bie.utils.DbUtils;
import com.bie.utils.MarkUtils;
/***
* 1.4:这是业务逻辑层的实现类,实现用户信息的接口
*
* 切忌新手写好service业务逻辑层需要test测试(junit)
* @author biehongli
*
*/
public class UserInfoServiceImpl implements UserInfoService{ private UserInfoDao dao=new UserInfoDaoImpl();
@Override
public boolean insertUser(UserInfo user) {
try{
//System.out.println(user);//测试传来的UserInfo里面是否够存在用户信息
if(user!=null && user.getUserAccount()!=null){
String sql="INSERT INTO user_info(user_account,user_pw,"
+ "user_number,user_name,user_age,user_sex,user_mark)"
+ " VALUES(?,?,?,?,?,?,?)";
List<Object> list=new ArrayList<Object>();
//可以理解位将实体类中get到的信息放到数据库中,因为set设置的信息就是为了查到数据库中
list.add(user.getUserAccount());//将设置好的账号信息保存到集合中
list.add(user.getUserPw());//将设置好的账号信息保存到集合中
list.add(user.getUserNumber());//将设置好的密码信息保存到集合中
list.add(user.getUserName());//将设置好的姓名信息保存到集合中
list.add(user.getUserAge());//将设置好的年龄信息保存到集合中
list.add(user.getUserSex());//将设置好的性别信息保存到集合中
//list.add(user.getUserMark());//将设置好的标识信息保存到集合中
//后台只可以添加管理员
user.setUserMark(MarkUtils.USER_MARK_MANAGER);
//将设置为默认的管理员添加到数据库
list.add(user.getUserMark()); //将封装到集合list中的信息和sql语句传递到DbUtils封装好的 方法中
//这里sql转化位String语句,list转化位数组类型
int count=DbUtils.addAndUpdate(sql.toString(), list.toArray());
//System.out.println(count);//测试返回值是0还是1
if(count>0){
return true;//成功返回true
}else{
return false;//失败返回false
}
}
}catch(Exception e){
e.printStackTrace();
}
return false;
} @Override
public List<UserInfo> selectUser(UserInfo user) {
//使用StringBuffer进行字符串的拼接,不使用String
//StringBuffer sql=new StringBuffer("select * from user_info where 1=1 ");
StringBuffer sql=new StringBuffer("select * from user_info where user_mark!=-1 ");
//设置集合,用户存放用户信息设置值的时候使用
List<Object> list=null;
//判断用户的信息不为空的时候
if(user!=null){
list=new ArrayList<Object>();
//按照账号查询,如果账号不为null且不为空
if(user.getUserAccount()!=null && !user.getUserAccount().equals("")){
sql.append(" and user_account=?");
list.add(user.getUserAccount());
}
//按照姓名查询,如果姓名不为null且不为空
if(user.getUserName()!=null && !user.getUserName().equals("")){
sql.append(" and user_name like ?");
//模糊查询这样拼接字符串
list.add("%"+user.getUserName()+"%");
}
//按照标识查询,如果标识不为null且不为空
if(user.getUserMark()!=null && !user.getUserMark().equals("")){
sql.append(" and user_mark=?");
list.add(user.getUserMark());
}
} sql.append(" order by user_id desc");
//返回的参数,sql语句是字符类型,集合转化为数组类型
return dao.selectUser(sql.toString(), list.toArray());
} @Override
public boolean updateUser(UserInfo user) {
try{
if(user!=null && user.getUserId()!=null){
//更新的sql语句
String sql="UPDATE user_info SET user_account=?,"
+ "user_pw=?,user_number=?,user_name=?,"
+ "user_age=?,user_sex=? WHERE user_id=?";
List<Object> list=new ArrayList<Object>();
//添加到集合中的顺序必须和上面些的字段一致,不然报错
list.add(user.getUserAccount());
list.add(user.getUserPw());
list.add(user.getUserNumber());
list.add(user.getUserName());
list.add(user.getUserAge());
list.add(user.getUserSex());
list.add(user.getUserId()); //添加和修改(伪删除)都可以调用工具类里面公共的方法。
int count=DbUtils.addAndUpdate(sql, list.toArray());
if(count>0){
return true;
}else{
return false;
}
}
}catch(Exception e){
e.printStackTrace();
}
return false;
} @Override
public UserInfo getUser(UserInfo user) {
//判断用户信息和id编号是否为空
if(user!=null && user.getUserId()!=null){
return dao.getUser(user.getUserId());
}
return null;
} @Override
public boolean deleteUser(UserInfo user) {
try{
String sql="update user_info set user_mark=? where user_id=?";
List<Object> list=new ArrayList<Object>();
//直接给user_mark设置为-1,查询的时候加上等于-1的不显示,即在页面就无法显示了
list.add(MarkUtils.USER_MARK_DEL);
list.add(user.getUserId());
int count=DbUtils.addAndUpdate(sql, list.toArray());
if(count>0){
return true;
}else{
return false;
}
}catch(Exception e){
e.printStackTrace();
}
return false;
} }
4:执行service业务逻辑层之后调用工具类
package com.bie.utils; import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ResourceBundle; /***
* 1.1:写DbUtils的工具类
* :utils是工具类,方便以后调用
* 在main方法测试的时候出现一个错误,
* 瞄了一眼立马想到了没有添加mysql的驱动,
* 所以我感觉测试还是很有必要的
* @author biehongli
*
*/
public class DbUtils { private static String drivername;//数据库驱动,为了加载数据库驱动
private static String url;//数据库连接字符串,只要是找到自己的数据库,需要和自己的数据库一致
private static String user;//数据库账号,需要和自己的一致
private static String password;//数据库密码,需要和自己的一致 static{
drivername=ResourceBundle.getBundle("db").getString("drivername");
url=ResourceBundle.getBundle("db").getString("url");
user=ResourceBundle.getBundle("db").getString("user");
password=ResourceBundle.getBundle("db").getString("password");
} /***
* 加载数据库驱动和连接到数据库,我一般是加载和连接的时候分别输出,可以快速找到哪里出错
* @return
* @throws Exception
*/
public static Connection getCon() throws Exception{
Class.forName(drivername);//记载数据库驱动
System.out.println("测试加载数据库驱动");
//连接到数据库
Connection con=DriverManager.getConnection(url, user, password);
System.out.println("测试连接到数据库");
return con;
} /***
* 这个用来判断关闭数据库的方法
* @param con 关闭Connection的连接
* @param ps 关闭PreparedStatement
* @param rs 关闭ResultSet
*/
public static void getClose(Connection con,PreparedStatement ps,ResultSet rs){
//关闭数据库,注意关闭的顺序。养成好习惯
try{
if(rs!=null){
rs.close();
}
if(ps!=null){
ps.close();
}
if(con!=null){
con.close();
}
}catch(Exception e){
e.printStackTrace();
}
} /***
* 添加(插入)和更新(更改)可以提取公共的方法写在工具类中
* 删除一般使用伪删除,这样删除就是更新(更改)操作,
* 所以只有查询(查找)需要写更多的代码
* @param sql 外面传来的sql语句
* @param arr 外面传来的数组类型的,是用户信息封装到集合传递进来
* @return 返回的是一个整形的数据类型
*/
public static int addAndUpdate(String sql,Object[] arr){
Connection con=null;
PreparedStatement ps=null;
try{
con=DbUtils.getCon();//第一步连接数据库
ps=con.prepareStatement(sql);//第二步预编译
//第三步给sql语句中的参数复制
for(int i=0;i<arr.length;i++){
ps.setObject(i+1, arr[i]);
}
//第四步执行sql并且返回。
return ps.executeUpdate();
}catch(Exception e){
e.printStackTrace();
}finally{
//关闭资源,如果没有ResultSet类型的,加上null即可
DbUtils.getClose(con, ps, null);
}
return 0;
}
/*public static void main(String[] args) {
//我一般在写好连接数据库的工具类时先测试一下,避免连接数据库都失败,测试后可注释即可
try {
DbUtils.getCon();
System.out.println("测试连接数据库终极版!!!");
} catch (Exception e) {
e.printStackTrace();
}
}*/
}
5:执行工具类之后返回到service层(业务逻辑层),service层(业务逻辑层)返回到servlet层,删除的servlet层,删除的servlet层到提示信息层,提示信息层到查询的servlet层,查询的servlet层执行service层(业务逻辑层),service层(业务逻辑层)调用用户信息的dao层(数据交互层),dao层返回到service层(业务逻辑层),service层(业务逻辑层)返回到查询的servlet层,servlet层转发到userinfo_list.jsp这个显示用户信息的页面。至此伪删除操作全部完成,希望看到这个博客的明白这个执行的流程,思路明白,代码会写,这样就ok了。
最后将演示的效果展示一下:
打开用户信息的页面:
点击删除之后查看第一行已经消失咯哦:
至此使用jsp+servlet完成用户信息的增删改查已经完结了,希望对大家有所帮助。后面会继续写图书的增删改查,但是图书的增删改查的代码和流程不再叙述,因为只是字段不一致而已,将介绍使用的小工具的具体用法,当写借书的时候再将用户借书的代码分享出来,那么整个合起来就完成了简易的图书管理系统。(每次代码的分享都是在原有基础上不断的增加,所以最后的代码分享肯定比开始的代码分享复杂合完整。)