一、图书管理系统实现的功能介绍
这里我们要实现普通用户和系统管理员的登录、借书还书功能、购买图书功能、展示所有图书的状态(借出、借出时间是否超期、超期后产生的滞纳金的计算等等)。我这里最初实现的是登录和查询功能。
二、数据库表结构的创建
首先,我们需在在数据库中建几张所需要的表,如下图所示。
建好表之后,需要往表里面插入相应的值。这里我就不作具体演示,具体的建表语句和插入数据的语句如下:
CREATE TABLE IF NOT EXISTS tb_book(
book_id INT(11) PRIMARY KEY AUTO_INCREMENT,
book_name VARCHAR(20),
price DOUBLE(15,2),
store INT(11),
des VARCHAR(50),
book_type VARCHAR(20)
)
INSERT INTO tb_library VALUES(1,'高等数学',35.00,20,'大学必修课,很难的','数学'),
(2,'高分子',25.00,30,'反正比高中的分子结构要难','化学'),
(3,'机器人制作',55.00,10,'与科技接轨','科技'),
(4,'走进江苏',29.00,20,'认识江苏','人文'),
(5,'新视野英语',15.00,50,'学习新视野,稳过四六级','英语'),
(6,'喀斯特地貌',16.00,30,'了解自然的地貌','地理');
CREATE TABLE IF NOT EXISTS tb_borrow(
book_id INT(11),
borrow_id INT(11),
borrow_date DATE,
back_date DATE,
delay_money DOUBLE(15,2)
)
CREATE TABLE IF NOT EXISTS tb_user(
user_id INT(11) PRIMARY KEY AUTO_INCREMENT,
user_name VARCHAR(10),
pwd VARCHAR(20),
grade INT(11),
phone VARCHAR(11),
user_type VARCHAR(10)
)
INSERT INTO tb_user VALUES(1,'admin','admin',1,'15269584852','管理员'),
(2,'lily','lily',2,'13215469850','学生'),
(3,'mark','mark',2,'15269847593','学生'),
(4,'green','green',3,'13265987485','学生'),
(5,'black','black',3,'18569598784','学生');
CREATE TABLE IF NOT EXISTS tb_bookType(
type_id INT(11) PRIMARY KEY AUTO_INCREMENT,
type_name VARCHAR(10),
default_date INT(11),
delay_money_per_day DOUBLE(15,2)
)
INSERT INTO tb_booktype VALUES(1,'科技',7,2.50),
(2,'地理',10,1.20),
(3,'人文',7,1.50),
(4,'数学',15,3.00),
(5,'英语',15,3.50),
(6,'化学',10,2.80);
建好表结构以后,接下来就需要进入idea的一些设置
三、idea的环境搭建
idea环境搭建我这里就不多做赘述,可以参考我上一篇的来进行配置。我们直接开始进行代码部分,首先来做一下登录模块。
四、实现登录功能
首先进行dao层的搭建,再此之前,我们可以把实体类都建好,如下图:
实体类里的getter、setter方法,有参无参构造以及tospring方法的重写,全都码一遍。下面再开始dao层的搭建。
在dao层,需要建一个UserDao接口,里面放一个获取用户信息的方法:
public interface UserDao {
User getUserByNameAndPwd(@Param("name") String name,@Param("pwd") String pwd);
}
然后建一个UserDao.xml文件进行配置。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.kgc.kb07.dao.user.UserDao">
<select id="getUserByNameAndPwd" resultType="user">
select * from tb_user where user_name=#{name} and pwd=#{pwd};
</select>
</mapper>
这里面的内容也很简单,直接就写一个查询语句,根据用户名和密码,返回一个user对象,当然这里的user是在mybatis.xml
文件中设置好的别名。
接下来在service层同样建一个UserService接口,里面也只是放一个方法:
public interface UserService {
User login(String user_name,String pwd);
}
下面在service层实现类中,就需要进行具体的需求分析判断了:
public class UserServiceImpl implements UserService {
Logger logger=Logger.getLogger(UserServiceImpl.class);
private SqlSession session;
@Override
public User login(String user_name, String pwd) {
session= MapperConfig.getSession(true);
User user=session.getMapper(UserDao.class).getUserByNameAndPwd(user_name,pwd);
session.close();
if(user==null){
logger.error("查不到该用户!");
return null;
}
return user;
}
}
通过session对象来调用dao层的方法,这里的session对象的获取方法,也是在工具类中设置好的,前一篇都有讲解具体设置步骤。
service层获取到用户对象之后,就要和前端页面进行交互,就需要一个servlet进行连接,首先建一个UserServlet类,
继承一下HttpServlet,重写一下里面的service方法,然后要在web.xml中进行相关配置。
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<servlet>
<servlet-name>userServlet</servlet-name>
<servlet-class>cn.kgc.kb07.servlet.UserServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>userServlet</servlet-name>
<url-pattern>/login.do</url-pattern>
</servlet-mapping>
<servlet>
</web-app>
public class UserServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String user_name=req.getParameter("user_name");
String pwd=req.getParameter("pwd");
UserService service=new UserServiceImpl();
User user=service.login(user_name,pwd);
if(user!=null){
if(user.getUser_type().equals("管理员")){
req.getSession().setAttribute("user",user);
resp.sendRedirect("manage.jsp");
}else if(user.getUser_type().equals("学生")) {
req.getSession().setAttribute("user", user);
resp.sendRedirect("choose.jsp");
}
}else {
req.getSession().setAttribute("msg","用户不存在!");
resp.sendRedirect("index.jsp");
}
}
}
这里的servlet层直接根据页面返回的用户名和密码,通过service层判断是否可以查询的到,如果查询不到,就跳回原界面,进行再次输入;如果查询的到,需要根据用户的类型,学生和管理员分别进入不同页面。
登录页面也很简单,直接使用c标签获取servlet层的返回结果。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>图书馆首页</title>
</head>
<body>
<c:if test="${user==null}">
<c:out value="${msg}"></c:out>
<form action="login.do" method="post">
<p>用户名:<input type="text" name="user_name"></p>
<p>密码:<input type="password" name="pwd"></p>
<p><input type="submit"></p>
</form>
</c:if>
</body>
</html>
这里是用户登录不成功返回的首页,进行继续登录。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>选择页面</title>
</head>
<body>
<p><input type="button" value="购书" onclick="window.location.href='buy.jsp'"></p>
<p><input type="button" value="借书" onclick="window.location.href='borrow.jsp'"></p>
<p><input type="button" value="还书" onclick="window.location.href='back.jsp'"></p>
</body>
</html>
这是学生登录后可以进行的操作,学生可以选择购书、借书、还书操作(此功能暂不实现)。
<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="utf-8" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>管理员页面</title>
</head>
<body>
<c:if test="${lists==null}">
<form action="show.do" method="post">
<p>书名:<input type="text" name="book_name">
用户名:<input type="text" name="user_name">
图书类型:<input type="text" name="book_type">
<input type="submit" value="查询"></p>
</form>
</c:if>
<c:if test="${lists!=null}">
<c:forEach items="${lists}" var="list">
<p>${list.book_id}</p>
</c:forEach>
</c:if>
</body>
<script>
</script>
</html>
这里管理员的页面,可以根据不同属性进行图书的查询(这里是根据图书的名称,借书人的名字,图书的类来查询)。
接下来,我们要对此功能进行实现。
五、图书的查询展示
同样进行相同的操作,在dao层建一个BookDao的接口,里面放一个方法:
public interface BookDao {
List<Book> show(@Param("book_name") String book_name,
@Param("user_name") String user_name,
@Param("book_type") String book_type);
}
再建一个BookDao.xml文件再进行配置:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.kgc.kb07.dao.book.BookDao">
<select id="show" resultType="book">
SELECT b1.*,b2.`borrow_id`,u.user_name //这里为了方便展示,将user_name和borrow_id写做book的属性,所以返回值类型是book就可以
FROM tb_book b1,tb_borrow b2,tb_user u
WHERE b1.`book_id`=b2.`book_id`
AND b2.`borrow_id`=u.`user_id`
<if test="book_name!=null and book_name!=''">
and b1.book_name like concat('%',#{book_name},'%')
</if>
<if test="user_name!=null and user_name!=''">
and u.user_name like concat('%',#{user_name},'%')
</if>
<if test="book_type!=null and book_type!=''">
and b1.book_type like concat('%',#{book_type},'%')
</if>
</select>
</mapper>
这里使用动态Sql实现模糊查询的功能。
同样service层和实现类进行相同的操作:
public interface BookService {
List<Book> showBooks(String book_name,String user_name,String book_type);
}
public class BookServiceImpl implements BookService {
Logger logger=Logger.getLogger(UserServiceImpl.class);
private SqlSession session;
@Override
public List<Book> showBooks(String book_name,String user_name,String book_type) {
session= MapperConfig.getSession(true);
List<Book> lists=session.getMapper(BookDao.class).show(book_name,user_name,book_type);
session.close();
if(lists==null) {
return null;
}
return lists;
}
}
接着就是web.xml和servlet层的配置:
<servlet>
<servlet-name>bookServlet</servlet-name>
<servlet-class>cn.kgc.kb07.servlet.BookServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>bookServlet</servlet-name>
<url-pattern>/show.do</url-pattern>
</servlet-mapping>
public class BookServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
String book_name=req.getParameter("book_name");
String user_name=req.getParameter("user_name");
String book_type=req.getParameter("book_type");
BookService service=new BookServiceImpl();
List<Book>lists =service.showBooks(book_name,user_name,book_type);
if(lists==null){
req.getSession().setAttribute("msg","查不到该书信息");
resp.sendRedirect("error.jsp");
}else {
req.getSession().setAttribute("lists",lists);
req.getSession().setAttribute("book_name",book_name);
req.getSession().setAttribute("user_name",user_name);
req.getSession().setAttribute("book_type",book_type);
resp.sendRedirect("manage.jsp");
}
}
这里面对请求和响应都进行一下字符编码的配置,防止出现中文乱码。
这样获取到lists对象后,就可以在页面进行展示了。
manage.jsp的页面为:
<%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="utf-8" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>管理员页面</title>
</head>
<body>
<c:if test="${lists==null}">
<form action="show.do" method="post">
<p>书名:<input type="text" name="book_name">
用户名:<input type="text" name="user_name">
图书类型:<input type="text" name="book_type">
<input type="submit" value="查询"></p>
</form>
</c:if>
<c:if test="${lists!=null}">
<p>书名:<input type="text" value="${book_name}">
借书人:<input type="text" value="${user_name}">
图书类型:<input type="text" value="${book_type}">
</p>
<table border="1">
<tr>
<th>图书编号</th>
<th>图书名称</th>
<th>图书价格</th>
<th>图书类型</th>
<th>图书库存</th>
<th>图书描述</th>
<th>借书人姓名</th>
</tr>
<c:forEach items="${lists}" var="list">
<tr>
<td>${list.book_id}</td>
<td>${list.book_name}</td>
<td>${list.price}</td>
<td>${list.book_type}</td>
<td>${list.store}</td>
<td>${list.des}</td>
<td>${list.user_name}</td>
</tr>
</c:forEach>
</table>
</c:if>
</body>
<script>
</script>
</html>
同样也是采用c标签的形式获取servlet层传过来的对象,使用c:forEach来循环打印结果。
这里我们使用模糊查询,来显示图书信息:
书名:高 借书人:不填 图书类型:学
直接在Mysql中可以查到的结果是:
可以看到显示两条信息,在页面中,我们实际来看一下效果:
可以看到页面中也是显示两条结果,证明我们的页面代码没有任何问题。
这样我们就简单实现了图书管理系统的登录和查询图书信息。