书城项目第四阶段:图书模块
4.1MVC的概念
MVC 全称:Model 模型、 View 视图、 Controller 控制器。MVC 最早出现在 JavaEE 三层中的 Web 层,它可以有效的指导 Web 层的代码如何有效分离,单独工作。
1、 View 视图:只负责数据和界面的显示,不接受任何与显示数据无关的代码,便于程序员和美工的分工合作—— JSP/HTML。
2、 Controller 控制器:只负责接收请求,调用业务层的代码处理请求,然后派发页面,是一个“调度者”的角色——Servlet。 转到某个页面。或者是重定向到某个页面。
3、 Model 模型:将与业务逻辑相关的数据封装为具体的 JavaBean 类,其中不掺杂任何与数据处理相关的代码—— JavaBean/domain/entity/pojo。
MVC 是一种思想 MVC 的理念是将软件代码拆分成为组件,单独开发,组合使用。(目的还是为了降低耦合度),MVC 的作用还是为了降低耦合。让代码合理分层。方便后期升级和维护。
4.2图书模块的实现
4.2.1编写图书模块的数据库表
创建对应的表:
1. create table t_book(
2. `id` int primary key auto_increment,
3. `name` varchar(100),
4. `price` decimal(11,2),
5. `author` varchar(100),
6. `sales` int,
7. `stock` int,
8. `img_path` varchar(200)
9. );
插入并查看数据:
1. insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`)
2. values(null , 'java 从入门到放弃' , '国哥' , 80 , 9999 , 9 , 'static/img/default.jpg');
3. insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`)
4. values(null , '数据结构与算法' , '严敏君' , 78.5 , 6 , 13 , 'static/img/default.jpg');
5. insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`)
6. values(null , '怎样拐跑别人的媳妇' , '龙伍' , 68, 99999 , 52 , 'static/img/default.jpg');
7. insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`)
8. values(null , '木虚肉盖饭' , '小胖' , 16, 1000 , 50 , 'static/img/default.jpg');
9. insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`)
10. values(null , 'C++编程思想' , '刚哥' , 45.5 , 14 , 95 , 'static/img/default.jpg');
11. insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`)
12. values(null , '蛋炒饭' , '周星星' , 9.9, 12 , 53 , 'static/img/default.jpg');
13. insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`)
14. values(null , '赌神' , '龙伍' , 66.5, 125 , 535 , 'static/img/default.jpg');
15. insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`)
16. values(null , 'Java 编程思想' , '阳哥' , 99.5 , 47 , 36 , 'static/img/default.jpg');
17. insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`)
18. values(null , 'JavaScript 从入门到精通' , '婷姐' , 9.9 , 85 , 95 , 'static/img/default.jpg');
19. insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`)
20. values(null , 'cocos2d-x 游戏编程入门' , '国哥' , 49, 52 , 62 , 'static/img/default.jpg');
21. insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`)
22. values(null , 'C 语言程序设计' , '谭浩强' , 28 , 52 , 74 , 'static/img/default.jpg');
23. insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`)
24. values(null , 'Lua 语言程序设计' , '雷丰阳' , 51.5 , 48 , 82 , 'static/img/default.jpg');
25. insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`)
26. values(null , '西游记' , '罗贯中' , 12, 19 , 9999 , 'static/img/default.jpg');
27. insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`)
28. values(null , '水浒传' , '华仔' , 33.05 , 22 , 88 , 'static/img/default.jpg');
29. insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`)
30. values(null , '操作系统原理' , '刘优' , 133.05 , 122 , 188 , 'static/img/default.jpg');
31. insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`)
32. values(null , '数据结构 java 版' , '封大神' , 173.15 , 21 , 81 , 'static/img/default.jpg');
33. insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`)
34. values(null , 'UNIX 高级环境编程' , '乐天' , 99.15 , 210 , 810 , 'static/img/default.jpg');
35. insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`)
36. values(null , 'javaScript 高级编程' , '国哥' , 69.15 , 210 , 810 , 'static/img/default.jpg');
37. insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`)
38. values(null , '大话设计模式' , '国哥' , 89.15 , 20 , 10 , 'static/img/default.jpg');
39. insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`)
40. values(null , '人月神话' , '刚哥' , 88.15 , 20 , 80 , 'static/img/default.jpg');
41. ## 查看表内容
42. select id,name,author,price,sales,stock,img_path from t_book
4.2.2编写图书模块的 JavaBean
1. public class Book {
2. private Integer id;
3. private String name;
4. private String author;
5. private BigDecimal price;
6. private Integer sales;
7. private Integer stock;
8. private String imgPath = "static/img/default.jpg";
4.2.3编写图书模块的 Dao 和测试 Dao
Dao接口:
1. public interface BookDao {
2. public int addBook(Book book);
3. public int deleteBookById(Integer id);
4. public int updateBook(Book book);
5. public Book queryBookById(Integer id);
6. public List<Book> queryBooks();
7. }
BookDaoImpl实现类:
8. public class BookDaoImpl extends BaseDao implements BookDao {
9. @Override
10. public int addBook(Book book) {
11. String sql = "insert into t_book(`name`,`author`,`price`,`sales`,`stock`,`img_path`)
12. values(?,?,?,?,?,?)";
13. return update(sql,
14. book.getName(),book.getAuthor(),book.getPrice(),book.getSales(),book.getStock(),book.getImgPath());
15. }
16. @Override
17. public int deleteBookById(Integer id) {
18. String sql = "delete from t_book where id = ?";
19. return update(sql, id);
20. }
21. @Override
22. public int updateBook(Book book) {
23. String sql = "update t_book set `name`=?,`author`=?,`price`=?,`sales`=?,`stock`=?,`img_path`=?
24. where id = ?";
25. return
26. update(sql,book.getName(),book.getAuthor(),book.getPrice(),book.getSales(),book.getStock(),book.ge
27. tImgPath(),book.getId());
28. }
29. @Override
30. public Book queryBookById(Integer id) {
31. String sql = "select `id` , `name` , `author` , `price` , `sales` , `stock` , `img_path` imgPath
32. from t_book where id = ?";
33. return queryForOne(Book.class, sql,id);
34. }
35. @Override
36. public List<Book> queryBooks() {
37. String sql = "select `id` , `name` , `author` , `price` , `sales` , `stock` , `img_path` imgPath
38. from t_book";
39. return queryForList(Book.class, sql);
40. }
41. }
BookDao的测试:
42. public class BookDaoTest {
43. private BookDao bookDao = new BookDaoImpl();
44. @Test
45. public void addBook() {
46. bookDao.addBook(new Book(null,"国哥为什么这么帅!", "191125", new
47. BigDecimal(9999),1100000,0,null
48. ));
49. }
50. @Test
51. public void deleteBookById() {
52. bookDao.deleteBookById(21);
53. }
54. @Test
55. public void updateBook() {
56. bookDao.updateBook(new Book(21,"大家都可以这么帅!", "国哥", new
57. BigDecimal(9999),1100000,0,null
58. ));
59. }
60. @Test
61. public void queryBookById() {
62. System.out.println( bookDao.queryBookById(21) );
63. }
64. @Test
65. public void queryBooks() {
66. for (Book queryBook : bookDao.queryBooks()) {
67. System.out.println(queryBook);
68. }
69. }
70. }
4.2.4编写图书模块的 Service 和测试 Service
BookService:
1. public interface BookService {
2. public void addBook(Book book);
3.
4. public void deleteBookById(Integer id);
5.
6. public void updateBook(Book book);
7.
8. public Book queryBookById(Integer id);
9.
10. public List<Book> queryBooks();
11. }
BookServiceImpl实现类:
12. import com.atguigu.dao.BookDao;
13. import com.atguigu.dao.impl.BookDaoImpl;
14. import com.atguigu.pojo.Book;
15. import com.atguigu.service.BookService;
16.
17. import java.util.List;
18.
19. public class BookServiceImpl implements BookService {
20. private BookDao bookDao = new BookDaoImpl();
21.
22. @Override
23. public void addBook(Book book) {
24. bookDao.addBook(book);
25. }
26.
27. @Override
28. public void deleteBookById(Integer id) {
29. bookDao.deleteBookById(id);
30. }
31.
32. @Override
33. public void updateBook(Book book) {
34. bookDao.updateBook(book);
35. }
36.
37. @Override
38. public Book queryBookById(Integer id) {
39. return bookDao.queryBookById(id);
40. }
41.
42. @Override
43. public List<Book> queryBooks() {
44. return bookDao.queryBooks();
45. }
46. }
BookService的测试:
47. import com.atguigu.service.BookService;
48. import com.atguigu.service.impl.BookServiceImpl;
49.
50. import java.math.BigDecimal;
51.
52. public class BookServiceTest {
53. private BookService bookService = new BookServiceImpl();
54.
55. @Test
56. public void addBook() {
57. bookService.addBook(new Book(null, "国哥在手,天下我有!", "1125", new BigDecimal(1000000), 100000000, 0, null));
58. }
59.
60. @Test
61. public void deleteBookById() {
62. bookService.deleteBookById(22);
63. }
64.
65. @Test
66. public void updateBook() {
67. bookService.updateBook(new Book(22, "社会我国哥,人狠话不多!", "1125", new BigDecimal(999999), 10, 111110, null));
68. }
69.
70. @Test
71. public void queryBookById() {
72. System.out.println(bookService.queryBookById(22));
73. }
74.
75. @Test
76. public void queryBooks() {
77. for (Book queryBook : bookService.queryBooks()) {
78. System.out.println(queryBook);
79. }
80. }
81. }
4.3编写图书模块的 Web 层,和页面联调测试
4.3.1图书列表功能的实现
4.3.1.1图解列表功能流程
4.3.1.2BookServlet 程序中添加 list 方法
1. protected void list(HttpServletRequest req,HttpServletResponse resp)throws ServletException,
2. IOException{
3. //1 通过 BookService 查询全部图书
4. List<Book> books=bookService.queryBooks();
5. //2 把全部图书保存到 Request 域中
6. req.setAttribute("books",books);
7. //3、请求转发到/pages/manager/book_manager.jsp 页面
8. req.getRequestDispatcher("/pages/manager/book_manager.jsp").forward(req,resp);
9. }
4.3.1.3修改【图书管理】请求地址
4.3.1.4修改 pages/manager/book_manager.jsp 页面的数据遍历输出
1. <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
2. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
3. <!DOCTYPE html>
4. <html>
5. <head>
6. <meta charset="UTF-8">
7. <title>图书管理</title>
8. <%-- 静态包含 base 标签、css 样式、jQuery 文件 --%>
9. <%@ include file="/pages/common/head.jsp"%>
10. </head>
11. <body>
12. <div id="header">
13. <img class="logo_img" alt="" src="../../static/img/logo.gif">
14. <span class="wel_word">图书管理系统</span>
15. <%-- 静态包含 manager 管理模块的菜单 --%>
16. <%@include file="/pages/common/manager_menu.jsp"%>
17. </div>
18. <div id="main">
19. <table>
20. <tr>
21. <td>名称</td>
22. <td>价格</td>
23. <td>作者</td>
24. <td>销量</td>
25. <td>库存</td>
26. <td colspan="2">操作</td>
27. </tr>
28. <c:forEach items="${requestScope.books}" var="book">
29. <tr>
30. <td>${book.name}</td>
31. <td>${book.price}</td>
32. <td>${book.author}</td>
33. <td>${book.sales}</td>
34. <td>${book.stock}</td>
35. <td><a href="book_edit.jsp">修改</a></td>
36. <td><a href="#">删除</a></td>
37. </tr>
38. </c:forEach>
39. <tr>
40. <td></td>
41. <td></td>
42. <td></td>
43. <td></td>
44. <td></td>
45. <td></td>
46. <td><a href="book_edit.jsp">添加图书</a></td>
47. </tr>
48. </table>
49. </div>
50. <%--静态包含页脚内容--%>
51. <%@include file="/pages/common/footer.jsp"%>
52. </body>
53. </html>
4.3.1.5前后台的简单介绍
4.3.2添加图书功能的实现
4.3.2.1添加图书流程细节
4.3.2.2表单重复提交
当用户提交完请求,浏览器会记录下最后一次请求的全部信息。当用户按下功能键 F5,就会发起浏览器记录的最后一次请求,这样就会造成表单重复提交的问题。
4.3.2.3BookServlet 程序中添加 add 方法
1. protected void add(HttpServletRequest req,HttpServletResponse resp)throws ServletException,
2. IOException{
3. // 1、获取请求的参数==封装成为 Book 对象
4. Book book=WebUtils.copyParamToBean(req.getParameterMap(),new Book());
5. // 2、调用 BookService.addBook()保存图书
6. bookService.addBook(book);
7. // 3、跳到图书列表页面
8. // /manager/bookServlet?action=list
9. // req.getRequestDispatcher("/manager/bookServlet?action=list").forward(req, resp);
10. resp.sendRedirect(req.getContextPath()+"/manager/bookServlet?action=list");
11. }
4.3.2.4修改 book_edit.jsp 页面
1. <%@ page contentType="text/html;charset=UTF-8" language="java" %>
2. <!DOCTYPE html>
3. <html>
4. <head>
5. <meta charset="UTF-8">
6. <title>编辑图书</title>
7. <%-- 静态包含 base 标签、css 样式、jQuery 文件 --%>
8. <%@ include file="/pages/common/head.jsp"%>
9. <style type="text/css">
10. h1 {
11. text-align: center;
12. margin-top: 200px;
13. }
14.
15. h1 a {
16. color: red;
17. }
18.
19. input {
20. text-align: center;
21. }
22. </style>
23. </head>
24. <body>
25. <div id="header">
26. <img class="logo_img" alt="" src="../../static/img/logo.gif">
27. <span class="wel_word">编辑图书</span>
28. <%-- 静态包含 manager 管理模块的菜单 --%>
29. <%@include file="/pages/common/manager_menu.jsp"%>
30. </div>
31. <div id="main">
32. <form action="manager/bookServlet" method="get">
33. <input type="hidden" name="action" value="add"/>
34. <table>
35. <tr>
36. <td>名称</td>
37. <td>价格</td>
38. <td>作者</td>
39. <td>销量</td>
40. <td>库存</td>
41. <td colspan="2">操作</td>
42. </tr>
43. <tr>
44. <td><input name="name" type="text" value="时间简史"/></td>
45. <td><input name="price" type="text" value="30.00"/></td>
46. <td><input name="author" type="text" value="霍金"/></td>
47. <td><input name="sales" type="text" value="200"/></td>
48. <td><input name="stock" type="text" value="300"/></td>
49. <td><input type="submit" value="提交"/></td>
50. </tr>
51. </table>
52. </form>
53. </div>
54. <%--静态包含页脚内容--%>
55. <%@include file="/pages/common/footer.jsp"%>
56. </body>
57. </html>
4.3.3删除图书功能的实现
4.3.3.1图解删除流程
4.3.3.2BookServlet 程序中的 delete 方法
1. protected void delete(HttpServletRequest req,HttpServletResponse resp)throws ServletException,IOException{
2. // 1、获取请求的参数 id,图书编程
3. int id=WebUtils.parseInt(req.getParameter("id"),0);
4. // 2、调用 bookService.deleteBookById();删除图书
5. bookService.deleteBookById(id);
6. // 3、重定向回图书列表管理页面
7. // /book/manager/bookServlet?action=list
8. resp.sendRedirect(req.getContextPath()+"/manager/bookServlet?action=list");
9. }
4.3.3.3给 WebUtils 工具类添加转换 int 类型的工具方法
1. /**
2. * 将字符串转换成为 int 类型的数据
3. *
4. * @param strInt
5. * @param defaultValue
6. * @return
7. */
8. public static int parseInt(String strInt,int defaultValue){
9. try{
10. return Integer.parseInt(strInt);
11. }catch(Exception e){
12. e.printStackTrace();
13. }
14. return defaultValue; 15. }
4.3.3.4修改删除的连接地址
4.3.3.5给删除添加确认提示操作
1. <script type="text/javascript">
2. $(function () {
3. // 给删除的 a 标签绑定单击事件,用于删除的确认提示操作
4. $("a.deleteClass").click(function () {
5. // 在事件的 function 函数中,有一个 this 对象。这个 this 对象,是当前正在响应事件的 dom 对象。
6. /**
7. * confirm 是确认提示框函数
8. * 参数是它的提示内容
9. * 它有两个按钮,一个确认,一个是取消。
10. * 返回 true 表示点击了,确认,返回 false 表示点击取消。
11. */
12. return confirm("你确定要删除【" + $(this).parent().parent().find("td:first").text() + "】?");
13. // return false// 阻止元素的默认行为===不提交请求
14. });
15. });
16. </script>
4.3.4修改图书功能的实现
4.3.4.1图解修改图书细节
4.3.4.2更新【修改】的请求地址
4.3.4.3BookServlet 程序中添加 getBook 方法
1. protected void getBook(HttpServletRequest req,HttpServletResponse resp)throws ServletException,
2. IOException{
3. //1 获取请求的参数图书编号
4. int id=WebUtils.parseInt(req.getParameter("id"),0);
5. //2 调用 bookService.queryBookById 查询图书
6. Book book=bookService.queryBookById(id);
7. //3 保存到图书到 Request 域中
8. req.setAttribute("book",book);
9. //4 请求转发到。pages/manager/book_edit.jsp 页面
10. req.getRequestDispatcher("/pages/manager/book_edit.jsp").forward(req,resp); 11. }
4.3.4.4在 book_edit.jsp 页面中显示修改的数据
1. <div id="main">
2. <form action="manager/bookServlet" method="get">
3. <input type="hidden" name="action" value="add"/>
4. <table>
5. <tr>
6. <td>名称</td>
7. <td>价格</td>
8. <td>作者</td>
9. <td>销量</td>
10. <td>库存</td>
11. <td colspan="2">操作</td>
12. </tr>
13. <tr>
14. <td><input name="name" type="text" value="${requestScope.book.name}"/></td>
15. <td><input name="price" type="text" value="${requestScope.book.price}"/></td>
16. <td><input name="author" type="text" value="${requestScope.book.author}"/></td>
17. <td><input name="sales" type="text" value="${requestScope.book.sales}"/></td>
18. <td><input name="stock" type="text" value="${requestScope.book.stock}"/></td>
19. <td><input type="submit" value="提交"/></td>
20. </tr>
21. </table>
22. </form>
23. </div>
4.3.4.5在 BookServlet 程序中添加 update 方法
1. protected void update(HttpServletRequest req,HttpServletResponse resp)throws ServletException,
2. IOException{
3. // 1、获取请求的参数==封装成为 Book 对象
4. Book book=WebUtils.copyParamToBean(req.getParameterMap(),new Book());
5. // 2、调用 BookService.updateBook( book );修改图书
6. bookService.updateBook(book);
7. // 3、重定向回图书列表管理页面
8. // 地址:/工程名/manager/bookServlet?action=list
9. resp.sendRedirect(req.getContextPath()+"/manager/bookServlet?action=list");
10. }