D12 Sping Boot 入门 Sping框架--Java Web之书城项目(四)MVC之图书模块
1、MVC
MVC全称:Model模型、View视图、Controller控制器。
View视图层:只负责数据和界面的显示,不接受任何与显示数据无关的代码,便于程序员与美工的分工合作--JSP/HTML。
Controller控制器:只负责接受请求,调用业务层的代码处理请求,然后派发页面,是一个“调度者”的角色--Servlet。
Model模型:将与业务逻辑相关的数据封装为具体的JavaBean类,其中不参杂任何与数据处理相关的代码--JavaBean/domain/entity/pojo。
MVC是一种思想
MVC的理念是将软件代码拆分成组件,单独开发,组合使用(为了解耦合)
2、图书模块
Ⅰ、编写图书模块的数据库表
1 -- 创建图书图书模块的数据库表(MySQL中已有book表) 2 use book; 3 create table t_book( 4 `id` int primary key auto_increment, 5 `name` varchar(100), 6 `price` decimal(11,2), 7 `author` varchar(100), 8 `stock` int, 9 `sales` int, 10 `img_path` varchar(200) 11 );
插入图书信息时出现中文编码错误时请参考解决办法
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
/*插入图书信息*/ insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`) values(null , 'java 从入门到放弃' , '国哥' , 80 , 9999 , 9 , 'static/img/default.jpg'); insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`) values(null , '数据结构与算法' , '严敏君' , 78.5 , 6 , 13 , 'static/img/default.jpg'); insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`) values(null , '怎样拐跑别人的媳妇' , '龙伍' , 68, 99999 , 52 , 'static/img/default.jpg'); insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`) values(null , '木虚肉盖饭' , '小胖' , 16, 1000 , 50 , 'static/img/default.jpg'); insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`) values(null , 'C++编程思想' , '刚哥' , 45.5 , 14 , 95 , 'static/img/default.jpg'); insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`) values(null , '蛋炒饭' , '周星星' , 9.9, 12 , 53 , 'static/img/default.jpg'); insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`) values(null , '赌神' , '龙伍' , 66.5, 125 , 535 , 'static/img/default.jpg'); insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`) values(null , 'Java 编程思想' , '阳哥' , 99.5 , 47 , 36 , 'static/img/default.jpg'); insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`) values(null , 'JavaScript 从入门到精通' , '婷姐' , 9.9 , 85 , 95 , 'static/img/default.jpg'); insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`) values(null , 'cocos2d-x 游戏编程入门' , '国哥' , 49, 52 , 62 , 'static/img/default.jpg'); insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`) values(null , 'C 语言程序设计' , '谭浩强' , 28 , 52 , 74 , 'static/img/default.jpg'); insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`) values(null , 'Lua 语言程序设计' , '雷丰阳' , 51.5 , 48 , 82 , 'static/img/default.jpg'); insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`) values(null , '西游记' , '罗贯中' , 12, 19 , 9999 , 'static/img/default.jpg'); insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`) values(null , '水浒传' , '华仔' , 33.05 , 22 , 88 , 'static/img/default.jpg'); insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`) values(null , '操作系统原理' , '刘优' , 133.05 , 122 , 188 , 'static/img/default.jpg'); insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`) values(null , '数据结构 java 版' , '封大神' , 173.15 , 21 , 81 , 'static/img/default.jpg'); insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`) values(null , 'UNIX 高级环境编程' , '乐天' , 99.15 , 210 , 810 , 'static/img/default.jpg'); insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`) values(null , 'javaScript 高级编程' , '国哥' , 69.15 , 210 , 810 , 'static/img/default.jpg'); insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`) values(null , '大话设计模式' , '国哥' , 89.15 , 20 , 10 , 'static/img/default.jpg'); insert into t_book(`id` , `name` , `author` , `price` , `sales` , `stock` , `img_path`) values(null , '人月神话' , '刚哥' , 88.15 , 20 , 80 , 'static/img/default.jpg');
Ⅱ、编写图书模块的JavaBean
在com.gychen.pojo中新建Book.java
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.gychen.pojo; 2 3 import java.math.BigDecimal; 4 5 public class Book { 6 7 //定义数据库变量 8 private Integer id; 9 private String name; 10 private String author; 11 private BigDecimal price; 12 private Integer sales; 13 private Integer stock; 14 private String imgPath = "static/img/default.jpg"; 15 16 17 //生成get和set方法 18 public Integer getId() { 19 return id; 20 } 21 22 public void setId(Integer id) { 23 this.id = id; 24 } 25 26 public String getName() { 27 return name; 28 } 29 30 public void setName(String name) { 31 this.name = name; 32 } 33 34 public String getAuthor() { 35 return author; 36 } 37 38 public void setAuthor(String author) { 39 this.author = author; 40 } 41 42 public BigDecimal getPrice() { 43 return price; 44 } 45 46 public void setPrice(BigDecimal price) { 47 this.price = price; 48 } 49 50 public Integer getSales() { 51 return sales; 52 } 53 54 public void setSales(Integer sales) { 55 this.sales = sales; 56 } 57 58 public Integer getStock() { 59 return stock; 60 } 61 62 public void setStock(Integer stock) { 63 this.stock = stock; 64 } 65 66 public String getImgPath() { 67 return imgPath; 68 } 69 70 public void setImgPath(String imgPath) { 71 this.imgPath = imgPath; 72 } 73 74 //生成toString 75 @Override 76 public String toString() { 77 return "Book{" + 78 "id=" + id + 79 ", name='" + name + '\'' + 80 ", author='" + author + '\'' + 81 ", price=" + price + 82 ", sales=" + sales + 83 ", stock=" + stock + 84 ", imgPath='" + imgPath + '\'' + 85 '}'; 86 } 87 88 //生成有参和无参 89 public Book() { 90 } 91 92 public Book(Integer id, String name, String author, BigDecimal price, Integer sales, Integer stock, String imgPath) { 93 this.id = id; 94 this.name = name; 95 this.author = author; 96 this.price = price; 97 this.sales = sales; 98 this.stock = stock; 99 //判断一下 100 //this.imgPath = imgPath; 101 //要求给定的图书封面图书路径不能为空或空字符串 102 if(imgPath != null && !"".equals(imgPath)){ 103 this.imgPath = imgPath; 104 } 105 } 106 }
Ⅲ、编写图书模块的Dao和测试Dao
在com.gychen.dao中创建BookDao.java接口
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.gychen.dao; 2 3 import com.gychen.pojo.Book; 4 5 import java.util.List; 6 7 public interface BookDao { 8 9 //public可以省略 10 //增 11 public int addBook(Book book); 12 13 //删 14 public int deleteBookById(Integer id); 15 16 //改 17 public int updateBook(Book book); 18 19 //查 20 public Book queryBookById(Integer id); 21 22 public List<Book> queryBooks(); 23 }
在com.gychen.dao.impl中新建BookDaoImpl实现类,生成一下实现方法:Implement Methods,并编写sql语句(其中继承的BaseDao如下)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.gychen.dao.impl; 2 3 import com.gychen.utils.JdbcUtils; 4 import org.apache.commons.dbutils.QueryRunner; 5 import org.apache.commons.dbutils.handlers.BeanHandler; 6 import org.apache.commons.dbutils.handlers.BeanListHandler; 7 import org.apache.commons.dbutils.handlers.ScalarHandler; 8 9 import java.sql.Connection; 10 import java.sql.SQLException; 11 import java.util.List; 12 13 //复用类使用抽象abstract类 14 public abstract class BaseDao { 15 16 //使用DbUtils操作数据库 17 private QueryRunner queryRunner = new QueryRunner(); 18 19 /** 20 * update()方法用来执行Insert、Update、Delete语句 21 * @return 如果返回-1,说明执行失败<br/>返回其他表示影响的行数 22 */ 23 public int update(String sql, Object ...args){ 24 Connection connection = JdbcUtils.getConnection(); 25 try { 26 return queryRunner.update(connection,sql,args); 27 } catch (SQLException e) { 28 e.printStackTrace(); 29 }finally { 30 JdbcUtils.close(connection); 31 } 32 return -1; 33 } 34 35 /** 36 * 查询返回一个JavaBean的sql语句 37 * @param type 返回的对象类型 38 * @param sql 执行的sql语句 39 * @param args sql对应的参数值 40 * @param <T> 返回的类型的泛型 41 * @return 42 */ 43 public <T> Object queryForOne(Class<T> type,String sql,Object...args){ 44 Connection connection = JdbcUtils.getConnection(); 45 try { 46 return queryRunner.query(connection,sql,new BeanHandler<T>(type),args); 47 } catch (SQLException e) { 48 e.printStackTrace(); 49 }finally { 50 JdbcUtils.close(connection); 51 } 52 return null; 53 } 54 55 /** 56 * 查询返回多个JavaBean的sql语句 57 * @param type 返回的对象类型 58 * @param sql 执行的sql语句 59 * @param args sql对应的参数值 60 * @param <T> 返回的类型的泛型 61 * @return 62 */ 63 public <T> List<T> queryForList(Class<T> type, String sql, Object...args){ 64 Connection connection = JdbcUtils.getConnection(); 65 try { 66 return queryRunner.query(connection,sql,new BeanListHandler<T>(type),args); 67 } catch (SQLException e) { 68 e.printStackTrace(); 69 }finally { 70 JdbcUtils.close(connection); 71 } 72 return null; 73 } 74 75 /** 76 * 执行返回一行一列的sql语句 77 * @param sql 执行的sql语句 78 * @param args sql对应的参数值 79 * @return 80 */ 81 public Object queryForSingleValue(String sql,Object...args){ 82 Connection connection = JdbcUtils.getConnection(); 83 try { 84 return queryRunner.query(connection,sql,new ScalarHandler(),args); 85 } catch (Exception e) { 86 e.printStackTrace(); 87 }finally { 88 JdbcUtils.close(connection); 89 } 90 return null; 91 } 92 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.gychen.dao.impl; 2 3 import com.gychen.dao.BookDao; 4 import com.gychen.pojo.Book; 5 6 import java.util.List; 7 8 public class BookDaoImpl extends BaseDao implements BookDao { 9 10 //生成一下实现方法:Implement Methods,并编写sql语句 11 @Override 12 public int addBook(Book book) { 13 14 String sql = "insert into t_book(`name`,`author`,`price`,`sales`,`stock`,`img_path`) " + 15 "values(?,?,?,?,?,?)"; 16 return update(sql,book.getName(),book.getAuthor(),book.getPrice(), 17 book.getSales(),book.getStock(),book.getImgPath()); 18 } 19 20 @Override 21 public int deleteBookById(Integer id) { 22 23 String sql = "delete from t_book where id = ?"; 24 return update(sql,id); 25 } 26 27 @Override 28 public int updateBook(Book book) { 29 30 String sql = "update t_book set `name`=?,`author`=?,`price`=?,`sales`=?,`stock`=?,`img_path`=? where id=?"; 31 return update(sql,book.getName(),book.getAuthor(),book.getPrice(), 32 book.getSales(),book.getStock(),book.getImgPath(),book.getId()); 33 } 34 35 @Override 36 public Book queryBookById(Integer id) { 37 //其中imgPath是别名 38 String sql = "select `id`, `name`,`author`,`price`,`sales`,`stock`,`img_path` imgPath from t_book where id=?"; 39 return (Book) queryForOne(Book.class,sql,id); 40 } 41 42 @Override 43 public List<Book> queryBooks() { 44 45 //其中imgPath是别名 46 String sql = "select `id`, `name`,`author`,`price`,`sales`,`stock`,`img_path` imgPath from t_book"; 47 return queryForList(Book.class,sql); 48 } 49 }
生成测试(在BookDaoImpl中ctrl+shift+t)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.gychen.test; 2 3 import com.gychen.dao.BookDao; 4 import com.gychen.dao.impl.BookDaoImpl; 5 import com.gychen.pojo.Book; 6 import org.junit.Test; 7 8 import java.math.BigDecimal; 9 10 import static org.junit.Assert.*; 11 12 public class BookDaoImplTest { 13 14 private BookDao bookDao = new BookDaoImpl(); 15 @Test 16 public void addBook() { 17 //中文保存乱码问题,暂没解决 18 bookDao.addBook(new Book(null,"测试01","gychen", 19 new BigDecimal(68),1100,21,null)); 20 } 21 22 @Test 23 public void deleteBookById() { 24 bookDao.deleteBookById(20); 25 } 26 27 @Test 28 public void updateBook() { 29 bookDao.updateBook(new Book(20,"delete","GoingChen", 30 new BigDecimal(100),120,9,null)); 31 } 32 33 @Test 34 public void queryBookById() { 35 System.out.println(bookDao.queryBookById(21)); 36 } 37 38 @Test 39 public void queryBooks() { 40 // System.out.println(bookDao.queryBooks()); 41 //可以简单理解为python中的for( item in iterator ) 42 for(Book queryBook : bookDao.queryBooks()){ 43 System.out.println(queryBook); 44 } 45 } 46 }
后记:从Java中保存中文到数据库乱码问题已解决-->查看
Ⅳ、编写图书模块的Service和测试Service
在com.gychen.service中新建BookService接口类
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.gychen.service; 2 3 import com.gychen.pojo.Book; 4 5 import java.util.List; 6 7 public interface BookService { 8 9 public void addBook(Book book); 10 11 public void deleteBookById(Integer id); 12 13 public void updateBook(Book book); 14 15 public Book querryBookById(Integer id); 16 17 public List<Book> queryBooks(); 18 19 }
在com.gychen.service.impl中新建BookServiceImpl实现类,生成一下实现方法:Implement Methods,并编写逻辑
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.gychen.service.impl; 2 3 import com.gychen.dao.BookDao; 4 import com.gychen.dao.impl.BookDaoImpl; 5 import com.gychen.pojo.Book; 6 import com.gychen.service.BookService; 7 8 import java.util.List; 9 10 public class BookServiceImpl implements BookService { 11 12 private BookDao bookDao = new BookDaoImpl(); 13 14 @Override 15 public void addBook(Book book) { 16 bookDao.addBook(book); 17 } 18 19 @Override 20 public void deleteBookById(Integer id) { 21 22 bookDao.deleteBookById(id); 23 } 24 25 @Override 26 public void updateBook(Book book) { 27 28 bookDao.updateBook(book); 29 } 30 31 @Override 32 public Book querryBookById(Integer id) { 33 34 35 return bookDao.queryBookById(id); 36 } 37 38 @Override 39 public List<Book> queryBooks() { 40 return bookDao.queryBooks(); 41 } 42 }
生成测试(在BookServiceImpl中ctrl+shift+t)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.gychen.test; 2 3 import com.gychen.pojo.Book; 4 import com.gychen.service.BookService; 5 import com.gychen.service.impl.BookServiceImpl; 6 import org.junit.Test; 7 8 import java.math.BigDecimal; 9 10 import static org.junit.Assert.*; 11 12 public class BookServiceImplTest { 13 14 private BookService bookService = new BookServiceImpl(); 15 @Test 16 public void addBook() { 17 18 bookService.addBook(new Book(null,"test","gy", 19 new BigDecimal(12.99),123,32,null)); 20 } 21 22 @Test 23 public void deleteBookById() { 24 bookService.deleteBookById(21); 25 } 26 27 @Test 28 public void updateBook() { 29 bookService.updateBook(new Book(1,"LOL","The Shy", 30 new BigDecimal(24.898),1100,0,null)); 31 } 32 33 @Test 34 public void querryBookById() { 35 System.out.println(bookService.querryBookById(1)); 36 } 37 38 @Test 39 public void queryBooks() { 40 41 for (Book queryBook:bookService.queryBooks()) { 42 System.out.println(queryBook); 43 } 44 } 45 }
Ⅴ、编写图书模块的Web层和页面联调测试
利用路径分类前后台权限
在com.gychen.web里新建BookServlet并配置web.xml
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.gychen.web; 2 3 import com.gychen.pojo.Book; 4 import com.gychen.service.BookService; 5 import com.gychen.service.impl.BookServiceImpl; 6 import com.gychen.utils.WebUtils; 7 8 import javax.servlet.ServletException; 9 import javax.servlet.http.HttpServletRequest; 10 import javax.servlet.http.HttpServletResponse; 11 import java.io.IOException; 12 import java.util.List; 13 14 15 public class BookServlet extends BaseServlet { 16 17 private BookService bookService = new BookServiceImpl(); 18 19 //添加图书数据 20 protected void add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{ 21 22 //1、获取请求参数 23 //使用封装好的bean工具类来注入参数 24 Book book = WebUtils.copyParamToBean(req.getParameterMap(),new Book()); 25 // System.out.println(book); 26 27 //2、插入数据保存到数据库 28 bookService.addBook(book); 29 30 // //3、请求转发,按F5会有重复提交表单的bug,重复执行add请求。建议使用重定向 31 // req.getRequestDispatcher("/manager/bookServlet?action=list").forward(req,resp); 32 33 //3、重定向,属于两次请求。需加工程名,按f5重复执行的请求是查询list 34 resp.sendRedirect(req.getContextPath()+"/manager/bookServlet?action=list"); 35 } 36 37 //删除图书数据 38 protected void delete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{ 39 40 //获取请求参数id,删除,请求转发 41 //=========================================================== 42 // //1、获取请求参数id 43 // String id = req.getParameter("id"); 44 // 45 // //2、删除数据 46 // bookService.deleteBookById(Integer.valueOf(id)); 47 //=========================================================== 48 49 //1、获取请求参数id 50 Integer id = WebUtils.parseInt(req.getParameter("id"),0); 51 52 //2、删除数据 53 bookService.deleteBookById(id); 54 55 56 // //3、请求转发 57 // req.getRequestDispatcher("/manager/bookServlet?action=list").forward(req,resp); 58 59 //3、重定向,属于两次请求。需加工程名,按f5重复执行的请求是查询list 60 resp.sendRedirect(req.getContextPath()+"/manager/bookServlet?action=list"); 61 62 } 63 64 //修改图书数据 65 protected void update(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{ 66 67 //1、获取请求参数 68 //使用封装好的bean工具类来注入参数 69 Book book = WebUtils.copyParamToBean(req.getParameterMap(),new Book()); 70 // 71 //2、更新数据 72 bookService.updateBook(new Book(book.getId(),book.getName(),book.getAuthor(),book.getPrice(), 73 book.getSales(),book.getStock(),book.getImgPath())); 74 // System.out.println(book); 75 //3、请求转发 76 req.getRequestDispatcher("/manager/bookServlet?action=list").forward(req,resp); 77 78 } 79 80 //查询所有图书数据 81 protected void list(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{ 82 83 /* 84 1、通过BookService查询全部数据 85 2、把全部图书保存到Request域中 86 3、请求转发到/pages/manager/book_manager.jsp页面 87 */ 88 89 //1、通过BookService查询全部数据 90 List<Book> books = bookService.queryBooks(); 91 92 //2、把全部图书保存到Request域中 93 req.setAttribute("books",books); 94 95 //3、请求转发到/pages/manager/book_manager.jsp页面 96 req.getRequestDispatcher("/pages/manager/book_manager.jsp").forward(req,resp); 97 98 } 99 100 //查询要修改的图书数据 101 protected void selectModify(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{ 102 103 //1、获取请求参数 104 String id = req.getParameter("id"); 105 // System.out.println(id); 106 //查询数据 107 Book book = bookService.querryBookById(Integer.valueOf(id)); 108 // System.out.println(book); 109 //数据保存到request域中 110 req.setAttribute("selectModify",book); 111 112 //3、请求转发到/pages/manager/book_manager.jsp页面 113 req.getRequestDispatcher("/pages/manager/book_edit.jsp").forward(req,resp); 114 } 115 116 117 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.gychen.web; 2 3 import com.gychen.pojo.Book; 4 import com.gychen.service.BookService; 5 import com.gychen.service.impl.BookServiceImpl; 6 import com.gychen.utils.WebUtils; 7 8 import javax.servlet.ServletException; 9 import javax.servlet.http.HttpServletRequest; 10 import javax.servlet.http.HttpServletResponse; 11 import java.io.IOException; 12 import java.util.List; 13 14 15 public class BookServlet extends BaseServlet { 16 17 private BookService bookService = new BookServiceImpl(); 18 19 //添加图书数据 20 protected void add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{ 21 22 //1、获取请求参数 23 //使用封装好的bean工具类来注入参数 24 Book book = WebUtils.copyParamToBean(req.getParameterMap(),new Book()); 25 // System.out.println(book); 26 27 //2、插入数据保存到数据库 28 bookService.addBook(book); 29 30 //3、请求转发 31 req.getRequestDispatcher("/manager/bookServlet?action=list").forward(req,resp); 32 33 } 34 35 //删除图书数据 36 protected void delete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{ 37 38 //获取请求参数id,删除,请求转发 39 40 //1、获取请求参数id 41 String id = req.getParameter("id"); 42 43 //2、删除数据 44 bookService.deleteBookById(Integer.valueOf(id)); 45 46 //3、请求转发 47 req.getRequestDispatcher("/manager/bookServlet?action=list").forward(req,resp); 48 49 } 50 51 //修改图书数据 52 protected void update(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{ 53 54 //1、获取请求参数 55 //使用封装好的bean工具类来注入参数 56 Book book = WebUtils.copyParamToBean(req.getParameterMap(),new Book()); 57 // 58 //2、更新数据 59 bookService.updateBook(new Book(book.getId(),book.getName(),book.getAuthor(),book.getPrice(), 60 book.getSales(),book.getStock(),book.getImgPath())); 61 // System.out.println(book); 62 //3、请求转发 63 req.getRequestDispatcher("/manager/bookServlet?action=list").forward(req,resp); 64 65 } 66 67 //查询所有图书数据 68 protected void list(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{ 69 70 /* 71 1、通过BookService查询全部数据 72 2、把全部图书保存到Request域中 73 3、请求转发到/pages/manager/book_manager.jsp页面 74 */ 75 76 //1、通过BookService查询全部数据 77 List<Book> books = bookService.queryBooks(); 78 79 //2、把全部图书保存到Request域中 80 req.setAttribute("books",books); 81 82 //3、请求转发到/pages/manager/book_manager.jsp页面 83 req.getRequestDispatcher("/pages/manager/book_manager.jsp").forward(req,resp); 84 85 } 86 87 //查询要修改的图书数据 88 protected void selectModify(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{ 89 90 //1、获取请求参数 91 String id = req.getParameter("id"); 92 // System.out.println(id); 93 //查询数据 94 Book book = bookService.querryBookById(Integer.valueOf(id)); 95 // System.out.println(book); 96 //数据保存到request域中 97 req.setAttribute("selectModify",book); 98 99 //3、请求转发到/pages/manager/book_manager.jsp页面 100 req.getRequestDispatcher("/pages/manager/book_edit.jsp").forward(req,resp); 101 } 102 103 104 }
查、删
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 13 <div id="header"> 14 <img class="logo_img" alt="" src="../../static/img/logo.gif" > 15 <span class="wel_word">图书管理系统</span> 16 <%@include file="/pages/common/manager_menu.jsp"%> 17 </div> 18 19 <div id="main"> 20 <table> 21 <tr> 22 <td>货号</td> 23 <td>名称</td> 24 <td>价格</td> 25 <td>作者</td> 26 <td>销量</td> 27 <td>库存</td> 28 <td colspan="2">操作</td> 29 </tr> 30 31 <c:forEach items="${ requestScope.books }" var="book"> 32 33 <tr> 34 <td>${book.id}</td> 35 <td>${book.name}</td> 36 <td>${book.price}</td> 37 <td>${book.author}</td> 38 <td>${book.sales}</td> 39 <td>${book.stock}</td> 40 <td><a href="manager/bookServlet?action=selectModify&id=${book.id}">修改</a></td> 41 <td><a href="manager/bookServlet?action=delete&id=${book.id}">删除</a></td> 42 </tr> 43 </c:forEach> 44 45 46 <tr> 47 <td></td> 48 <td></td> 49 <td></td> 50 <td></td> 51 <td></td> 52 <td></td> 53 <td><a href="pages/manager/book_add.jsp">添加图书</a></td> 54 </tr> 55 </table> 56 </div> 57 58 <%--静态包含页脚内容--%> 59 <%@include file="/pages/common/footer.jsp"%> 60 </body> 61 </html>
改
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 <%@include file="/pages/common/manager_menu.jsp"%> 29 </div> 30 31 <div id="main"> 32 <form action="manager/bookServlet" method="get"> 33 <table> 34 <tr> 35 <td>名称</td> 36 <td>价格</td> 37 <td>作者</td> 38 <td>销量</td> 39 <td>库存</td> 40 <td colspan="2">操作</td> 41 </tr> 42 <input type="hidden" name="action" value="update" > 43 <input name="id" type="hidden" value="${requestScope.selectModify.id}"/> 44 <tr> 45 <td><input name="name" type="text" value="${requestScope.selectModify.name}"/></td> 46 <td><input name="price" type="text" value="${requestScope.selectModify.price}"/></td> 47 <td><input name="author" type="text" value="${requestScope.selectModify.author}"/></td> 48 <td><input name="sales" type="text" value="${requestScope.selectModify.sales}"/></td> 49 <td><input name="stock" type="text" value="${requestScope.selectModify.stock}"/></td> 50 <td><input type="submit" value="提交"/></td> 51 </tr> 52 </table> 53 </form> 54 55 56 </div> 57 58 <%--静态包含页脚内容--%> 59 <%@include file="/pages/common/footer.jsp"%> 60 </body> 61 </html>
增
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 <%@include file="/pages/common/manager_menu.jsp"%> 29 </div> 30 31 <div id="main"> 32 <form action="manager/bookServlet" method="get"> 33 <table> 34 <tr> 35 <td>名称</td> 36 <td>价格</td> 37 <td>作者</td> 38 <td>销量</td> 39 <td>库存</td> 40 <td colspan="2">操作</td> 41 </tr> 42 <input type="hidden" name="action" value="add" > 43 44 <tr> 45 <td><input name="name" type="text" value="" placeholder="name"/></td> 46 <td><input name="price" type="text" value="" placeholder="price"/></td> 47 <td><input name="author" type="text" value="" placeholder="author"/></td> 48 <td><input name="sales" type="text" value="" placeholder="sales"/></td> 49 <td><input name="stock" type="text" value="" placeholder="stock"/></td> 50 <td><input type="submit" value="提交"/></td> 51 </tr> 52 </table> 53 </form> 54 55 56 </div> 57 58 <%--静态包含页脚内容--%> 59 <%@include file="/pages/common/footer.jsp"%> 60 </body> 61 </html>
三、分页功能
Ⅰ、编写分页模块的JavaBean
在com.gychen.pojo里新建Page.java
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.gychen.pojo; 2 3 import java.util.List; 4 5 /** 6 * Page是分页的模型对象 7 * @param <T> 泛型是具体的模块的JavaBean类 8 */ 9 public class Page<T> { 10 11 private static final Integer PAGE_SIZE = 4; 12 //当前页码 13 private Integer pageNo; 14 //总页码 15 private Integer pageTotal; 16 //当前页显示数量 17 private Integer pageSize = PAGE_SIZE; 18 //总记录数 19 private Integer pageTotalCount; 20 //当前页数据 21 private List<T> items; 22 23 24 25 //生成get和set方法 26 public static Integer getPageSize() { 27 return PAGE_SIZE; 28 } 29 30 public void setPageSize(Integer pageSize) { 31 this.pageSize = pageSize; 32 } 33 34 public Integer getPageTotalCount() { 35 return pageTotalCount; 36 } 37 38 public void setPageTotalCount(Integer pageTotalCount) { 39 this.pageTotalCount = pageTotalCount; 40 } 41 42 public List<T> getItems() { 43 return items; 44 } 45 46 public void setItems(List<T> items) { 47 this.items = items; 48 } 49 50 public Integer getPageNo() { 51 return pageNo; 52 } 53 54 public void setPageNo(Integer pageNo) { 55 this.pageNo = pageNo; 56 } 57 58 public Integer getPageTotal() { 59 return pageTotal; 60 } 61 62 public void setPageTotal(Integer pageTotal) { 63 this.pageTotal = pageTotal; 64 } 65 66 67 68 //生成toString 69 70 @Override 71 public String toString() { 72 return "Page{" + 73 "pageNo=" + pageNo + 74 ", pageTotal=" + pageTotal + 75 ", pageSize=" + pageSize + 76 ", pageTotalCount=" + pageTotalCount + 77 ", items=" + items + 78 '}'; 79 } 80 81 //生成有参和无参构造函数,在这个功能里其实暂时用不上 82 83 public Page(Integer pageNo, Integer pageTotal, Integer pageSize, Integer pageTotalCount, List<T> items) { 84 this.pageNo = pageNo; 85 this.pageTotal = pageTotal; 86 this.pageSize = pageSize; 87 this.pageTotalCount = pageTotalCount; 88 this.items = items; 89 } 90 91 public Page() { 92 } 93 }
在com.gychen.web.BookServlet里新增page方法处理分页功能
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.gychen.web; 2 3 import com.gychen.pojo.Book; 4 import com.gychen.pojo.Page; 5 import com.gychen.service.BookService; 6 import com.gychen.service.impl.BookServiceImpl; 7 import com.gychen.utils.WebUtils; 8 9 import javax.servlet.ServletException; 10 import javax.servlet.http.HttpServletRequest; 11 import javax.servlet.http.HttpServletResponse; 12 import java.io.IOException; 13 import java.util.List; 14 15 16 public class BookServlet extends BaseServlet { 17 18 private BookService bookService = new BookServiceImpl(); 19 20 /** 21 * 添加图书数据 22 */ 23 protected void add(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{ 24 25 //1、获取请求参数 26 String pageNo = req.getParameter("pageNo"); 27 //使用封装好的bean工具类来注入参数 28 Book book = WebUtils.copyParamToBean(req.getParameterMap(),new Book()); 29 // System.out.println(book); 30 31 //2、插入数据保存到数据库 32 bookService.addBook(book); 33 34 // //3、请求转发,按F5会有重复提交表单的bug,重复执行add请求。建议使用重定向 35 // req.getRequestDispatcher("/manager/bookServlet?action=list").forward(req,resp); 36 37 //3、重定向,属于两次请求。需加工程名,按f5重复执行的请求是查询list 38 resp.sendRedirect(req.getContextPath()+"/manager/bookServlet?action=page&pageNo="+pageNo); 39 } 40 41 /** 42 * 删除图书数据,重定向 43 */ 44 protected void delete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{ 45 46 //获取请求参数id,删除,请求转发 47 //=========================================================== 48 // //1、获取请求参数id 49 // String id = req.getParameter("id"); 50 // 51 // //2、删除数据 52 // bookService.deleteBookById(Integer.valueOf(id)); 53 //=========================================================== 54 55 //1、获取请求参数id 56 Integer id = WebUtils.parseInt(req.getParameter("id"),0); 57 //接受这个页码参数是为了记住页码,做删除操作后前端仍渲染该页 58 String pageNo = req.getParameter("pageNo"); 59 //2、删除数据 60 bookService.deleteBookById(id); 61 62 // //3、请求转发 63 // req.getRequestDispatcher("/manager/bookServlet?action=list").forward(req,resp); 64 65 //3、重定向,属于两次请求。需加工程名,按f5重复执行的请求是查询list 66 //由于重定向,不可用请求域传参,用此方法传给page()的pageNo 67 resp.sendRedirect(req.getContextPath()+"/manager/bookServlet?action=page&pageNo="+pageNo); 68 69 } 70 71 /** 72 * 修改图书数据 73 */ 74 protected void update(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{ 75 76 //1、获取请求参数 77 /*此前,前端修改页面book_edit.jsp向update传了一个pageNo参数, 78 在此可不用接收,因为下面是请求转发,属于一次请求,故在page()里再接收*/ 79 //使用封装好的bean工具类来注入参数 80 Book book = WebUtils.copyParamToBean(req.getParameterMap(),new Book()); 81 // 82 //2、更新数据 83 bookService.updateBook(new Book(book.getId(),book.getName(),book.getAuthor(),book.getPrice(), 84 book.getSales(),book.getStock(),book.getImgPath())); 85 // System.out.println(book); 86 //3、请求转发 87 req.getRequestDispatcher("/manager/bookServlet?action=page").forward(req,resp); 88 89 } 90 91 /** 92 * 查询所有图书数据 93 */ 94 protected void list(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{ 95 96 /* 97 1、通过BookService查询全部数据 98 2、把全部图书保存到Request域中 99 3、请求转发到/pages/manager/book_manager.jsp页面 100 */ 101 102 //1、通过BookService查询全部数据 103 List<Book> books = bookService.queryBooks(); 104 105 //2、把全部图书保存到Request域中 106 req.setAttribute("books",books); 107 108 //3、请求转发到/pages/manager/book_manager.jsp页面 109 req.getRequestDispatcher("/pages/manager/book_manager.jsp").forward(req,resp); 110 111 } 112 113 /** 114 * 查询要修改的图书数据 115 */ 116 protected void selectModify(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{ 117 118 //1、获取请求参数 119 String pageNo = req.getParameter("pageNo"); 120 String id = req.getParameter("id"); 121 // System.out.println(id); 122 //查询数据 123 Book book = bookService.querryBookById(Integer.valueOf(id)); 124 // System.out.println(book); 125 //数据保存到request域中 126 req.setAttribute("selectModify",book); 127 req.setAttribute("pageNo",pageNo); 128 129 //3、请求转发到/pages/manager/book_manager.jsp页面 130 req.getRequestDispatcher("/pages/manager/book_edit.jsp").forward(req,resp); 131 } 132 133 /** 134 * 处理分页功能,返回分页后的数据 135 */ 136 protected void page(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{ 137 138 //1、获取请求参数,pageNo(当前页码)和pageSize(当前页显示数量) 139 //使用封装好的bean工具类来注入参数 140 int pageNo = WebUtils.parseInt(req.getParameter("pageNo"),1); 141 int pageSize = WebUtils.parseInt(req.getParameter("pageSize"), Page.PAGE_SIZE); 142 // System.out.println(book); 143 144 //2、调用BookService.page(pageNo,pageSize):Page对象 145 Page<Book> page = bookService.page(pageNo,pageSize); 146 147 //3、保存Page对象到Request域中 148 req.setAttribute("page",page); 149 //4、请求转发到pages/manager/book_manager.jsp页面 150 req.getRequestDispatcher("/pages/manager/book_manager.jsp").forward(req,resp); 151 152 } 153 154 }
到com.gychen.service.bookService.java中新增page()接口
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.gychen.service; 2 3 import com.gychen.pojo.Book; 4 import com.gychen.pojo.Page; 5 6 import java.util.List; 7 8 public interface BookService { 9 10 /** 11 * 添加图书 12 */ 13 public void addBook(Book book); 14 15 /** 16 * 通过id删除图书 17 * @param id 图书id 18 */ 19 public void deleteBookById(Integer id); 20 21 /** 22 * 修改图书 23 */ 24 public void updateBook(Book book); 25 26 /** 27 * 通过id查询图书 28 * @param id 图书id 29 */ 30 public Book querryBookById(Integer id); 31 32 /** 33 * 查询所有图书 34 */ 35 public List<Book> queryBooks(); 36 37 /** 38 * 查询分页的信息 39 * @param pageNo 当前页码 40 * @param pageSize 当前页显示数量 41 */ 42 Page<Book> page(int pageNo, int pageSize); 43 44 }
到com.gychen.service.impl.BookServiceImpl.java中新建page()实现方法
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.gychen.service.impl; 2 3 import com.gychen.dao.BookDao; 4 import com.gychen.dao.impl.BookDaoImpl; 5 import com.gychen.pojo.Book; 6 import com.gychen.pojo.Page; 7 import com.gychen.service.BookService; 8 9 import java.util.List; 10 11 public class BookServiceImpl implements BookService { 12 13 private BookDao bookDao = new BookDaoImpl(); 14 15 /** 16 * 调用Dao添加数据到数据库中 17 */ 18 @Override 19 public void addBook(Book book) { 20 bookDao.addBook(book); 21 } 22 23 /** 24 * 调用Dao通过id删除数据 25 * @param id 图书id 26 */ 27 @Override 28 public void deleteBookById(Integer id) { 29 30 bookDao.deleteBookById(id); 31 } 32 33 /** 34 * 调用Dao修改数据 35 */ 36 @Override 37 public void updateBook(Book book) { 38 39 bookDao.updateBook(book); 40 } 41 42 /** 43 * 调用Dao通过id查询数据 44 * @param id 图书id 45 */ 46 @Override 47 public Book querryBookById(Integer id) { 48 49 50 return bookDao.queryBookById(id); 51 } 52 53 /** 54 * 调用Dao执行查询所有数据 55 */ 56 @Override 57 public List<Book> queryBooks() { 58 return bookDao.queryBooks(); 59 } 60 61 /** 62 * 63 * @param pageNo 当前页码 64 * @param pageSize 当前页显示数量 65 * @return 66 */ 67 @Override 68 public Page<Book> page(int pageNo, int pageSize) { 69 Page<Book> page = new Page<Book>(); 70 //设置当前页码 71 page.setPageNo(pageNo); 72 //设置每页显示的数量 73 page.setPageSize(pageSize); 74 //计算总的记录数 75 Integer pageTotalCount = bookDao.queryForPageTotalCount(); 76 //设置总记录数 77 page.setPageTotalCount(pageTotalCount); 78 //计算总页码 79 int pageTotal = pageTotalCount / pageSize; 80 //判断最后一页不满的情况 81 if(pageTotalCount % pageSize > 0){ 82 pageTotal += 1; 83 } 84 //设置总页码 85 page.setPageTotal(pageTotal); 86 //计算当前页数据,begin为当前页首条记录的索引 87 int begin = (page.getPageNo() -1) * pageSize; 88 List<Book> items = bookDao.queryForPageItems(begin,pageSize); 89 //设置当前页数据 90 page.setItems(items); 91 return page; 92 } 93 }
到com.gychen.dao.BookDao.java里新增查询接口
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.gychen.service.impl; 2 3 import com.gychen.dao.BookDao; 4 import com.gychen.dao.impl.BookDaoImpl; 5 import com.gychen.pojo.Book; 6 import com.gychen.pojo.Page; 7 import com.gychen.service.BookService; 8 9 import java.util.List; 10 11 public class BookServiceImpl implements BookService { 12 13 private BookDao bookDao = new BookDaoImpl(); 14 15 /** 16 * 调用Dao添加数据到数据库中 17 */ 18 @Override 19 public void addBook(Book book) { 20 bookDao.addBook(book); 21 } 22 23 /** 24 * 调用Dao通过id删除数据 25 * @param id 图书id 26 */ 27 @Override 28 public void deleteBookById(Integer id) { 29 30 bookDao.deleteBookById(id); 31 } 32 33 /** 34 * 调用Dao修改数据 35 */ 36 @Override 37 public void updateBook(Book book) { 38 39 bookDao.updateBook(book); 40 } 41 42 /** 43 * 调用Dao通过id查询数据 44 * @param id 图书id 45 */ 46 @Override 47 public Book querryBookById(Integer id) { 48 49 50 return bookDao.queryBookById(id); 51 } 52 53 /** 54 * 调用Dao执行查询所有数据 55 */ 56 @Override 57 public List<Book> queryBooks() { 58 return bookDao.queryBooks(); 59 } 60 61 /** 62 * 63 * @param pageNo 当前页码 64 * @param pageSize 当前页显示数量 65 * @return 66 */ 67 @Override 68 public Page<Book> page(int pageNo, int pageSize) { 69 Page<Book> page = new Page<Book>(); 70 //设置当前页码 71 page.setPageNo(pageNo); 72 //设置每页显示的数量 73 page.setPageSize(pageSize); 74 //计算总的记录数 75 Integer pageTotalCount = bookDao.queryForPageTotalCount(); 76 //设置总记录数 77 page.setPageTotalCount(pageTotalCount); 78 //计算总页码 79 int pageTotal = pageTotalCount / pageSize; 80 //判断最后一页不满的情况 81 if(pageTotalCount % pageSize > 0){ 82 pageTotal += 1; 83 } 84 //设置总页码 85 page.setPageTotal(pageTotal); 86 //计算当前页数据,begin为当前页首条记录的索引 87 int begin = (page.getPageNo() -1) * pageSize; 88 List<Book> items = bookDao.queryForPageItems(begin,pageSize); 89 //设置当前页数据 90 page.setItems(items); 91 return page; 92 } 93 }
到com.gychen.dao.impl.BookDaoImpl.java中实现数据库的查询
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.gychen.dao.impl; 2 3 import com.gychen.dao.BookDao; 4 import com.gychen.pojo.Book; 5 6 import java.util.List; 7 8 public class BookDaoImpl extends BaseDao implements BookDao { 9 10 //生成一下实现方法:Implement Methods,并编写sql语句 11 @Override 12 public int addBook(Book book) { 13 14 String sql = "insert into t_book(`name`,`author`,`price`,`sales`,`stock`,`img_path`) " + 15 "values(?,?,?,?,?,?)"; 16 return update(sql,book.getName(),book.getAuthor(),book.getPrice(), 17 book.getSales(),book.getStock(),book.getImgPath()); 18 } 19 20 @Override 21 public int deleteBookById(Integer id) { 22 23 String sql = "delete from t_book where id = ?"; 24 return update(sql,id); 25 } 26 27 @Override 28 public int updateBook(Book book) { 29 30 String sql = "update t_book set `name`=?,`author`=?,`price`=?,`sales`=?," + 31 "`stock`=?,`img_path`=? where id=?"; 32 return update(sql,book.getName(),book.getAuthor(),book.getPrice(), 33 book.getSales(),book.getStock(),book.getImgPath(),book.getId()); 34 } 35 36 @Override 37 public Book queryBookById(Integer id) { 38 //其中imgPath是别名 39 String sql = "select `id`, `name`,`author`,`price`,`sales`,`stock`," + 40 "`img_path` imgPath from t_book where id=?"; 41 return (Book) queryForOne(Book.class,sql,id); 42 } 43 44 @Override 45 public List<Book> queryBooks() { 46 47 //其中imgPath是别名 48 String sql = "select `id`, `name`,`author`,`price`,`sales`,`stock`," + 49 "`img_path` imgPath from t_book"; 50 return queryForList(Book.class,sql); 51 } 52 53 @Override 54 public Integer queryForPageTotalCount() { 55 String sql = "select count(*) from t_book"; 56 Number count = (Number) queryForSingleValue(sql); 57 return count.intValue(); 58 } 59 60 @Override 61 public List<Book> queryForPageItems(int begin, int pageSize) { 62 String sql = "select `id`, `name`,`author`,`price`,`sales`,`stock`," + 63 "`img_path` imgPath from t_book limit ?,?"; 64 return queryForList(Book.class,sql,begin,pageSize); 65 } 66 }
到com.gychen.test里写Dao测试和Service测试
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.gychen.test; 2 3 import com.gychen.dao.BookDao; 4 import com.gychen.dao.impl.BookDaoImpl; 5 import com.gychen.pojo.Book; 6 import org.junit.Test; 7 8 import java.math.BigDecimal; 9 import java.util.List; 10 11 import static org.junit.Assert.*; 12 13 public class BookDaoImplTest { 14 15 private BookDao bookDao = new BookDaoImpl(); 16 @Test 17 public void addBook() { 18 //中文保存乱码问题,暂没解决=====>已解决,数据库JDBC配置源添加utf8字符编码就行 19 bookDao.addBook(new Book(null,"测试01","gychen", 20 new BigDecimal(68),1100,21,null)); 21 } 22 23 @Test 24 public void deleteBookById() { 25 bookDao.deleteBookById(20); 26 } 27 28 @Test 29 public void updateBook() { 30 bookDao.updateBook(new Book(20,"delete","GoingChen", 31 new BigDecimal(100),120,9,null)); 32 } 33 34 @Test 35 public void queryBookById() { 36 System.out.println(bookDao.queryBookById(21)); 37 } 38 39 @Test 40 public void queryBooks() { 41 // System.out.println(bookDao.queryBooks()); 42 //可以简单理解为python中的for( item in iterator ) 43 for(Book queryBook : bookDao.queryBooks()){ 44 System.out.println(queryBook); 45 } 46 } 47 48 49 @Test 50 public void queryForPageTotalCount() { 51 52 System.out.println(bookDao.queryForPageTotalCount()); 53 } 54 55 @Test 56 public void queryForPageItems() { 57 58 List<Book> items = bookDao.queryForPageItems(1,5); 59 for (Book item : items) { 60 System.out.println(item); 61 } 62 } 63 }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.gychen.test; 2 3 import com.gychen.pojo.Book; 4 import com.gychen.pojo.Page; 5 import com.gychen.service.BookService; 6 import com.gychen.service.impl.BookServiceImpl; 7 import com.gychen.web.BookServlet; 8 import org.junit.Test; 9 10 import java.math.BigDecimal; 11 import java.util.List; 12 13 import static org.junit.Assert.*; 14 15 public class BookServiceImplTest { 16 17 private BookService bookService = new BookServiceImpl(); 18 @Test 19 public void addBook() { 20 21 bookService.addBook(new Book(null,"Q都会Q歪来","包桑", 22 new BigDecimal(12.99),123,32,null)); 23 } 24 25 @Test 26 public void deleteBookById() { 27 bookService.deleteBookById(21); 28 } 29 30 @Test 31 public void updateBook() { 32 bookService.updateBook(new Book(1,"LOL","The Shy", 33 new BigDecimal(24.898),1100,0,null)); 34 } 35 36 @Test 37 public void querryBookById() { 38 System.out.println(bookService.querryBookById(1)); 39 } 40 41 @Test 42 public void queryBooks() { 43 44 for (Book queryBook: bookService.queryBooks()) { 45 System.out.println(queryBook); 46 } 47 48 } 49 50 @Test 51 public void page(){ 52 Page<Book> list = bookService.page(1,Page.PAGE_SIZE); 53 for (Book item : list.getItems()) { 54 System.out.println(item); 55 } 56 57 } 58 }
最后在前端界面写好参数和传递方式
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <%@ page contentType="text/html;charset=UTF-8" language="java" %> 2 <div> 3 <a href="manager/bookServlet?action=page">图书管理</a> 4 <a href="pages/manager/order_manager.jsp">订单管理</a> 5 <a href="index.jsp">返回商城</a> 6 </div>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 <script> 12 $(function(){ 13 //确认删除操作 14 $("a.deleteClass").click(function () { 15 /** 16 * confirm 是确认提示框函数 17 * 参数是提示内容 18 * 两个按钮:确认和取消 19 * 返回true表示确认,false表示取消 20 */ 21 return confirm("是否删除【"+$(this).parent().parent().find("td:nth-child(2)").text()+"】?"); 22 }) 23 }) 24 </script> 25 <body> 26 27 <div id="header"> 28 <img class="logo_img" alt="" src="../../static/img/logo.gif" > 29 <span class="wel_word">图书管理系统</span> 30 <%@include file="/pages/common/manager_menu.jsp"%> 31 </div> 32 33 <div id="main"> 34 <table> 35 <tr> 36 <td>货号</td> 37 <td>名称</td> 38 <td>价格</td> 39 <td>作者</td> 40 <td>销量</td> 41 <td>库存</td> 42 <td colspan="2">操作</td> 43 </tr> 44 45 <c:forEach items="${ requestScope.page.items }" var="book"> 46 47 <tr> 48 <td>${book.id}</td> 49 <td>${book.name}</td> 50 <td>${book.price}</td> 51 <td>${book.author}</td> 52 <td>${book.sales}</td> 53 <td>${book.stock}</td> 54 <td><a href="manager/bookServlet?action=selectModify&id=${book.id}&pageNo=${requestScope.page.pageNo}">修改</a></td> 55 <td><a class="deleteClass" href="manager/bookServlet?action=delete&id=${book.id}&pageNo=${requestScope.page.pageNo}">删除</a></td> 56 </tr> 57 </c:forEach> 58 59 60 <tr> 61 <td></td> 62 <td></td> 63 <td></td> 64 <td></td> 65 <td></td> 66 <td></td> 67 <%--传总记录数和最后一页页数,为了计算添加功能时是否会跳到新的一页--%> 68 <td><a href="pages/manager/book_add.jsp?pageTotalCount=${requestScope.page.pageTotalCount}&pageNo=${requestScope.page.pageTotal}">添加图书</a></td> 69 </tr> 70 </table> 71 72 <div id="page_nav"> 73 <a href="manager/bookServlet?action=page">首页</a> 74 <a href="manager/bookServlet?action=page&pageNo=${requestScope.page.pageNo-1}"> 75 ${requestScope.page.pageNo < 2?"":"上一页"} 76 </a> 77 <a href="manager/bookServlet?action=page&pageNo=${requestScope.page.pageNo-1}"> 78 ${requestScope.page.pageNo < 2?"":requestScope.page.pageNo-1} 79 </a> 80 <%--当前页码--%> 81 【${ requestScope.page.pageNo }】 82 <a href="manager/bookServlet?action=page&pageNo=${requestScope.page.pageNo+1}"> 83 ${requestScope.page.pageNo+1 > requestScope.page.pageTotal?"":requestScope.page.pageNo+1} 84 </a> 85 <a href="manager/bookServlet?action=page&pageNo=${requestScope.page.pageNo+1}"> 86 ${requestScope.page.pageNo+1 > requestScope.page.pageTotal?"":"下一页"} 87 </a> 88 <a href="manager/bookServlet?action=page&pageNo=${requestScope.page.pageTotal}">末页</a> 89 90 共${ requestScope.page.pageTotal }页,${ requestScope.page.pageTotalCount }条记录 到第 91 <input value="${requestScope.page.pageNo}" name="pn" id="pn_input"/>页 92 <input type="button" value="确定"> 93 </div> 94 </div> 95 96 <%--静态包含页脚内容--%> 97 <%@include file="/pages/common/footer.jsp"%> 98 </body> 99 </html>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 <%@include file="/pages/common/manager_menu.jsp"%> 29 </div> 30 31 <div id="main"> 32 <form action="manager/bookServlet" method="get"> 33 <table> 34 <tr> 35 <td>名称</td> 36 <td>价格</td> 37 <td>作者</td> 38 <td>销量</td> 39 <td>库存</td> 40 <td colspan="2">操作</td> 41 42 </tr> 43 <input type="hidden" name="action" value="update" > 44 <input name="id" type="hidden" value="${requestScope.selectModify.id}"/> 45 <input name="pageNo" type="hidden" value="${requestScope.pageNo}"/> 46 <tr> 47 <td><input name="name" type="text" value="${requestScope.selectModify.name}"/></td> 48 <td><input name="price" type="text" value="${requestScope.selectModify.price}"/></td> 49 <td><input name="author" type="text" value="${requestScope.selectModify.author}"/></td> 50 <td><input name="sales" type="text" value="${requestScope.selectModify.sales}"/></td> 51 <td><input name="stock" type="text" value="${requestScope.selectModify.stock}"/></td> 52 <td><input type="submit" value="提交"/></td> 53 </tr> 54 </table> 55 </form> 56 57 58 </div> 59 60 <%--静态包含页脚内容--%> 61 <%@include file="/pages/common/footer.jsp"%> 62 </body> 63 </html>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 <%@include file="/pages/common/manager_menu.jsp"%> 29 </div> 30 31 <div id="main"> 32 <form action="manager/bookServlet" method="get"> 33 <table> 34 <tr> 35 <td>名称</td> 36 <td>价格</td> 37 <td>作者</td> 38 <td>销量</td> 39 <td>库存</td> 40 <td colspan="2">操作</td> 41 </tr> 42 <input type="hidden" name="action" value="add" > 43 <%--接收总记录数和总页数,为了计算添加功能时是否会跳到新的一页--%> 44 <input name="pageNo" type="hidden" value="${param.pageTotalCount%4==0 45 ?param.pageNo+1:param.pageNo}"/> 46 47 <tr> 48 <td><input name="name" type="text" value="" /></td> 49 <td><input name="price" type="text" value="" /></td> 50 <td><input name="author" type="text" value="" /></td> 51 <td><input name="sales" type="text" value="" /></td> 52 <td><input name="stock" type="text" value="" /></td> 53 <td><input type="submit" value="提交"/></td> 54 </tr> 55 </table> 56 </form> 57 58 59 </div> 60 61 <%--静态包含页脚内容--%> 62 <%@include file="/pages/common/footer.jsp"%> 63 </body> 64 </html>
3、首页分页查询
Ⅰ、在com.gychen.web里新建ClientBookServlet.java并配置xml
//首页分页查询
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 package com.gychen.web; 2 3 import com.gychen.pojo.Book; 4 import com.gychen.pojo.Page; 5 import com.gychen.service.BookService; 6 import com.gychen.service.impl.BookServiceImpl; 7 import com.gychen.utils.WebUtils; 8 9 import javax.servlet.ServletException; 10 import javax.servlet.http.HttpServletRequest; 11 import javax.servlet.http.HttpServletResponse; 12 import java.io.IOException; 13 14 public class ClientBookServlet extends BaseServlet { 15 16 private BookService bookService = new BookServiceImpl(); 17 18 /** 19 * 处理分页功能,返回分页后的数据 20 */ 21 protected void page(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 22 System.out.println("ax"); 23 //1、获取请求参数,pageNo(当前页码)和pageSize(当前页显示数量) 24 //使用封装好的bean工具类来注入参数 25 int pageNo = WebUtils.parseInt(req.getParameter("pageNo"),1); 26 int pageSize = WebUtils.parseInt(req.getParameter("pageSize"), Page.PAGE_SIZE); 27 // System.out.println(book); 28 29 //2、调用BookService.page(pageNo,pageSize):Page对象 30 Page<Book> page = bookService.page(pageNo,pageSize); 31 32 //3、保存Page对象到Request域中 33 req.setAttribute("page",page); 34 //4、请求转发页面 35 req.getRequestDispatcher("/pages/client/index.jsp").forward(req,resp); 36 37 } 38 }
Ⅱ、在web/pages里新建client/index.jsp
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 2 <%-- 3 Created by IntelliJ IDEA. 4 User: 99622 5 Date: 2020/3/30 6 Time: 20:18 7 To change this template use File | Settings | File Templates. 8 --%> 9 <%@ page 10 contentType="text/html;charset=UTF-8" 11 language="java" 12 errorPage="/error500.jsp" 13 autoFlush="true" 14 buffer="8kb" 15 %> 16 <!-- 17 errorPage表示错误后自动跳转到error500.jsp 18 --> 19 <!DOCTYPE html> 20 <html> 21 <head> 22 <meta charset="UTF-8"> 23 <title>书城首页</title> 24 25 <%-- 静态包含 base标签、css样式、jQuery文件 --%> 26 <%@ include file="/pages/common/head.jsp"%> 27 28 29 </head> 30 <body> 31 32 <div id="header"> 33 <img class="logo_img" alt="" src="static/img/logo.gif" > 34 <span class="wel_word">网上书城</span> 35 <div> 36 <a href="pages/user/login.jsp">登录</a> | 37 <a href="pages/user/regist.jsp">注册</a> 38 <a href="pages/cart/cart.jsp">购物车</a> 39 <a href="pages/manager/manager.jsp">后台管理</a> 40 </div> 41 </div> 42 43 <div id="main"> 44 <div id="book"> 45 <div class="book_cond"> 46 <form action="" method="get"> 47 价格:<input id="min" type="text" name="min" value=""> 元 - 48 <input id="max" type="text" name="max" value=""> 元 49 <input type="submit" value="查询" /> 50 </form> 51 </div> 52 <div style="text-align: center"> 53 <span>您的购物车中有3件商品</span> 54 <div> 55 您刚刚将<span style="color: red">时间简史</span>加入到了购物车中 56 </div> 57 </div> 58 <c:forEach items="${requestScope.page.items}" var="book"> 59 <div class="b_list"> 60 <div class="img_div"> 61 <img class="book_img" alt="" src="static/img/default.jpg" /> 62 </div> 63 <div class="book_info"> 64 <div class="book_name"> 65 <span class="sp1">书名:</span> 66 <span class="sp2">${book.name}</span> 67 </div> 68 <div class="book_author"> 69 <span class="sp1">作者:</span> 70 <span class="sp2">${book.author}</span> 71 </div> 72 <div class="book_price"> 73 <span class="sp1">价格:</span> 74 <span class="sp2">¥${book.price}</span> 75 </div> 76 <div class="book_sales"> 77 <span class="sp1">销量:</span> 78 <span class="sp2">${book.sales}</span> 79 </div> 80 <div class="book_amount"> 81 <span class="sp1">库存:</span> 82 <span class="sp2">${book.stock}</span> 83 </div> 84 <div class="book_add"> 85 <button>加入购物车</button> 86 </div> 87 </div> 88 </div> 89 </c:forEach> 90 91 </div> 92 93 <div id="page_nav"> 94 <%--大于1才显示首页--%> 95 <c:if test="${requestScope.page.pageNo > 1}"> 96 <a href="client/clientbookServlet?action=page">首页</a> 97 <a href="client/clientbookServlet?action=page&pageNo=${requestScope.page.pageNo-1}"> 98 上一页 99 </a> 100 <a href="client/clientbookServlet?action=page&pageNo=${requestScope.page.pageNo-1}"> 101 ${requestScope.page.pageNo-1} 102 </a> 103 </c:if> 104 105 <%--当前页码--%> 106 【${ requestScope.page.pageNo }】 107 108 <%--小于末页才显示末页--%> 109 <c:if test="${requestScope.page.pageNo < requestScope.page.pageTotal}"> 110 <a href="client/clientbookServlet?action=page&pageNo=${requestScope.page.pageNo+1}"> 111 ${requestScope.page.pageNo+1} 112 </a> 113 <a href="client/clientbookServlet?action=page&pageNo=${requestScope.page.pageNo+1}"> 114 下一页 115 </a> 116 <a href="client/clientbookServlet?action=page&pageNo=${requestScope.page.pageTotal}">末页</a> 117 </c:if> 118 119 120 共${ requestScope.page.pageTotal }页,${ requestScope.page.pageTotalCount }条记录 到第 121 <input value="${requestScope.page.pageNo}" name="pn" id="pn_input"/>页 122 <input id="searchPageBtn" type="button" value="确定"> 123 </div> 124 125 </div> 126 127 <%--静态包含页脚内容--%> 128 <%@include file="/pages/common/footer.jsp"%> 129 <script> 130 $(function () { 131 $("#searchPageBtn").click(function () { 132 //获取要跳转的页面页码 133 var pageNo = $("#pn_input").val(); 134 //location的href属性是地址栏的路由,执行请求转发 135 location.href="${pageScope.basePath}client/clientbookServlet?action=page&pageNo="+pageNo; 136 }); 137 }); 138 </script> 139 </body> 140 </html>
Ⅲ、修改首页index.jsp,功能仅为请求转发
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <%@ page 2 contentType="text/html;charset=UTF-8" 3 language="java" 4 errorPage="/error500.jsp" 5 autoFlush="true" 6 buffer="8kb" 7 %> 8 <%-- 9 errorPage表示错误后自动跳转到error500.jsp 10 --%> 11 12 <%--只负责请求转发--%> 13 <jsp:forward page="/client/clientbookServlet?action=page"></jsp:forward>