经典项目,练手必备。

  • 图书管理系统

    需求分析(大致,并不专业):1.需要有用户管理;

                    1.1 用户注册;

                    1.2 用户登录;

                    1.3 用户信息修改;

                    1.4 用户修改密码;

                  2.需要有书本管理;

                    2.1 添加书籍;

                    2.2 借出书籍;

                    2.3 归还书籍;

                    2.4 修改/更新书籍信息;

                  3.需要权限管理;

                    3.1 普通用户与管理员的区别;

                    3.2 拥有不同权限可浏览不同的页面;

    实现技术:1.struts2表现层框架;

         2.hibernate持久层框架;

         3.tomcat web容器;

         4.c3p0数据库连接池;

         5.msql数据库;

         6.jquery开源包;

         7.ajax技术;

         8.css/html页面设计。

  • 准备阶段 

    配置环境:配置struts2,hibernate环境,配上tomcat服务器,安装mysql服务器;

    表设计:本项目设计四张表:user,book,borrow,description

    

    系统总体设计:

    

    页面设计:

    

  • 实现

    采用mvc的设计模式,页面请求到action,action开启服务service,service调用dao来操作数据库。最后将结果返回到页面上呈现。

    

    tips:1.连接池使用listener启动,因为它启动得最早,而且spring也是使用listener来初始化bean工厂;

       2.filter用来做权限控制;

       3.action实现modeldriven接口,需要新建一些映射表单的类;

       4.业务写多了会无聊,并且逻辑都一样,所以我选择只实现了一半;

    页面图:

    index.jsp

    

    register.jsp

    findpassword.jsp

    message页面,统一样式

    main.jsp

    userBook.jsp

     就实现了这些功能,写业务比算法无聊很多,所以大致掌握了就行了,反正练手。

  • 技术笔记

    页面延迟n秒跳转

  1. //自动跳转的轮子
  2. function delayURL(url, time) {
  3. setTimeout("top.location.href='" + url + "'", time);
  4. }

      在html中加入

  1. <script type="text/javascript">
  2. delayURL("findPasswd.jsp", 3000);
  3. </script>

    初始化请求

      在页面载入成功后请求服务器拿初始化数据,并生成表格。

  1. //初始化请求--将当前页和总页面初始化 和 list
  2. $(document).ready(function(){
  3. pagerRequest(currentPage);
  4. });

      使用数据生成表格。

  1. //将数据放在页面上
  2. function putOnTable(list) {
  3. var table = $('#content');
  4. $("#content tr:not(:first)").remove();
  5.  
  6. for ( var k in list) {
  7. var tr = $("<tr></tr>");
  8. tr.appendTo(table);
  9. var book = new Object();
  10. var td;
  11.  
  12. book.bookid = list[k]['bookid'];
  13. book.bookname = list[k]['bookname'];
  14. book.authorname = list[k]['authorname'];
  15. book.publisher = list[k]['publisher'];
  16. book.pub_date = list[k]['pub_date'];
  17.  
  18. td = $("<td>" + book.bookid + "</td>");
  19. td.appendTo(tr);
  20. td = $("<td>" + book.bookname + "</td>");
  21. td.appendTo(tr);
  22. td = $("<td>" + book.authorname + "</td>");
  23. td.appendTo(tr);
  24. td = $("<td>" + book.publisher + "</td>");
  25. td.appendTo(tr);
  26. td = $("<td>" + book.pub_date + "</td>");
  27. td.appendTo(tr);
  28. td = $("<td><button id=btn"+book.bookid +">借书</button>|<button value=''>查看详情</button>");
  29. td.appendTo(tr);
  30. addEvent('btn'+book.bookid,book.bookid);//此处添加事件
  31.  
  32. }
  33.  
  34. }

    分页查询

  1. //点击按钮发送ajax请求
  2. function pagerRequest(need) {
  3. $.post("pager", "need=" + need , function(result) {
  4.  
  5. size = result['size'];
  6. count = result['count'];
  7. booklist = result['booklist'];
  8. $('#current').text(currentPage);
  9. var n1;
  10. var n2;
  11. n1 = count / size;
  12. n2 = count % size;
  13. n1 = Math.floor(n1);
  14. pageNumber = n1;
  15.  
  16. if (n2 !== 0)
  17. pageNumber = pageNumber + 1;
  18.  
  19. $('#total').text(pageNumber);
  20. putOnTable(booklist);
  21. });
  22. }
  1. <!-- 分页查询动作-->
  2. <action name="pager" class="Action.BookPageSelectAction" method="Pager">
  3. <result type="json">
  4. <!-- 这里指定将被Struts2序列化的属性,该属性在action中必须有对应的getter方法 -->
  5. <param name="root">dataMap</param>
  6. </result>
  7. </action>
  1. package Action;
  2.  
  3. import java.util.HashMap;
  4. import java.util.List;
  5.  
  6. import org.apache.struts2.ServletActionContext;
  7.  
  8. import com.opensymphony.xwork2.ActionSupport;
  9.  
  10. import Model.book;
  11. import Service.bookService;
  12.  
  13. public class BookPageSelectAction extends ActionSupport{
  14. private HashMap<String,Object> dataMap;
  15. private List<book> bookList;
  16. private int size=10;
  17. public List<book> getUserList() {
  18. return bookList;
  19. }
  20. public void setUserList(List<book> bookList) {
  21. this.bookList = bookList;
  22. }
  23. public HashMap<String, Object> getDataMap() {
  24. return dataMap;
  25. }
  26.  
  27. public void setDataMap(HashMap<String, Object> dataMap) {
  28. this.dataMap = dataMap;
  29. }
  30. //ajax请求页
  31. public String Pager(){
  32. dataMap = new HashMap<String,Object>();
  33. bookService pager = new bookService();
  34. int count = pager.getBookCount();
  35. String req = ServletActionContext.getRequest().getParameter("need");
  36. Integer value = new Integer(req);
  37. int need = value.intValue();
  38. List list = pager.pageSelectService(need, size);
  39. dataMap.put("booklist",list);
  40. dataMap.put("size", size);
  41. dataMap.put("count", count);
  42. return SUCCESS;
  43. }
  44.  
  45. }
  1. //分页查询
  2. public List pageSelectService(int start,int size){
  3. Session session = SFactoryGenerator.getSession();
  4. Transaction tx = session.beginTransaction();
  5. List list = null;
  6. try{
  7. int need = (start-1)*size;
  8. list = bookDAO.pageSelect(session,need, size);
  9. }catch (Exception e) {
  10. // TODO: handle exception
  11. tx.rollback();
  12. }finally{
  13. session.close();
  14. }
  15. return list;
  16. }
  1. //分页查询
  2. public static List<book> pageSelect(Session session,int start,int size){
  3. String hql = "from book";
  4. Query<?> query = session.createQuery(hql);
  5. query.setFirstResult(start);//开始索引
  6. query.setMaxResults(size);//取几条
  7. List list = query.list();
  8. return list;
  9. }

    删除所有表格条目,只留下表头

  1. $("#content tr:not(:first)").remove();

    绑定事件

  1. $('#'+btnid).bind("click",function(){});

    添加通知栏

      别人的轮子

  1. //添加通知框
  2. function pop_init(title,content) {
  3. //取当前浏览器窗口大小
  4. var windowWidth=document.body.clientWidth;
  5. var windowHeight=document.body.clientHeight;
  6. //弹窗的大小
  7. var weight=250;
  8. var height=132;
  9. $("body").append(
  10. "<div id='pop_div'style='display:none;position:absolute;border:1px solid #e0e0e0;z-index:99;width:"+weight+"px;height:"+height+"px;top:"+(windowHeight-height-132)+"px;left:"+(windowWidth-weight)+"px'>"+
  11. "<div style='line-height:32px;background:#F4A460;border-bottom:1px solid #e0e0e0;font-size:14px;padding:0 0 0 10px;'>" +
  12. "<div style='float:left;'><b>"+title+"</b></div><div style='float:right;cursor:pointer;'><b onclick='pop_close()'>×</b></div>" +
  13. "<div style='clear:both'></div>"+
  14. "</div>" +
  15. "<div id='content' style='background:#EED8AE;height:100px;'>" +
  16. content+
  17. "</div>"+
  18. "</div>"
  19. );
  20. }
  21. function pop_close(){
  22. $('#pop_div').fadeOut(400);
  23. }

    前端校验

      非空校验,长度校验,用户名是否存在校验等等

  1. /**
  2. * 用作注册校验以及ajax服务端校验
  3. */
  4. //非空校验 长度校验
  5. function verificationUsername(){
  6. var data = $('#username').val();
  7. if(data.length === 0)
  8. {
  9. $('#registerErrorMsg1').text("用户名不能为空");
  10. return false;
  11. }
  12. else if(data.length <3 || data.length>12)
  13. {
  14. $('#registerErrorMsg1').text("长度需要在3-12位");
  15. return false;
  16. }
  17. return true;
  18. }
  19. //密码校验
  20. var passwordVer1 = false;
  21. var passwordVer2 = false;
  22. function verificationPassword(){
  23. var data = $('#password').val();
  24. var again = $('#password1').val();
  25. if(data.length === 0)
  26. {
  27. $('#registerErrorMsg2').text("密码不能为空");
  28. return ;
  29. }
  30. else if(data.length <6 || data.length>20)
  31. {
  32. $('#registerErrorMsg2').text("长度需要在6-20位");
  33. return ;
  34. }
  35. passwordVer1 = true;
  36. }
  37. //ajax校验
  38. function ServerVerification(){
  39. var data = $('#username').val();
  40. $.get("userExist","username="+data,function(result){
  41. if(result === "true"){
  42. $('#registerErrorMsg1').text("用户名已存在");
  43. return false;
  44. }
  45. else
  46. {
  47. $('#registerErrorMsg1').text("此用户名可以注册");
  48. return true;
  49. }
  50. });
  51. }
  52. //用户名校验
  53. $(document).ready(function(){
  54. $('#username').blur(function(){
  55. if(verificationUsername())
  56. ServerVerification();
  57. });
  58. });
  59. $(document).ready(function(){
  60. $('#username').focus(function(){
  61. $('#registerErrorMsg1').text("");
  62. });
  63. });
  64. //密码校验
  65. $(document).ready(function(){
  66. $('#password').blur(function(){
  67. verificationPassword();
  68. });
  69. });
  70. $(document).ready(function(){
  71. $('#password').focus(function(){
  72. $('#registerErrorMsg2').text("");
  73. });
  74. });
  75. //两次输入密码校验
  76. $(document).ready(function(){
  77. $('#password1').blur(function(){
  78. if($('#password1').val() !== $('#password').val())
  79. {
  80. $('#registerErrorMsg2').text("密码输入不一致");
  81. return ;
  82. }else
  83. {
  84. $('#registerErrorMsg2').text("");
  85. passwordVer2 = true;
  86. }
  87. });
  88. });
  89.  
  90. //提交时候需要验证
  91. $(document).ready(function(){
  92. $("#registerform").submit(function(){
  93. verificationPassword();
  94. console.log("-----3------");
  95. if(verificationUsername() && passwordVer1 && passwordVer2)
  96. {
  97. return true;
  98. }else
  99. return false;
  100. });
  101. });

    查找书本

      使用hql的都是这样写,被划了横线了好像是过期方法

  1. //查找书本
  2. public static book findByName(Session session,String name){
  3. String hql = "from book where bookname = ?";
  4. Query<?> query = session.createQuery(hql);
  5. query.setParameter(0, name);
  6. List list = query.list();
  7. book book = null;
  8. if(list.size() != 0)
  9. book =(book) list.get(0);
  10. return book;
  11. }

    使用count计算条目

  1. //获取书本的条数
  2. public static int getBookCount(Session session){
  3. String hql="SELECT COUNT(*) FROM book";
  4. Query<?> query = session.createQuery(hql);
  5. return ((Number)query.uniqueResult()).intValue();
  6. }

    自定类联合查询

      不会join,用的where and。新建一个类不需要添加mapping也能封装成object。

  1. //获取借书列表
  2. public static List user_bookList(Session session,int userid){
  3. String hql = "select new Model.user_book(b.bookid,b.bookname,b.publisher,bo.date) from book b,borrow bo where bo.user_id = ? and bo.book_id = b.bookid";
  4. Query query =session.createQuery(hql);
  5. query.setParameter(0, userid);
  6. List list = query.list();
  7. if(list.size() == 0)
  8. return null;
  9. return list;
  10. }

    request

      request的attribute和parameter是两个东西,已parameter是跟在请求后面的参数,attribute是类似于session这种存储在request范围内的属性。

      标准的获取形式为

  1. //获取请求响应
  2. HttpServletRequest request = ServletActionContext.getRequest();
  3. HttpServletResponse response = ServletActionContext.getResponse();
  • 总结

    个人觉得不写之前很简单,写了之后也很简单。但是写的过程有很多的不懂,所以项目还是要做一下不然抱着demo不知道怎么用。因为s和h框架很少用了,所以不专注于写这个项目了。关键是网站的大部分的功能如何构建,换了框架和数据库一样是这样实现。自己做一做小项目会增长很多的本事。写了代码也要多多总结,比如刚写css的时候就感觉越写越多,很多重复功能,因为不主攻前端,所以让它变成臭鸡蛋吧,这样的感觉。

    action的配置我觉得挺方便的,反而是注释开发,好像不能一眼看完所有的controller,然而action太侵入性,所以已经有些过时。hibernate用了之后我觉得各有利弊吧,我还是喜欢jdbc的感觉。接下来就该细致地写spring的项目了。

    

    

struts2+hibernate 项目实战:图书管理系统的更多相关文章

  1. C项目实践--图书管理系统(3)

    接下来将要实现用户管理模块的相关功能,用户管理模块的主要功能包括增加用户,查找用户以及保存用户等功能,查找用户时,如果查找成功,充许对查找到用户进行更新或删除操作.如果查找不成功,则给出相应的提示信息 ...

  2. C项目实践--图书管理系统(1)

    1.功能需求分析 图书管理系统主要用于对大量的图书信息,包括书名.作者.出版社.出版日期.ISBN(书号)等进行增.删.改.查以及保存等操作.同时也包括对用户的管理,用户包括管理员和普通用户两种权限, ...

  3. C项目实践--图书管理系统(2)

    前面在<<C项目实践-图书管理系统(1)>>中把系统中的三大功能模块中可能涉及到的常量,结构体及相关函数进行了声明定义,下来就来实现它们. 执行系统首先从登录到系统开始,所以首 ...

  4. Spring Boot → 11:项目实战-账单管理系统完整版

    Spring Boot → 11:项目实战-账单管理系统完整版

  5. Spring Boot → 06:项目实战-账单管理系统

    Spring Boot → 06:项目实战-账单管理系统

  6. javaWeb项目之图书管理系统(附视频讲解)

    视频播放地址:javaWeb图书系统 本系统为"Swing项目之图书管理系统"(此源码已共享)的Web版,网页框架用采用EasyUI 数据库为MysqL,写Web项目摒弃了火狐浏览 ...

  7. C项目实践--图书管理系统(4)

    前面已经把图书管理系统的所有功能模块都已实现完毕了,下面通过运行来分析该系统的操作流程并检验是否符合逻辑设计要求. 3.系统操作过程 F5 运行 1.登录系统 系统运行之后,提示输入用户名和密码,系统 ...

  8. 新建Django项目示例--图书管理系统

    知识点: Django 1. 安装 1. Django版本 1.11.xx 2. 安装方式 1. 命令行 --> Python环境(双版本,pip的使用) 2. PyCharm安装 2. 创建D ...

  9. [ABP项目实战]-后台管理系统-目录

    学习ABP也有一段时间了,但是总是学习了后面的忘记了前面的,为了巩固所学到的知识以及记录所学到的东西,因此有了本系列的诞生. ABP ASP.NET Boilerplate Project(ABP.N ...

随机推荐

  1. android 拔打电话功能

    private void phoneCall(String num) { String phoneNum = "tel:" + num; Uri smsToUri = Uri.pa ...

  2. centos 6.6 使用tomcat6部署solr5.3.1

    Solr现在是一个独立的服务器. 从Solr5.0开始,Solr不再发布为在任何Servlet容器中部署的“war”Web应用程序包(Web Application Archive).网上关于solr ...

  3. Qt 之 入门例程 (一)

    以 “Hello Qt” 为例,介绍如何建立一个 Qt 工程 . 1  QLabel 例程 QLabel 继承自 QFrame (继承自 QWidget),主要用来显示文本和图片. 1.1  Hell ...

  4. Jsp 错题分析

    ArrayList删除元素通过RemoveAt(int index)来删除指定索引值的元素 运行时异常都是RuntimeException类及其子类异常,如NullPointerException.I ...

  5. Winform(DataGridView)控件及通过此控件中实现增删改查

    DataGridView:显示数据表,通过此控件中可以实现连接数据库,实现数据的增删改查 一.后台数据绑定:    List<xxx> list = new List<xxx> ...

  6. Session跟SessionFactory的线程安全与非安全

    SessionFactory负责创建session,SessionFactory是线程安全的,多个并发线程可以同时访问一个 SessionFactory 并从中获取Session实例. (Sessio ...

  7. BestCoder Round #89 Fxx and string

    问题描述 青年理论计算机科学家Fxx得到了一个只包含小写字母的字符串. 字符串的长度为\:nn,下标从1开始,第\:i\:i位的字母为\:s_is​i​​,现在Fxx想知道有多少三元组\:(i,j,k ...

  8. Apache 配置虚拟主机三种方式

    一.基于IP 1. 假设服务器有个IP地址为192.168.1.10,使用ifconfig在同一个网络接口eth0上绑定3个IP: [root@localhost root]# ifconfig et ...

  9. Centos6 服务器病毒查杀命令历史

    top whereis vhowazeclu ll /usr/bin/v* more /usr/bin/vhowazeclu ps aux|grep vhowa ps aux|grep vhowaze ...

  10. (原创)JAVA多线程二线程池

    一,线程池的介绍 线程池包括一下三种: 线程池名称 创建方法 特点 其他 固定大小线程池 ExecutorService threadpool = Executors.newFixedThreadPo ...