图书管理系统
1.系统功能性需求描述
图书借阅管理系统是典型的信息管理系统,其开发主要包括后台数据库的建立和维护以及前端应用程序的开发两个方面。对于前者要求建立起数据一致性和完整性强、数据安全性好的数据库。而对于后者则要求应用程序功能完备,易使用等特点。
我们应当对数据库的开发进行全面的了解和认识,知道什么是开发数据库、开发体系、步骤及结构等。只有知道了这些,我们才能把信息管理融入到图书管理中去。开发数据库应用系统是为了给用户建立一个可以长期供给其需求的产品。开发的基本过程为:知道用户们的需求,转化为相应的数据库设计。设计出实际有效的数据库。
2.设计概述
图书管理系统实施后,能够达到以下目标:
界面设计简洁,友好
信息分类清晰,准确
提高较好的查询能力
支持图书馆工作人员对图书借阅、续借和归还等过程
提供图书借阅排行榜
3.系统详细需求分析
3.1系统总设计需求
实现以下功能:
1)对图书进行管理
2)对借阅者信息管理
3)对借阅归还管理
4)管理员登入管理
5)借阅查询
总体架构图:
3.2系统功能需求
1)系统设置模块
其中:
a)图书馆信息模块:对图书馆的相应信息(图书馆名称,地址,建馆时间,负责人信息,联系方式等)进行设置模块。
b)管理员设置模块: 添加,删除,修改管理员的账户信息及权限等功能。
c)参数设置(可选): 对一些可能发生变化的系统级业务数据进行设置,如借阅卡的办理费用,借阅有效期等系统级数据
d)书架设置:添加,修改或删除书架信息。
2)对图书进行管理
其中:
a)图书类型管理: 添加,删除,修改图书类型,如添加少儿图书 等
b)图书信息管理: 添加,修改图书信息.
3)对借阅者信息管理
其中:
a)读者类型管理: 对读者的类型进行维护和管理,如添加,删除读者类型,并设置相应的每次可借阅数量。
b)读者信息管理: 对读者信息进行管理,如添加或修改读者信息,如修改该读者的类型,对于该模块最好提供相应的属性(如加入时间,读者类型等)的排序功能。
4)对借阅归还管理
其中:
图书借阅: 根据用户的借阅卡号,进行图书的借阅,具体如下图:
5)借阅查询
其中:
a)图书信息查询: 提供图书的各种属性的模糊查询
b)借阅信息查询:提供对借阅的各种属性(主要为图书的ISBN, 借阅卡号,用户姓名等)的模糊查询。
4.系统详细设计
4.1系统设计
使用Spring+SpingMVC+Mybatis框架实现。
总体的目录:
导入的包(有些不一定需要):
配置文件:
数据库连接配置文件:db.properties
dataSource.driverClass=com.mysql.jdbc.Driver
dataSource.jdbcUrl=jdbc\:mysql\://127.0.0.1\:3306/db_librarysys?characterEncoding\=utf-8
dataSource.user=root
dataSource.password=
dataSource.maxPoolSize=20
dataSource.maxIdleTime=1000
dataSource.minPoolSize=6
dataSource.initialPoolSize=5
SpringMVC配置:springmvc-config.xml
<!-- 自动扫描该包,SpringMVC会将包下用了@controller注解的类注册为Spring的controller -->
<context:component-scan base-package="com.wyq.Controller" />
<!-- 设置默认配置方案 -->
<!-- <mvc:annotation-driven /> -->
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter" />
<bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" />
</mvc:message-converters>
</mvc:annotation-driven>
<!-- 使用默认的Servlet来响应静态文件比如css、html、js等文件 -->
<mvc:default-servlet-handler />
<!-- 视图解析器 -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 前缀 -->
<property name="prefix">
<value>/WEB-INF/pages/</value>
</property>
<!-- 后缀 -->
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
Spring配置文件,bean注入与mybatis配置:applicationContext.xml
<!-- mybatis:scan会将org.fkit.mapper包里的所有接口当作mapper配置,之后可以自动引入mapper类-->
<mybatis:scan base-package="com.wyq.Mapper" />
<!-- 扫描org.fkit包下面的java文件,有Spring的相关注解的类,则把这些类注册为Spring的bean -->
<context:component-scan base-package="com.wyq" />
<!-- 使用PropertyOverrideConfigurer后处理器加载数据源参数 -->
<context:property-override location="classpath:db.properties"/>
<!-- 配置c3p0数据源 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"/>
<!-- 配置SqlSessionFactory,org.mybatis.spring.SqlSessionFactoryBean是Mybatis社区开发用于整合Spring的bean -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"
p:dataSource-ref="dataSource"/>
<!-- JDBC事务管理器 -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
p:dataSource-ref="dataSource"/>
<!-- 启用支持annotation注解方式事务管理 -->
<tx:annotation-driven transaction-manager="transactionManager" />
配置文件,加载spring的配置文件和字符过滤:Web.xml
<!-- 配置spring核心监听器,默认会以 /WEB-INF/applicationContext.xml作为配置文件 -->
<listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- contextConfigLocation参数用来指定Spring的配置文件 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext*.xml</param-value>
</context-param>
<!-- 定义Spring MVC的前端控制器 -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/springmvc-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- 让Spring MVC的前端控制器拦截所有请求 -->
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!-- 编码过滤器 -->
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
4.2系统前台界面设计
前端的数据获取:
Jsp通过ajax和a便签请求,使用springmvc的controller注释处理请求。通过spring框架的
org.springframework.web.servlet.DispatcherServlet将controller转 化成servlet,将数据返回到前端显示。
前端的显示:
使用bootstrop框架。
4.3系统后台业务设计
使用springmvc的service注释,操作数据库接口,查询数据,并且根据需求对数据进行简单处理,返回给controller。
4.4系统后台数据设计
使用mapper注释,即对数据库连接,查询,返回对应的bean。使用的都是自动注释,有@select,@insert,@update,@delete。
例子:(登入模块)
Mapper:
public interface WLoginMapper {
@Select("SELECT * FROM tb_manager WHERE name=#{name} and PWD=#{pwd}")
public Manager loginAdmin(@Param("name")String name,
@Param("pwd")String pwd);
@Select("SELECT * FROM tb_reader WHERE barcode=#{barcode} and pwd=#{pwd}")
public Reader loginUser(@Param("barcode")String barcode,
@Param("pwd")String pwd);
}
Service:
接口:
package com.wyq.Service;
public interface WLoginService {
public Manager loginAdmin(String name,String pwd);
public Reader loginUser(String barcode,String pwd);
}
实现类:
/*
* 表示数据库隔离级别如果当前就有使用当前,如果没有的话就新建新的事务,
*隔离级别:读已提交,也就是数据在写入的时候是无法被读的,只有提交后才能让其他事务读取,
*防止数据库发生
*/
@Transactional(propagation=Propagation.REQUIRED,isolation=Isolation.DEFAULT)
@Service("wLoginService")
public class WLoginServiceImpl implements WLoginService {
@Autowired
private WLoginMapper loginMapper;
private String str = "WLoginServiceImpl...++";
public WLoginServiceImpl(){System.out.println(str+"无参数");}
@Transactional(readOnly=true)
public Manager loginAdmin(String name, String pwd) {
if (name==null || pwd==null) {
System.out.println(str+"name or pwd is null");
return null;
}
System.out.println(str+"name is "+name+";pwd is "+pwd);
//调用DB层方法
Manager manager = loginMapper.loginAdmin(name, pwd);
if (manager!=null) {
System.out.println(str+manager.getName());
} else {
System.out.println(str+"manager is null...."+manager);
}
return manager;
}
@Transactional(readOnly=true)
public Reader loginUser(String barcode, String pwd) {
return loginMapper.loginUser(barcode, pwd);
}
}
Controller:
/**
* 登入控制
* @author user32
*
*/
@Controller("wLoginController")
public class WLoginController {
@Autowired
@Qualifier("wLoginService") //里面写的是bean的名字,与service的id一样。在longinservice的service里面的一样
private WLoginService loginService;
private String str = "WLoginController...//";
/*@RequestMapping(value="/adminW",method=RequestMethod.POST,produces="application/json")
@ResponseBody //此处不能省略 否则ajax无法解析返回值
public ModelAndView loginAdmin(@RequestParam("name")String name,
@RequestParam("pwd")String pwd,
ModelAndView mv,HttpSession session){
//判断请求参数是否为空
if (name==null || pwd==null) {
System.out.println(str+" one is null");
return null;
}
System.out.println(str+"param name is "+name+";pwd is "+pwd);
Manager admin = loginService.loginAdmin(name, pwd);
String page = "";
//查询到登入不为空
if (admin != null) {
System.out.println(str+"登入成功 name:"+admin.getName());
session.setAttribute("admin", admin);
//定向到admin页面
mv.setView(new RedirectView("/BookApp/admin/index"));
// page = "forward:admin/index";
}else{
System.out.println(str+"登入失败");
mv.addObject("message","登入名或密码错误,请重新输入");
//重新设置view视图页面
mv.setViewName("wLoginAdmin");
// page = "redirect:loginForm";
}
// System.out.println((Manager)session.getAttribute("admin"));
return mv;
// return page;
}*/
@RequestMapping(value="/adminW")
@ResponseBody //此处不能省略 否则ajax无法解析返回值
public String loginAdmin(@RequestParam("name")String name,
@RequestParam("pwd")String pwd,
ModelAndView mv,HttpSession session){
//判断请求参数是否为空
if (name==null || pwd==null) {
System.out.println(str+" one is null");
return null;
}
System.out.println(str+"param name is "+name+";pwd is "+pwd);
Manager admin = loginService.loginAdmin(name, pwd);
String page = "";
//查询到登入不为空
if (admin != null) {
System.out.println(str+"登入成功 name:"+admin.getName());
if (session.getAttribute("admin")!=null) {
session.removeAttribute("admin");
}
session.setAttribute("admin", admin);
//定向到admin页面
// mv.setView(new RedirectView("/BookApp/admin/index"));
page = "admin/index";
}else{
System.out.println(str+"登入失败");
mv.addObject("message","登入名或密码错误,请重新输入");
//重新设置view视图页面
// mv.setViewName("wLoginAdmin");
page = "wLoginAdmin";
}
return page;
}
@RequestMapping("/exitW")
public String exitLogin(HttpSession session){
// System.out.println(str+"有运行到这里!!!");
session.removeAttribute("admin");
if (session.getAttribute("admin")==null) {
System.out.println(str+"退出成功");
}
// mv.setViewName("wLoginAdmin");
// mv.setView(new RedirectView("BookApp/wLoginAdmin"));
// return mv;
return "wExitAdmin";
}
}
实现思路:
对于系统设置里边管理员,图书馆,书架;读者管理,图书管理这三大模块的基本实现的思路是类似的,可以说代码基本上是相同的。即通过mapper查询到对应的数据信息,传递给service;controller通过service接口获取数据信息,再将数据信息通过session或者请求方式(model,request)返回到jsp,jsp页面通过jsp语言或者EL以及EL表达式打印数据到页面中。Jsp页面请求数据通过ajax,和a标签两种模式。页面的显示采用和过时很基础的方式
对于图书借阅模块和系统查询模块来说。系统模块查询借本上就是与借阅模块的类表显示一样的。借阅操作:首先通过输入读者的卡号信息,请求对应的借阅数据表,显示列表信息图书和借阅信息;其次再输入对应的图书信息,进行借阅操作。
5.数据库设计
5.1数据表建立
tb_bookcase
tb_bookinfo
Tb_booktype
Tb_borrow
Tb_giveback
Tb_library
Tb_manager
Tb_parameter
Tb_publishing
Tb_purview
Tb_reader
Tb_readertype
6.完成结果
后台登入界面:
登入后界面:(可以忽略中间部分.....主要的部分是左边的菜单栏)
系统设置:
管理员列表:
图书馆列表;
书架列表:
对应操作有编辑,删除和添加。
读者管理模块:
读者类型列表:
读者信息列表:
也类似可以编辑添加删除
图书管理模块:
图书类型列表:
图书信息列表:
也类似的有删除编辑,添加
图书借阅模块:
图书借阅操作:
输入读者的卡号查询借阅情况,在输入图书的相关信息可完成借阅操作。
图书续借操作:
图书归还操作:
系统查询模块:
图书信息查询:
借阅查询:
7.总结
存在bug有登入时候需要提交两次才会跳转,值提交一次数据后虽然在后台有写入session,但是页面没有跳转不过如果是退出后在登入的话就只要提交一次;在借阅管理操作中输入信息也需要调剂哦两次才可以打印出数据信息;对于网页部分,在长时间没有交互或报错,找不到对一个页面;
有些图显示不了可以去下载对应文档看:http://download.csdn.net/detail/shawshank_bingo/9915813
对应代码也有,不过需要一个积分