1. 数据库设计 1.1 数据库设计范式 什么叫数据库设计范式?
范式:规范的形式,应用于各个行业的标准化
数据库设计中有5种范式,但是常用的分别是:第一范式(1NF),第二范式(2NF),第三范式(3NF)
第一范式(1NF) :针对数据表中的列,列要具备原子性,不可再拆分
如果数据表这样设计,籍贯这一列不具备原子性,因为数据可再次拆分,不拆分的话无法获取用户的州郡信息或县市信息,拆分之后如下:
第二范式(2NF) :数据表要具备唯一主键,不存在多主键,使得每一行数据具有唯一性
在如图所示的表中:没有哪一个字段(列)能唯一确定一条数据,要想唯一确定一条数据,需要两个或更多的字段,这就违反了第二范式,数据表不具备唯一主键而存在多主键。
那如何来解决呢?在表中加一个唯一主键列:id
第三范式(3NF) :不依赖非主键的字段及更深层次的依赖,使得每个字段都独立依赖于主键字段(独立性)
什么叫依赖:依赖,就是在一个表中,其中某个字段的值B可以由另一个字段值A来决定,那我们称字段B依赖字段A或字段A决定字段B
在如图所示的表结构中:合计列=单价 X 数量,当然这中间还需要依赖商品编号来查询商品单价
总而言之,合计这一列,依赖了表中的非主键字段,以及非主键字段的更深层次的依赖,这表明合计这一列的数据是冗余的,因为我们完全可以通过计算的方式得到合计数据,而不需要在表中来存储。
反三范式 :允许少量的数据冗余,提高查询的速度
1.2 数据库设计工具 PowerDesigner:简称PD,是一款功能强大的建模软件,提供强大的元数据管理功能,可以帮助用户构建关键信息的全方位视图,创建多种类型的模型,包括概念数据模型,物理数据模型,面向对象模型等等,同时集成了数据管理,BI,数据集成和数据整合多种功能。
2. 学科模块快速开发 下面我们进行学科模块的快速开发:
(1)创建学科实体:com.itheima.domain.store.Course
1 2 3 4 5 6 7 8 9 public class Course { private String id; private String name; private String remark; private String state; private Date createTime; }
(2)创建dao接口:com.itheima.dao.store.CourseDao
1 2 3 4 5 6 7 8 9 10 11 public interface CourseDao { int save (Course course) ; int delete (Course course) ; int update (Course course) ; Course findById (String id) ; List<Course> findAll () ; }
(3)从今日课程资料中找到dao层资源文件\CourseDao.xml
,拷贝到项目src/main/resources/com/itheima/dao/store/
下
当然这个地方可以将该目录下的所有映射配置文件都拷贝到该目录下,在做后续业务时就无需在拷贝了。
(4)创建业务层接口:com.itheima.service.store.CourseService
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 public interface CourseService { void save (Course course) ; void delete (Course course) ; void update (Course course) ; Course findById (String id) ; List<Course> findAll () ; PageInfo findAll (int page, int size) ; }
(5)创建业务层实现类:com.itheima.service.store.impl.CourseServiceImpl
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 public class CourseServiceImpl implements CourseService { @Override public void save (Course course) { SqlSession sqlSession = null ; try { sqlSession = MapperFactory.getSqlSession(); CourseDao courseDao = MapperFactory.getMapper(sqlSession,CourseDao.class ) ; String id = UUID.randomUUID().toString(); course.setId(id); courseDao.save(course); TransactionUtil.commit(sqlSession); }catch (Exception e){ TransactionUtil.rollback(sqlSession); throw new RuntimeException(e); }finally { try { TransactionUtil.close(sqlSession); }catch (Exception e){ e.printStackTrace(); } } } @Override public void delete (Course course) { SqlSession sqlSession = null ; try { sqlSession = MapperFactory.getSqlSession(); CourseDao courseDao = MapperFactory.getMapper(sqlSession,CourseDao.class ) ; courseDao.delete(course); TransactionUtil.commit(sqlSession); }catch (Exception e){ TransactionUtil.rollback(sqlSession); throw new RuntimeException(e); }finally { try { TransactionUtil.close(sqlSession); }catch (Exception e){ e.printStackTrace(); } } } @Override public void update (Course course) { SqlSession sqlSession = null ; try { sqlSession = MapperFactory.getSqlSession(); CourseDao courseDao = MapperFactory.getMapper(sqlSession,CourseDao.class ) ; courseDao.update(course); TransactionUtil.commit(sqlSession); }catch (Exception e){ TransactionUtil.rollback(sqlSession); throw new RuntimeException(e); }finally { try { TransactionUtil.close(sqlSession); }catch (Exception e){ e.printStackTrace(); } } } @Override public Course findById (String id) { SqlSession sqlSession = null ; try { sqlSession = MapperFactory.getSqlSession(); CourseDao courseDao = MapperFactory.getMapper(sqlSession,CourseDao.class ) ; return courseDao.findById(id); }catch (Exception e){ throw new RuntimeException(e); }finally { try { TransactionUtil.close(sqlSession); }catch (Exception e){ e.printStackTrace(); } } } @Override public List<Course> findAll () { SqlSession sqlSession = null ; try { sqlSession = MapperFactory.getSqlSession(); CourseDao courseDao = MapperFactory.getMapper(sqlSession,CourseDao.class ) ; return courseDao.findAll(); }catch (Exception e){ throw new RuntimeException(e); }finally { try { TransactionUtil.close(sqlSession); }catch (Exception e){ e.printStackTrace(); } } } @Override public PageInfo findAll (int page, int size) { SqlSession sqlSession = null ; try { sqlSession = MapperFactory.getSqlSession(); CourseDao courseDao = MapperFactory.getMapper(sqlSession,CourseDao.class ) ; PageHelper.startPage(page,size); List<Course> all = courseDao.findAll(); PageInfo pageInfo = new PageInfo(all); return pageInfo; }catch (Exception e){ throw new RuntimeException(e); }finally { try { TransactionUtil.close(sqlSession); }catch (Exception e){ e.printStackTrace(); } } } }
(6)创建servlet:com.itheima.web.controller.store.CourseServlet
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 @WebServlet ("/store/course" )public class CourseServlet extends BaseServlet { @Override protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String operation = request.getParameter("operation" ); if ("list" .equals(operation)){ this .list(request,response); }else if ("toAdd" .equals(operation)){ this .toAdd(request,response); }else if ("save" .equals(operation)){ this .save(request, response); }else if ("toEdit" .equals(operation)){ this .toEdit(request,response); }else if ("edit" .equals(operation)){ this .edit(request,response); }else if ("delete" .equals(operation)){ this .delete(request,response); } } private void list (HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { int page = 1 ; int size = 5 ; if (StringUtils.isNotBlank(request.getParameter("page" ))){ page = Integer.parseInt(request.getParameter("page" )); } if (StringUtils.isNotBlank(request.getParameter("size" ))){ size = Integer.parseInt(request.getParameter("size" )); } PageInfo all = courseService.findAll(page, size); request.setAttribute("page" ,all); request.getRequestDispatcher("/WEB-INF/pages/store/course/list.jsp" ).forward(request,response); } private void toAdd (HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { request.getRequestDispatcher("/WEB-INF/pages/store/course/add.jsp" ).forward(request,response); } private void save (HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { Course course = BeanUtil.fillBean(request,Course.class,"yyyy-MM-dd"); courseService.save(course); response.sendRedirect(request.getContextPath()+"/store/course?operation=list" ); } private void toEdit (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String id = request.getParameter("id" ); Course course = courseService.findById(id); request.setAttribute("course" ,course); request.getRequestDispatcher("/WEB-INF/pages/store/course/update.jsp" ).forward(request,response); } private void edit (HttpServletRequest request, HttpServletResponse response) throws IOException { Course course = BeanUtil.fillBean(request,Course.class,"yyyy-MM-dd"); courseService.update(course); response.sendRedirect(request.getContextPath()+"/store/course?operation=list" ); } private void delete (HttpServletRequest request, HttpServletResponse response) throws IOException { Course course = BeanUtil.fillBean(request,Course.class ) ; courseService.delete(course); response.sendRedirect(request.getContextPath()+"/store/course?operation=list" ); } @Override protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this .doGet(request,response); } }
(7)修改BaseServlet,添加CourseService
1 2 3 4 5 6 7 8 9 10 11 12 13 14 public class BaseServlet extends HttpServlet { protected CompanyService companyService; protected DeptService deptService; protected UserService userService; protected CourseService courseService; @Override public void init () throws ServletException { companyService = new CompanyServiceImpl(); deptService = new DeptServiceImpl(); userService = new UserServiceImpl(); courseService = new CourseServiceImpl(); } }
(8)创建/WEB-INF/pages/store/course
目录,然后从今日课程资料中找到模块页面\course
下的所有页面,拷贝到刚刚创建的目录下
(9)修改业务层的保存方法,添加创建时间的保存
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 @Override public void save (Course course) { SqlSession sqlSession = null ; try { sqlSession = MapperFactory.getSqlSession(); CourseDao courseDao = MapperFactory.getMapper(sqlSession,CourseDao.class ) ; String id = UUID.randomUUID().toString(); course.setId(id); course.setCreateTime(new Date()); courseDao.save(course); TransactionUtil.commit(sqlSession); }catch (Exception e){ TransactionUtil.rollback(sqlSession); throw new RuntimeException(e); }finally { try { TransactionUtil.close(sqlSession); }catch (Exception e){ e.printStackTrace(); } } }
(10)在修改时,我们的创建时间是不允许修改的,因此我们在dao层进行update操作是去掉对创建时间的修改,找到CourseDao
对应的持久层映射配置文件CourseDao.xml
中的update
,去掉创建时间即可
1 2 3 4 5 6 7 8 <update id ="update" parameterType ="com.itheima.domain.store.Course" > update st_course set name = #{name,jdbcType=VARCHAR}, remark = #{remark,jdbcType=VARCHAR}, state = #{state,jdbcType=VARCHAR} where id = #{id,jdbcType=VARCHAR}</update >
(11)解决站点字符编码的问题,从今日课程资料中找到web层资源文件\CharacterEncodingFilter.java
然后创建一个包com.itheima.web.filters
,然后把该文件拷贝到该包下
(12)启动项目进行测试
3. 目录模块 (1)创建目录实体:com.itheima.domain.store.Catalog
1 2 3 4 5 6 7 8 9 10 11 12 public class Catalog { private String id; private String name; private String remark; private String state; private Date createTime; private String courseId; private Course course; }
(2)创建dao接口:com.itheima.dao.store.CatalogDao
1 2 3 4 5 6 7 8 9 10 11 public interface CatalogDao { int save (Catalog catalog) ; int delete (Catalog catalog) ; int update (Catalog catalog) ; Catalog findById (String id) ; List<Catalog> findAll () ; }
(3)拷贝dao映射配置文件:前面已完成
(4)创建业务层接口:com.itheima.service.store.CatalogService
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 public interface CatalogService { void save (Catalog catalog) ; void delete (Catalog catalog) ; void update (Catalog catalog) ; Catalog findById (String id) ; List<Catalog> findAll () ; PageInfo findAll (int page, int size) ; }
(5)创建业务层实现类:com.itheima.service.store.impl.CatalogServiceImpl
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 public class CatalogServiceImpl implements CatalogService { @Override public void save (Catalog catalog) { SqlSession sqlSession = null ; try { sqlSession = MapperFactory.getSqlSession(); CatalogDao catalogDao = MapperFactory.getMapper(sqlSession, CatalogDao.class ) ; String id = UUID.randomUUID().toString(); catalog.setId(id); catalogDao.save(catalog); TransactionUtil.commit(sqlSession); } catch (Exception e) { TransactionUtil.rollback(sqlSession); throw new RuntimeException(e); } finally { try { TransactionUtil.close(sqlSession); } catch (Exception e) { e.printStackTrace(); } } } @Override public void delete (Catalog catalog) { SqlSession sqlSession = null ; try { sqlSession = MapperFactory.getSqlSession(); CatalogDao catalogDao = MapperFactory.getMapper(sqlSession, CatalogDao.class ) ; catalogDao.delete(catalog); TransactionUtil.commit(sqlSession); } catch (Exception e) { TransactionUtil.rollback(sqlSession); throw new RuntimeException(e); } finally { try { TransactionUtil.close(sqlSession); } catch (Exception e) { e.printStackTrace(); } } } @Override public void update (Catalog catalog) { SqlSession sqlSession = null ; try { sqlSession = MapperFactory.getSqlSession(); CatalogDao catalogDao = MapperFactory.getMapper(sqlSession, CatalogDao.class ) ; catalogDao.update(catalog); TransactionUtil.commit(sqlSession); } catch (Exception e) { TransactionUtil.rollback(sqlSession); throw new RuntimeException(e); } finally { try { TransactionUtil.close(sqlSession); } catch (Exception e) { e.printStackTrace(); } } } @Override public Catalog findById (String id) { SqlSession sqlSession = null ; try { sqlSession = MapperFactory.getSqlSession(); CatalogDao catalogDao = MapperFactory.getMapper(sqlSession, CatalogDao.class ) ; return catalogDao.findById(id); } catch (Exception e) { throw new RuntimeException(e); } finally { try { TransactionUtil.close(sqlSession); } catch (Exception e) { e.printStackTrace(); } } } @Override public List<Catalog> findAll () { SqlSession sqlSession = null ; try { sqlSession = MapperFactory.getSqlSession(); CatalogDao catalogDao = MapperFactory.getMapper(sqlSession, CatalogDao.class ) ; return catalogDao.findAll(); } catch (Exception e) { throw new RuntimeException(e); } finally { try { TransactionUtil.close(sqlSession); } catch (Exception e) { e.printStackTrace(); } } } @Override public PageInfo findAll (int page, int size) { SqlSession sqlSession = null ; try { sqlSession = MapperFactory.getSqlSession(); CatalogDao catalogDao = MapperFactory.getMapper(sqlSession, CatalogDao.class ) ; PageHelper.startPage(page, size); List<Catalog> all = catalogDao.findAll(); PageInfo pageInfo = new PageInfo(all); return pageInfo; } catch (Exception e) { throw new RuntimeException(e); } finally { try { TransactionUtil.close(sqlSession); } catch (Exception e) { e.printStackTrace(); } } } }
(6)创建servlet:com.itheima.web.controller.store.CatalogServlet
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 @WebServlet ("/store/catalog" )public class CatalogServlet extends BaseServlet { @Override protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String operation = request.getParameter("operation" ); if ("list" .equals(operation)){ this .list(request,response); }else if ("toAdd" .equals(operation)){ this .toAdd(request,response); }else if ("save" .equals(operation)){ this .save(request, response); }else if ("toEdit" .equals(operation)){ this .toEdit(request,response); }else if ("edit" .equals(operation)){ this .edit(request,response); }else if ("delete" .equals(operation)){ this .delete(request,response); } } private void list (HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { int page = 1 ; int size = 5 ; if (StringUtils.isNotBlank(request.getParameter("page" ))){ page = Integer.parseInt(request.getParameter("page" )); } if (StringUtils.isNotBlank(request.getParameter("size" ))){ size = Integer.parseInt(request.getParameter("size" )); } PageInfo all = catalogService.findAll(page, size); request.setAttribute("page" ,all); request.getRequestDispatcher("/WEB-INF/pages/store/catalog/list.jsp" ).forward(request,response); } private void toAdd (HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { request.getRequestDispatcher("/WEB-INF/pages/store/catalog/add.jsp" ).forward(request,response); } private void save (HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { Catalog catalog = BeanUtil.fillBean(request,Catalog.class,"yyyy-MM-dd"); catalogService.save(catalog); response.sendRedirect(request.getContextPath()+"/store/catalog?operation=list" ); } private void toEdit (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String id = request.getParameter("id" ); Catalog catalog = catalogService.findById(id); request.setAttribute("catalog" ,catalog); request.getRequestDispatcher("/WEB-INF/pages/store/catalog/update.jsp" ).forward(request,response); } private void edit (HttpServletRequest request, HttpServletResponse response) throws IOException { Catalog catalog = BeanUtil.fillBean(request,Catalog.class,"yyyy-MM-dd"); catalogService.update(catalog); response.sendRedirect(request.getContextPath()+"/store/catalog?operation=list" ); } private void delete (HttpServletRequest request, HttpServletResponse response) throws IOException { Catalog catalog = BeanUtil.fillBean(request,Catalog.class ) ; catalogService.delete(catalog); response.sendRedirect(request.getContextPath()+"/store/catalog?operation=list" ); } @Override protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this .doGet(request,response); } }
(7)修改BaseServlet,添加CatalogService
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public class BaseServlet extends HttpServlet { protected CompanyService companyService; protected DeptService deptService; protected UserService userService; protected CourseService courseService; protected CatalogService catalogService; @Override public void init () throws ServletException { companyService = new CompanyServiceImpl(); deptService = new DeptServiceImpl(); userService = new UserServiceImpl(); courseService = new CourseServiceImpl(); catalogService = new CatalogServiceImpl(); } }
(8)创建页面存放目录/WEB-INF/pages/store/catalog
,然后从今日课程资料中找到模块页面\catalog
下的所有页面到该目录
(9)修改servlet代码,找到toAdd
方法,在去添加页面之前查询所有的学科数据
1 2 3 4 5 6 7 private void toAdd (HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { List<Course> all = courseService.findAll(); request.setAttribute("courseList" ,all); request.getRequestDispatcher("/WEB-INF/pages/store/catalog/add.jsp" ).forward(request,response); }
(10)保存目录的时候要保存创建时间,修改业务层的save方法,添加对创建时间的保存
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 @Override public void save (Catalog catalog) { SqlSession sqlSession = null ; try { sqlSession = MapperFactory.getSqlSession(); CatalogDao catalogDao = MapperFactory.getMapper(sqlSession, CatalogDao.class ) ; String id = UUID.randomUUID().toString(); catalog.setId(id); catalog.setCreateTime(new Date()); catalogDao.save(catalog); TransactionUtil.commit(sqlSession); } catch (Exception e) { TransactionUtil.rollback(sqlSession); throw new RuntimeException(e); } finally { try { TransactionUtil.close(sqlSession); } catch (Exception e) { e.printStackTrace(); } } }
(11)修改servlet代码,找到toEdit
方法,去到编辑页面之前查询所有的学科信息,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 private void toEdit (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String id = request.getParameter("id" ); Catalog catalog = catalogService.findById(id); request.setAttribute("catalog" ,catalog); List<Course> all = courseService.findAll(); request.setAttribute("courseList" ,all); request.getRequestDispatcher("/WEB-INF/pages/store/catalog/update.jsp" ).forward(request,response); }
(12)启动项目,进行测试
4. 题目模块 4.1 题目模块快速开发 (1)创建题目实体:com.itheima.domain.store.Question
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 public class Question { private String id; private String companyId; private String catalogId; private String remark; private String subject; private String analysis; private String type; private String difficulty; private String isClassic; private String state; private String reviewStatus; private Date createTime; private Company company; private Catalog catalog; }
(2)创建dao接口:com.itheima.dao.store.QuestionDao
1 2 3 4 5 6 7 8 9 10 11 12 public interface QuestionDao { int save (Question question) ; int delete (Question question) ; int update (Question question) ; Question findById (String id) ; List<Question> findAll () ; }
(3)添加题目dao的映射配置文件,之前已操作,略
(4)创建业务层接口:com.itheima.service.store.QuestionService
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 public interface QuestionService { void save (Question question) ; void delete (Question question) ; void update (Question question) ; Question findById (String id) ; List<Question> findAll () ; PageInfo findAll (int page, int size) ; }
(5)创建业务层实现类:com.itheima.service.store.impl.QuestionServiceImpl
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 public class QuestionServiceImpl implements QuestionService { @Override public void save (Question question) { SqlSession sqlSession = null ; try { sqlSession = MapperFactory.getSqlSession(); QuestionDao questionDao = MapperFactory.getMapper(sqlSession,QuestionDao.class ) ; String id = UUID.randomUUID().toString(); question.setId(id); questionDao.save(question); TransactionUtil.commit(sqlSession); }catch (Exception e){ TransactionUtil.rollback(sqlSession); throw new RuntimeException(e); }finally { try { TransactionUtil.close(sqlSession); }catch (Exception e){ e.printStackTrace(); } } } @Override public void delete (Question question) { SqlSession sqlSession = null ; try { sqlSession = MapperFactory.getSqlSession(); QuestionDao questionDao = MapperFactory.getMapper(sqlSession,QuestionDao.class ) ; questionDao.delete(question); TransactionUtil.commit(sqlSession); }catch (Exception e){ TransactionUtil.rollback(sqlSession); throw new RuntimeException(e); }finally { try { TransactionUtil.close(sqlSession); }catch (Exception e){ e.printStackTrace(); } } } @Override public void update (Question question) { SqlSession sqlSession = null ; try { sqlSession = MapperFactory.getSqlSession(); QuestionDao questionDao = MapperFactory.getMapper(sqlSession,QuestionDao.class ) ; questionDao.update(question); TransactionUtil.commit(sqlSession); }catch (Exception e){ TransactionUtil.rollback(sqlSession); throw new RuntimeException(e); }finally { try { TransactionUtil.close(sqlSession); }catch (Exception e){ e.printStackTrace(); } } } @Override public Question findById (String id) { SqlSession sqlSession = null ; try { sqlSession = MapperFactory.getSqlSession(); QuestionDao questionDao = MapperFactory.getMapper(sqlSession,QuestionDao.class ) ; return questionDao.findById(id); }catch (Exception e){ throw new RuntimeException(e); }finally { try { TransactionUtil.close(sqlSession); }catch (Exception e){ e.printStackTrace(); } } } @Override public List<Question> findAll () { SqlSession sqlSession = null ; try { sqlSession = MapperFactory.getSqlSession(); QuestionDao questionDao = MapperFactory.getMapper(sqlSession,QuestionDao.class ) ; return questionDao.findAll(); }catch (Exception e){ throw new RuntimeException(e); }finally { try { TransactionUtil.close(sqlSession); }catch (Exception e){ e.printStackTrace(); } } } @Override public PageInfo findAll (int page, int size) { SqlSession sqlSession = null ; try { sqlSession = MapperFactory.getSqlSession(); QuestionDao questionDao = MapperFactory.getMapper(sqlSession,QuestionDao.class ) ; PageHelper.startPage(page,size); List<Question> all = questionDao.findAll(); PageInfo pageInfo = new PageInfo(all); return pageInfo; }catch (Exception e){ throw new RuntimeException(e); }finally { try { TransactionUtil.close(sqlSession); }catch (Exception e){ e.printStackTrace(); } } } }
(6)创建servlet:com.itheima.web.controller.store.QuestionServlet
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 @WebServlet ("/store/question" )public class QuestionServlet extends BaseServlet { @Override protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String operation = request.getParameter("operation" ); if ("list" .equals(operation)){ this .list(request,response); }else if ("toAdd" .equals(operation)){ this .toAdd(request,response); }else if ("save" .equals(operation)){ this .save(request, response); }else if ("toEdit" .equals(operation)){ this .toEdit(request,response); }else if ("edit" .equals(operation)){ this .edit(request,response); }else if ("delete" .equals(operation)){ this .delete(request,response); } } private void list (HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { int page = 1 ; int size = 5 ; if (StringUtils.isNotBlank(request.getParameter("page" ))){ page = Integer.parseInt(request.getParameter("page" )); } if (StringUtils.isNotBlank(request.getParameter("size" ))){ size = Integer.parseInt(request.getParameter("size" )); } PageInfo all = questionService.findAll(page, size); request.setAttribute("page" ,all); request.getRequestDispatcher("/WEB-INF/pages/store/question/list.jsp" ).forward(request,response); } private void toAdd (HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { request.getRequestDispatcher("/WEB-INF/pages/store/question/add.jsp" ).forward(request,response); } private void save (HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { Question question = BeanUtil.fillBean(request,Question.class,"yyyy-MM-dd"); questionService.save(question); response.sendRedirect(request.getContextPath()+"/store/question?operation=list" ); } private void toEdit (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String id = request.getParameter("id" ); Question question = questionService.findById(id); request.setAttribute("question" ,question); request.getRequestDispatcher("/WEB-INF/pages/store/question/update.jsp" ).forward(request,response); } private void edit (HttpServletRequest request, HttpServletResponse response) throws IOException { Question question = BeanUtil.fillBean(request,Question.class,"yyyy-MM-dd"); questionService.update(question); response.sendRedirect(request.getContextPath()+"/store/question?operation=list" ); } private void delete (HttpServletRequest request, HttpServletResponse response) throws IOException { Question question = BeanUtil.fillBean(request,Question.class ) ; questionService.delete(question); response.sendRedirect(request.getContextPath()+"/store/question?operation=list" ); } @Override protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this .doGet(request,response); } }
(7)修改BaserServlet,添加QuestionService
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public class BaseServlet extends HttpServlet { protected CompanyService companyService; protected DeptService deptService; protected UserService userService; protected CourseService courseService; protected CatalogService catalogService; protected QuestionService questionService; @Override public void init () throws ServletException { companyService = new CompanyServiceImpl(); deptService = new DeptServiceImpl(); userService = new UserServiceImpl(); courseService = new CourseServiceImpl(); catalogService = new CatalogServiceImpl(); questionService = new QuestionServiceImpl(); } }
(8)创建页面存放目录,/WEB-INF/pages/store/question
,从今日课程资料中找到模块页面\question
,将下面的所有页面拷贝到该目录下
(9)修改servlet,找到toAdd
方法,去添加页面之前查询企业和目录数据
1 2 3 4 5 6 7 8 9 10 private void toAdd (HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { List<Company> companyList = companyService.findAll(); List<Catalog> catalogList = catalogService.findAll(); request.setAttribute("companyList" ,companyList); request.setAttribute("catalogList" ,catalogList); request.getRequestDispatcher("/WEB-INF/pages/store/question/add.jsp" ).forward(request,response); }
找到toEdit
方法,去修改页面之前查询企业和目录数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 private void toEdit (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String id = request.getParameter("id" ); Question question = questionService.findById(id); request.setAttribute("question" ,question); List<Company> companyList = companyService.findAll(); List<Catalog> catalogList = catalogService.findAll(); request.setAttribute("companyList" ,companyList); request.setAttribute("catalogList" ,catalogList); request.getRequestDispatcher("/WEB-INF/pages/store/question/update.jsp" ).forward(request,response); }
(10)修改业务层代码,找到添加数据的方法,需要新增审核状态和创建时间的数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 @Override public void save (Question question) { SqlSession sqlSession = null ; try { sqlSession = MapperFactory.getSqlSession(); QuestionDao questionDao = MapperFactory.getMapper(sqlSession,QuestionDao.class ) ; String id = UUID.randomUUID().toString(); question.setId(id); question.setReviewStatus("0" ); question.setCreateTime(new Date()); questionDao.save(question); TransactionUtil.commit(sqlSession); }catch (Exception e){ TransactionUtil.rollback(sqlSession); throw new RuntimeException(e); }finally { try { TransactionUtil.close(sqlSession); }catch (Exception e){ e.printStackTrace(); } } }
(11)修改查询所有数据时的排序,修改对应的dao映射配置文件QuestionDao.xml
1 2 3 4 5 6 7 <select id ="findAll" resultMap ="BaseResultMap" > select <include refid ="Base_Column_List" /> from st_question order by create_time desc</select >
(12)在进行数据修改时,有些数据是不能修改的,我们可以在持久层映射配置文件中进行控制
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <update id ="update" parameterType ="com.itheima.domain.store.Question" > update st_question set company_id = #{companyId,jdbcType=VARCHAR}, catalog_id = #{catalogId,jdbcType=VARCHAR}, remark = #{remark,jdbcType=VARCHAR}, subject = #{subject,jdbcType=VARCHAR}, analysis = #{analysis,jdbcType=VARCHAR}, difficulty = #{difficulty,jdbcType=VARCHAR}, is_classic = #{isClassic,jdbcType=VARCHAR}, state = #{state,jdbcType=VARCHAR} where id = #{id,jdbcType=VARCHAR}</update >
4.2 文件上传基础演示 文件上传功能需要前台功能和后台功能共同配合完成
前台 :文件上传的三要素
form表单enctype属性的值为multipart/form-data
表单的提交方式必须是POST
,get方式无法提交大量的数据
后台 :可以使用的技术有很多,在此处我们使用apache提供的commons-fileupload组件完成文件上次操作,后台的操作步骤如下
确认请求操作是否支持文件上传
创建磁盘工厂对象,用于将页面上传的文件保存到磁盘中
获取servet文件上传核心对象
读取数据
对读取到数据中的文件表单进行操作,并将内容写到指定位置
下面我们开始进行文件上传的演示:
(1)从今日课程资料找到文件下载\testFileUpload.jsp
文件上传页面,将其添加到项目/WEB-INF/pages/store/question目录下
(2)在question目录下的list.jsp页面上添加一个新的按钮,点击该按钮跳转到文件上传页面
1 <button type ="button" class ="btn btn-default" title ="测试文件上传" onclick ='location.href="${ctx}/store/question?operation=toTestUpload"' > <i class ="fa fa-file-o" > </i > 测试文件上传</button >
(3)在QuestionServlet
中添加toTestUpload
方法,跳转到文件上传页面
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 @WebServlet ("/store/question" )public class QuestionServlet extends BaseServlet { @Override protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String operation = request.getParameter("operation" ); if ("list" .equals(operation)){ this .list(request,response); }else if ("toAdd" .equals(operation)){ this .toAdd(request,response); }else if ("save" .equals(operation)){ this .save(request, response); }else if ("toEdit" .equals(operation)){ this .toEdit(request,response); }else if ("edit" .equals(operation)){ this .edit(request,response); }else if ("delete" .equals(operation)){ this .delete(request,response); }else if ("toTestUpload" .equals(operation)){ this .toTestUpload(request,response); }else if ("testUpload" .equals(operation)){ try { this .testUpload(request,response); } catch (Exception e) { e.printStackTrace(); } } } private void toTestUpload (HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { request.getRequestDispatcher("/WEB-INF/pages/store/question/testFileUpload.jsp" ).forward(request,response); } private void testUpload (HttpServletRequest request,HttpServletResponse response) throws Exception { } }
(4)完成文件上传的后台代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 private void testUpload (HttpServletRequest request,HttpServletResponse response) throws Exception { if (ServletFileUpload.isMultipartContent(request)){ DiskFileItemFactory factory = new DiskFileItemFactory(); ServletFileUpload fileUpload = new ServletFileUpload(factory); List<FileItem> fileItems = fileUpload.parseRequest(request); for (FileItem item : fileItems){ if (!item.isFormField()){ item.write(new File(this .getServletContext().getRealPath("upload" ),item.getName())); } } } }
需要在项目webapp
目录下创建一个upload目录用于存储上传过来的文件
(5)启动测试
4.3 添加题目时加入文件上传 (1)在题目实体中添加图片的属性
1 2 3 4 5 6 7 8 9 10 11 public class Question { private String picture; public String getPicture () { return picture; } public void setPicture (String picture) { this .picture = picture; } }
(2)在对应的dao映射配置文件中添加图片字段的配置,在resultMap,查询的sql片段,保存,更新
几个位置添加映射配置即可,更新的时候是不需要更改图片的名称,因此是去掉对图片名称的更新
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 <resultMap id ="BaseResultMap" type ="com.itheima.domain.store.Question" > <id column ="id" jdbcType ="VARCHAR" property ="id" /> <result column ="company_id" jdbcType ="VARCHAR" property ="companyId" /> <result column ="catalog_id" jdbcType ="VARCHAR" property ="catalogId" /> <result column ="remark" jdbcType ="VARCHAR" property ="remark" /> <result column ="subject" jdbcType ="VARCHAR" property ="subject" /> <result column ="analysis" jdbcType ="VARCHAR" property ="analysis" /> <result column ="type" jdbcType ="VARCHAR" property ="type" /> <result column ="difficulty" jdbcType ="VARCHAR" property ="difficulty" /> <result column ="is_classic" jdbcType ="VARCHAR" property ="isClassic" /> <result column ="state" jdbcType ="VARCHAR" property ="state" /> <result column ="review_status" jdbcType ="VARCHAR" property ="reviewStatus" /> <result column ="create_time" jdbcType ="TIMESTAMP" property ="createTime" /> <result column ="picture" jdbcType ="VARCHAR" property ="picture" /> <association property ="company" column ="company_id" javaType ="com.itheima.domain.store.Course" select ="com.itheima.dao.store.CompanyDao.findById" /> <association property ="catalog" column ="catalog_id" javaType ="com.itheima.domain.store.Course" select ="com.itheima.dao.store.CatalogDao.findById" /> </resultMap > <sql id ="Base_Column_List" > id, catalog_id, company_id, remark,subject,analysis,type, difficulty, is_classic, state, review_status, create_time, picture</sql > <insert id ="save" parameterType ="com.itheima.domain.store.Question" > insert into st_question(id, company_id, catalog_id, remark, subject, analysis, type, difficulty, is_classic, state, review_status, create_time ,picture ) values (#{id,jdbcType=VARCHAR}, #{companyId,jdbcType=VARCHAR}, #{catalogId,jdbcType=VARCHAR}, #{remark,jdbcType=VARCHAR}, #{subject,jdbcType=VARCHAR}, #{analysis,jdbcType=VARCHAR}, #{type,jdbcType=VARCHAR}, #{difficulty,jdbcType=VARCHAR}, #{isClassic,jdbcType=VARCHAR}, #{state,jdbcType=VARCHAR}, #{reviewStatus,jdbcType=VARCHAR}, #{createTime,jdbcType=TIMESTAMP}, #{picture,jdbcType=VARCHAR} )</insert > <update id ="update" parameterType ="com.itheima.domain.store.Question" > update st_question set company_id = #{companyId,jdbcType=VARCHAR}, catalog_id = #{catalogId,jdbcType=VARCHAR}, remark = #{remark,jdbcType=VARCHAR}, subject = #{subject,jdbcType=VARCHAR}, analysis = #{analysis,jdbcType=VARCHAR}, difficulty = #{difficulty,jdbcType=VARCHAR}, is_classic = #{isClassic,jdbcType=VARCHAR}, state = #{state,jdbcType=VARCHAR} where id = #{id,jdbcType=VARCHAR}</update >
(3)在question模块的添加页面add.jsp
中加入图片上传的表单项
1 2 3 4 5 6 7 8 9 10 <form id="editForm" action="${ctx}/store/question?operation=save" method="post" enctype="multipart/form-data" > <!--其他元素略--> <div class="col-md-2 title">题干图片</div><!--放到题干后面--> <div class ="col-md-10 data " > <input type="file" class ="form-control" placeholder="题干图片" name="picture" > </div> </form>
(4)在servlet中修改保存题目的方法save
,首先要更改的就是接收数据的方式,我们要按照文件上传的形式来接收
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 @Override protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String operation = request.getParameter("operation" ); if ("list" .equals(operation)){ this .list(request,response); }else if ("toAdd" .equals(operation)){ this .toAdd(request,response); }else if ("save" .equals(operation)){ try { this .save(request, response); } catch (Exception e) { e.printStackTrace(); } }else if ("toEdit" .equals(operation)){ this .toEdit(request,response); }else if ("edit" .equals(operation)){ this .edit(request,response); }else if ("delete" .equals(operation)){ this .delete(request,response); }else if ("toTestUpload" .equals(operation)){ this .toTestUpload(request,response); }else if ("testUpload" .equals(operation)){ try { this .testUpload(request,response); } catch (Exception e) { e.printStackTrace(); } } }private void save (HttpServletRequest request,HttpServletResponse response) throws Exception { if (ServletFileUpload.isMultipartContent(request)){ DiskFileItemFactory factory = new DiskFileItemFactory(); ServletFileUpload fileUpload = new ServletFileUpload(factory); List<FileItem> fileItems = fileUpload.parseRequest(request); Question question = BeanUtil.fillBean(fileItems,Question.class ) ; questionService.save(question); for (FileItem item : fileItems){ if (!item.isFormField()){ item.write(new File(this .getServletContext().getRealPath("upload" ),item.getName())); } } } response.sendRedirect(request.getContextPath()+"/store/question?operation=list" ); }
4.4 文件上传的重名问题 (1)在question模块的list.jsp
页面中添加对图片名称的展示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 <!--数据列表--> <table id="dataList" class ="table table-bordered table-striped table-hover dataTable" > <thead> <tr> <th class ="" style="padding-right:0px;" > <input type="checkbox" name="selid" onclick="checkAll('id',this)" > </th> <th class="sorting">图片</th> <th class="sorting">企业</th> <th class="sorting">类别</th> <th class="sorting">题目</th> <th class="sorting">类型</th> <th class="sorting">难度</th> <th class="sorting">经典面试题</th> <th class="sorting">状态</th> <th class="sorting">审核结果</th> <th class="text-center">操作</th> </tr> </thead> <tbody> <c:forEach items="${page.list}" var ="o" varStatus="status" > <tr class ="odd" onmouseover="this.className='highlight'" onmouseout="this.className='odd'" > <td><input type="checkbox" name="id" value="${o.id}"/></td> <td>${o.picture}</td> <td>${o.company.name}</td> <td>${o.catalog.name}</td> <td>${o.subject}</td> <td> <c:choose> <c:when test="${o.type eq '1'}">单选</c:when> <c:when test="${o.type eq '2'}">多选</c:when> <c:when test="${o.type eq '3'}">简答</c:when> </c:choose> </td> <td> <c:forEach begin="1" end="${o.difficulty}" > ★ </c:forEach> </td> <td>${o.isClassic eq "1" ? "经典题":"普通题"}</td> <td>${o.state eq "1" ? "<font color='green'>启用</font>" : "<font color='red'>禁用</font>"}</td> <td> <c:choose> <c:when test="${o.reviewStatus eq '1'}"><font color="green">审核通过</font></c:when> <c:when test="${o.reviewStatus eq '0'}">审核中</c:when> <c:when test="${o.reviewStatus eq '-1'}"><font color="red">审核不通过</font></c:when> </c:choose> </td> <th class ="text-center" > <button type="button" class="btn bg-olive btn-xs" onclick='location.href="${ctx}/store/question?operation=toEdit&id=${o.id}"'>编辑</button> <button type="button" class="btn bg-olive btn-xs" onclick='location.href="${ctx}/store/question?operation=toExamine&id=${o.id}"'>审核</button> </th> </tr> </c:forEach> </tbody> </table>
文件上传的常见问题:文件重名问题
(1)修改业务层接口QuestionService
的保存方法,添加返回值,将图片的名称返回
1 2 3 4 5 6 String save (Question question) ;
(2)修改实现类,添加对图片名称的存储及返回图片的名称,图片名称使用该条数据的id
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 @Override public String save (Question question) { SqlSession sqlSession = null ; try { sqlSession = MapperFactory.getSqlSession(); QuestionDao questionDao = MapperFactory.getMapper(sqlSession,QuestionDao.class ) ; String id = UUID.randomUUID().toString(); question.setId(id); question.setReviewStatus("0" ); question.setCreateTime(new Date()); question.setPicture(id); questionDao.save(question); TransactionUtil.commit(sqlSession); return id; }catch (Exception e){ TransactionUtil.rollback(sqlSession); throw new RuntimeException(e); }finally { try { TransactionUtil.close(sqlSession); }catch (Exception e){ e.printStackTrace(); } } }
(3)在servlet中的save
方法中接收图片名称
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 private void save (HttpServletRequest request,HttpServletResponse response) throws Exception { if (ServletFileUpload.isMultipartContent(request)){ DiskFileItemFactory factory = new DiskFileItemFactory(); ServletFileUpload fileUpload = new ServletFileUpload(factory); List<FileItem> fileItems = fileUpload.parseRequest(request); Question question = BeanUtil.fillBean(fileItems,Question.class ) ; String picture = questionService.save(question); for (FileItem item : fileItems){ if (!item.isFormField()){ item.write(new File(this .getServletContext().getRealPath("upload" ),picture)); } } } response.sendRedirect(request.getContextPath()+"/store/question?operation=list" ); }
4.5 修改题目时加入文件上传 修改之前需要先将图片展示出来
(1)在question
模块的update.jsp
页面中添加图片的展示,同时把修改时上传图片的表单项添加进去,以及表单也要配套修改
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <form id="editForm" action="${ctx}/store/question?operation=edit" method="post" enctype="multipart/form-data" > <!--其他省略--> <div class="col-md-2 title">题干图片</div> <div class ="col-md-10 data " > <input type="file" class ="form-control" placeholder="题干图片" name="picture" value="${question.picture}" > </div> <div class="col-md-2 title">题干图片</div> <div class ="col-md-10 data " > <img src="${ctx}/upload/${question.picture}" /> </div> </form>
(2)修改后台的servlet,找到edit
方法进行修改
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 @Override protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String operation = request.getParameter("operation" ); if ("list" .equals(operation)){ this .list(request,response); }else if ("toAdd" .equals(operation)){ this .toAdd(request,response); }else if ("save" .equals(operation)){ try { this .save(request, response); } catch (Exception e) { e.printStackTrace(); } }else if ("toEdit" .equals(operation)){ this .toEdit(request,response); }else if ("edit" .equals(operation)){ try { this .edit(request,response); } catch (Exception e) { e.printStackTrace(); } }else if ("delete" .equals(operation)){ this .delete(request,response); }else if ("toTestUpload" .equals(operation)){ this .toTestUpload(request,response); }else if ("testUpload" .equals(operation)){ try { this .testUpload(request,response); } catch (Exception e) { e.printStackTrace(); } } }private void edit (HttpServletRequest request, HttpServletResponse response) throws Exception { if (ServletFileUpload.isMultipartContent(request)){ DiskFileItemFactory factory = new DiskFileItemFactory(); ServletFileUpload fileUpload = new ServletFileUpload(factory); List<FileItem> fileItems = fileUpload.parseRequest(request); Question question = BeanUtil.fillBean(fileItems,Question.class ) ; questionService.update(question); for (FileItem item : fileItems){ if (!item.isFormField()){ item.write(new File(this .getServletContext().getRealPath("upload" ),question.getId())); } } } response.sendRedirect(request.getContextPath()+"/store/question?operation=list" ); }
(3)业务层实现类的update
方法在进行数据修改时,图片名称不需要修改,这个我们在持久层的update操作时去掉对图片的更改,我们改一下对应的映射配置文件(这步操作之前已完成)如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <update id ="update" parameterType ="com.itheima.domain.store.Question" > update st_question set company_id = #{companyId,jdbcType=VARCHAR}, catalog_id = #{catalogId,jdbcType=VARCHAR}, remark = #{remark,jdbcType=VARCHAR}, subject = #{subject,jdbcType=VARCHAR}, analysis = #{analysis,jdbcType=VARCHAR}, difficulty = #{difficulty,jdbcType=VARCHAR}, is_classic = #{isClassic,jdbcType=VARCHAR}, state = #{state,jdbcType=VARCHAR} where id = #{id,jdbcType=VARCHAR}</update >
4.6 兼容图片上传可选操作与显示问题 问题 :
如果在新增的时候没有选择上传图片,会导致在修改的时候页面上展示不出图片,如下图所示
产生问题的原因:
新增的时候虽然没有上传图片,但是由于我们保存数据的时候默认是将数据的id作为图片的名称,所以在展示的时候会去找这个名称的图片,但是我们又没上传因此会找到不到
改进方法:
在新增时做一个判断,如果上传了图片再去保存图片的名称,没有上传则不保存图片的名称
(1)在servlet的add
方法中去判断当前是否上传文件,可以用一个布尔值标记来表明是否有文件上传,同时在业务层执行保存操作时可以把这个是否有图片的标记传递过去
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 private void save (HttpServletRequest request,HttpServletResponse response) throws Exception { if (ServletFileUpload.isMultipartContent(request)){ DiskFileItemFactory factory = new DiskFileItemFactory(); ServletFileUpload fileUpload = new ServletFileUpload(factory); List<FileItem> fileItems = fileUpload.parseRequest(request); boolean flag = false ; for (FileItem item :fileItems){ if (StringUtils.isNotBlank(item.getName())){ flag = true ; break ; } } Question question = BeanUtil.fillBean(fileItems,Question.class ) ; String picture = questionService.save(question , flag); for (FileItem item : fileItems){ if (!item.isFormField()){ item.write(new File(this .getServletContext().getRealPath("upload" ),picture)); } } } response.sendRedirect(request.getContextPath()+"/store/question?operation=list" ); }
(2)修改业务层接口方法save
,添加参数
1 2 3 4 5 6 7 String save (Question question,boolean flag) ;
(3)修改对应的接口实现类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 @Override public String save (Question question,boolean flag) { SqlSession sqlSession = null ; try { sqlSession = MapperFactory.getSqlSession(); QuestionDao questionDao = MapperFactory.getMapper(sqlSession,QuestionDao.class ) ; String id = UUID.randomUUID().toString(); question.setId(id); question.setReviewStatus("0" ); question.setCreateTime(new Date()); if (flag) { question.setPicture(id); } questionDao.save(question); TransactionUtil.commit(sqlSession); return id; }catch (Exception e){ TransactionUtil.rollback(sqlSession); throw new RuntimeException(e); }finally { try { TransactionUtil.close(sqlSession); }catch (Exception e){ e.printStackTrace(); } } }
(4)在修改时,如果没有图片则不显示图片,有图片信息的时候再显示,我们可以使用<c:if>
进行判断
1 2 3 4 5 6 7 8 9 10 11 <div class="col-md-2 title">题干图片</div> <div class ="col-md-10 data " > <input type="file" class ="form-control" placeholder="题干图片" name="picture" value="${question.picture}" > </div> <c:if test="${question.picture.length() > 0}" > <div class="col-md-2 title">题干图片</div> <div class ="col-md-10 data " > <img src="${ctx}/upload/${question.picture}" /> </div> </c:if>
(5)页面修改完成后,在进行真正的修改操作时,我们同样需要进行判断,如果上传了图片则进行修改,否则不进行修改。
找到后台的servlet的edit
方法,做出如下修改
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 private void edit (HttpServletRequest request, HttpServletResponse response) throws Exception { if (ServletFileUpload.isMultipartContent(request)){ DiskFileItemFactory factory = new DiskFileItemFactory(); ServletFileUpload fileUpload = new ServletFileUpload(factory); List<FileItem> fileItems = fileUpload.parseRequest(request); boolean flag = false ; for (FileItem item :fileItems){ if (StringUtils.isNotBlank(item.getName())){ flag = true ; break ; } } Question question = BeanUtil.fillBean(fileItems,Question.class ) ; questionService.update(question , flag); for (FileItem item : fileItems){ if (!item.isFormField()){ item.write(new File(this .getServletContext().getRealPath("upload" ),question.getId())); } } } response.sendRedirect(request.getContextPath()+"/store/question?operation=list" ); }
(6)同样需要修改业务层接口,在update
方法上添加是否修改图片的参数
1 2 3 4 5 6 7 void update (Question question,boolean flag) ;
(7)在业务层实现类中修改该方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 @Override public void update (Question question, boolean flag) { SqlSession sqlSession = null ; try { sqlSession = MapperFactory.getSqlSession(); QuestionDao questionDao = MapperFactory.getMapper(sqlSession,QuestionDao.class ) ; if (flag) { question.setPicture(question.getId()); } questionDao.update(question); TransactionUtil.commit(sqlSession); }catch (Exception e){ TransactionUtil.rollback(sqlSession); throw new RuntimeException(e); }finally { try { TransactionUtil.close(sqlSession); }catch (Exception e){ e.printStackTrace(); } } }
(8)在持久层dao真正进行update操作的时候我们把对图片的更新添加进去,我们去修改对应的映射配置文件即可
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <update id ="update" parameterType ="com.itheima.domain.store.Question" > update st_question set company_id = #{companyId,jdbcType=VARCHAR}, catalog_id = #{catalogId,jdbcType=VARCHAR}, remark = #{remark,jdbcType=VARCHAR}, subject = #{subject,jdbcType=VARCHAR}, analysis = #{analysis,jdbcType=VARCHAR}, difficulty = #{difficulty,jdbcType=VARCHAR}, is_classic = #{isClassic,jdbcType=VARCHAR}, picture = #{picture,jdbcType=VARCHAR}, state = #{state,jdbcType=VARCHAR} where id = #{id,jdbcType=VARCHAR}</update >
5. 题目选项模块 5.1 列表页制作 (1)创建题目选项实体:com.itheima.domain.store.QuestionItem
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public class QuestionItem { private String id; private String questionId; private String content; private String picture; private String isRight; @Override public String toString () { return "QuestionItem{" + "id='" + id + '\'' + ", questionId='" + questionId + '\'' + ", content='" + content + '\'' + ", picture='" + picture + '\'' + ", isRight='" + isRight + '\'' + '}' ; } }
(2)创建dao接口:com.itheima.dao.store.QuestionItemDao
1 2 3 4 5 6 7 8 9 10 11 public interface QuestionItemDao { int save (QuestionItem questionItem) ; int delete (QuestionItem questionItem) ; int update (QuestionItem questionItem) ; QuestionItem findById (String id) ; List<QuestionItem> findAll () ; }
(3)添加对应的映射配置文件,之前已导入过了
(4)创建业务层接口:com.itheima.service.store.QuestionItemService
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 public interface QuestionItemService { void save (QuestionItem questionItem) ; void delete (QuestionItem questionItem) ; void update (QuestionItem questionItem) ; QuestionItem findById (String id) ; List<QuestionItem> findAll () ; PageInfo findAll (int page, int size) ; }
(5)创建业务层实现类:com.itheima.service.store.impl.QuestionItemServiceImpl
我们基于CompanyServiceImpl
拷贝然后改造
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 public class QuestionItemServiceImpl implements QuestionItemService { @Override public void save (QuestionItem questionItem) { SqlSession sqlSession = null ; try { sqlSession = MapperFactory.getSqlSession(); QuestionItemDao questionItemDao = MapperFactory.getMapper(sqlSession,QuestionItemDao.class ) ; String id = UUID.randomUUID().toString(); questionItem.setId(id); questionItemDao.save(questionItem); TransactionUtil.commit(sqlSession); }catch (Exception e){ TransactionUtil.rollback(sqlSession); throw new RuntimeException(e); }finally { try { TransactionUtil.close(sqlSession); }catch (Exception e){ e.printStackTrace(); } } } @Override public void delete (QuestionItem questionItem) { SqlSession sqlSession = null ; try { sqlSession = MapperFactory.getSqlSession(); QuestionItemDao questionItemDao = MapperFactory.getMapper(sqlSession,QuestionItemDao.class ) ; questionItemDao.delete(questionItem); TransactionUtil.commit(sqlSession); }catch (Exception e){ TransactionUtil.rollback(sqlSession); throw new RuntimeException(e); }finally { try { TransactionUtil.close(sqlSession); }catch (Exception e){ e.printStackTrace(); } } } @Override public void update (QuestionItem questionItem) { SqlSession sqlSession = null ; try { sqlSession = MapperFactory.getSqlSession(); QuestionItemDao questionItemDao = MapperFactory.getMapper(sqlSession,QuestionItemDao.class ) ; questionItemDao.update(questionItem); TransactionUtil.commit(sqlSession); }catch (Exception e){ TransactionUtil.rollback(sqlSession); throw new RuntimeException(e); }finally { try { TransactionUtil.close(sqlSession); }catch (Exception e){ e.printStackTrace(); } } } @Override public QuestionItem findById (String id) { SqlSession sqlSession = null ; try { sqlSession = MapperFactory.getSqlSession(); QuestionItemDao questionItemDao = MapperFactory.getMapper(sqlSession,QuestionItemDao.class ) ; return questionItemDao.findById(id); }catch (Exception e){ throw new RuntimeException(e); }finally { try { TransactionUtil.close(sqlSession); }catch (Exception e){ e.printStackTrace(); } } } @Override public List<QuestionItem> findAll () { SqlSession sqlSession = null ; try { sqlSession = MapperFactory.getSqlSession(); QuestionItemDao questionItemDao = MapperFactory.getMapper(sqlSession,QuestionItemDao.class ) ; return questionItemDao.findAll(); }catch (Exception e){ throw new RuntimeException(e); }finally { try { TransactionUtil.close(sqlSession); }catch (Exception e){ e.printStackTrace(); } } } @Override public PageInfo findAll (int page, int size) { SqlSession sqlSession = null ; try { sqlSession = MapperFactory.getSqlSession(); QuestionItemDao questionItemDao = MapperFactory.getMapper(sqlSession,QuestionItemDao.class ) ; PageHelper.startPage(page,size); List<QuestionItem> all = questionItemDao.findAll(); PageInfo pageInfo = new PageInfo(all); return pageInfo; }catch (Exception e){ throw new RuntimeException(e); }finally { try { TransactionUtil.close(sqlSession); }catch (Exception e){ e.printStackTrace(); } } } }
(6)创建servlet:com.itheima.web.controller.store.QuestionItemServlet
基于CompanyServlet
拷贝进行改造(修改完成后有些方法其实没有用,我们暂时不用去修改,后续我们会逐级进行修改)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 @WebServlet ("/store/questionItem" )public class QuestionItemServlet extends BaseServlet { @Override protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String operation = request.getParameter("operation" ); if ("list" .equals(operation)){ this .list(request,response); }else if ("toAdd" .equals(operation)){ this .toAdd(request,response); }else if ("save" .equals(operation)){ this .save(request, response); }else if ("toEdit" .equals(operation)){ this .toEdit(request,response); }else if ("edit" .equals(operation)){ this .edit(request,response); }else if ("delete" .equals(operation)){ this .delete(request,response); } } private void list (HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { int page = 1 ; int size = 5 ; if (StringUtils.isNotBlank(request.getParameter("page" ))){ page = Integer.parseInt(request.getParameter("page" )); } if (StringUtils.isNotBlank(request.getParameter("size" ))){ size = Integer.parseInt(request.getParameter("size" )); } PageInfo all = questionItemService.findAll(page, size); request.setAttribute("page" ,all); request.getRequestDispatcher("/WEB-INF/pages/store/questionItem/list.jsp" ).forward(request,response); } private void toAdd (HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { request.getRequestDispatcher("/WEB-INF/pages/store/questionItem/add.jsp" ).forward(request,response); } private void save (HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { QuestionItem questionItem = BeanUtil.fillBean(request,QuestionItem.class,"yyyy-MM-dd"); questionItemService.save(questionItem); response.sendRedirect(request.getContextPath()+"/store/questionItem?operation=list" ); } private void toEdit (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String id = request.getParameter("id" ); QuestionItem questionItem = questionItemService.findById(id); request.setAttribute("questionItem" ,questionItem); request.getRequestDispatcher("/WEB-INF/pages/store/questionItem/update.jsp" ).forward(request,response); } private void edit (HttpServletRequest request, HttpServletResponse response) throws IOException { QuestionItem questionItem = BeanUtil.fillBean(request,QuestionItem.class,"yyyy-MM-dd"); questionItemService.update(questionItem); response.sendRedirect(request.getContextPath()+"/store/questionItem?operation=list" ); } private void delete (HttpServletRequest request, HttpServletResponse response) throws IOException { QuestionItem questionItem = BeanUtil.fillBean(request,QuestionItem.class ) ; questionItemService.delete(questionItem); response.sendRedirect(request.getContextPath()+"/store/questionItem?operation=list" ); } @Override protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this .doGet(request,response); }
(7)在BaseServlet中添加QuestionItemService
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public class BaseServlet extends HttpServlet { protected CompanyService companyService; protected DeptService deptService; protected UserService userService; protected CourseService courseService; protected CatalogService catalogService; protected QuestionService questionService; protected QuestionItemService questionItemService; @Override public void init () throws ServletException { companyService = new CompanyServiceImpl(); deptService = new DeptServiceImpl(); userService = new UserServiceImpl(); courseService = new CourseServiceImpl(); catalogService = new CatalogServiceImpl(); questionService = new QuestionServiceImpl(); questionItemService = new QuestionItemServiceImpl(); } }
(8)创建页面存放的目录/WEB-INF/pages/store/questionItem
,从今日课程资料中的模块页面\questionItem
下复制所有的页面到刚创建好的目录中
(9)在question
模块的list.jsp
页面中添加题目选项列表页的入口,因为题目选项是针对某个具体的题目的,在每条列表数据的操作中添加一个配置选项的按钮
1 <button type="button" class="btn bg-olive btn-xs" onclick='location.href="${ctx}/store/questionItem?operation=list&questionId=${o.id}"'>配置选项</button>
同时在questionItem
模块中的list.jsp
页面中我们需要删除一些页面元素,分页,新建按钮,删除按钮,只留下刷新按钮
(10)在后台servlet的list方法中接收题目的id,我们要查询的列表应该是该题目下的所有选项列表
1 2 3 4 5 6 7 8 9 private void list (HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { String questionId = request.getParameter("questionId" ); PageInfo all = questionItemService.findAll(questionId,1 , 100 ); request.setAttribute("page" ,all); request.getRequestDispatcher("/WEB-INF/pages/store/questionItem/list.jsp" ).forward(request,response); }
(11)修改业务层接口方法,添加参数,注意是改带分页的那个方法
1 2 3 4 5 6 7 8 PageInfo findAll (String questionId,int page, int size) ;
(12)在业务层实现类中修改对应的方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 @Override public PageInfo findAll (String questionId,int page, int size) { SqlSession sqlSession = null ; try { sqlSession = MapperFactory.getSqlSession(); QuestionItemDao questionItemDao = MapperFactory.getMapper(sqlSession,QuestionItemDao.class ) ; PageHelper.startPage(page,size); List<QuestionItem> all = questionItemDao.findAll(questionId); PageInfo pageInfo = new PageInfo(all); return pageInfo; }catch (Exception e){ throw new RuntimeException(e); }finally { try { TransactionUtil.close(sqlSession); }catch (Exception e){ e.printStackTrace(); } } }
(13)修改持久层接口方法findAll
,添加查询参数
1 2 3 4 5 6 List<QuestionItem> findAll (String questionId) ;
(14)修改dao映射配置文件,添加条件
1 2 3 4 5 6 7 <select id ="findAll" parameterType ="java.lang.String" resultMap ="BaseResultMap" > select <include refid ="Base_Column_List" /> from st_question_item where question_id = #{questionId,jdbcType=VARCHAR}</select >
(15)对于业务层原有的不带任何参数的findAll
方法,我们可以去掉,删除接口和实现类中的无参的findAll
方法
(16)启动项目测试效果
5.2 添加功能制作 (1)在后台servlet的doGet
方法中去掉一些逻辑,toAdd
的逻辑判断和对应的toAdd
方法需要删除,然后直接查看save
方法
(2)save
方法最后需要去跳转页面,我们让它直接调用list
方法,该方法最后就是跳转页面的
1 2 3 4 5 6 7 8 private void save (HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { QuestionItem questionItem = BeanUtil.fillBean(request,QuestionItem.class,"yyyy-MM-dd"); questionItemService.save(questionItem); list(request,response); }
(3)找到questionItem
模块下的list.jsp
页面,在<form id="editForm">
该表单里面添加一个隐藏域,接收题目的id
1 <input type="hidden" name="questionId" value="${questionId}" >
同时要保证这个值能够在该页面中获取到,我们需要在跳转到该页面的后台list
方法中向request
域中存入该值即可,修改后台servlet的list
方法
1 2 3 4 5 6 7 8 9 10 11 private void list (HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { String questionId = request.getParameter("questionId" ); request.setAttribute("questionId" ,questionId); PageInfo all = questionItemService.findAll(questionId,1 , 100 ); request.setAttribute("page" ,all); request.getRequestDispatcher("/WEB-INF/pages/store/questionItem/list.jsp" ).forward(request,response); }
(4)启动项目进行测试
5.3 删除功能制作 (1)删除首先要解决的是删除完成后端页面跳转问题,需要修改后台servlet的delete
方法,删除完成后调用list
方法进行跳转
1 2 3 4 5 6 7 8 private void delete (HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { QuestionItem questionItem = BeanUtil.fillBean(request,QuestionItem.class ) ; questionItemService.delete(questionItem); list(request,response); }
(2)产生的新的问题是,删除后跳转回list.jsp
页面其他的数据都不见了,分析得到的原因是后台servlet执行完成删除调用list
方法时,需要去获取题目的id,来查询该题目下的所有选项,这个地方缺少了题目的id,因此解决方案是在页面发送删除请求时需要将题目id传递给后台,因此我们需要去修改页面删除的js代码
1 2 3 4 5 6 7 8 <script type="text/javascript" > function deleteById (id ) { var questionId = '${questionId}' ; if (confirm("你确认要删除此条记录吗?" )) { window .location.href="${ctx}/store/questionItem?operation=delete&questionId=${questionId}&id=" +id; } } </script>
(3)启动项目,进行测试
5.4 修改功能制作 (1)修改后台servlet的toEdit
方法,查询完数据后跳转页面仍然是调用list
方法完成跳转
1 2 3 4 5 6 7 8 9 private void toEdit (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String id = request.getParameter("id" ); QuestionItem questionItem = questionItemService.findById(id); request.setAttribute("questionItem" ,questionItem); list(request,response); }
(2)出现的问题是,点完编辑后跳转到页面上所有数据都无法显示,包括之前的所有选项数据,我们需要先来解决之前所有的选项数据的显示问题,原因很简单,还是因为在点击编辑的时候没有传递题目的id到后台,后台在通过list方法进行跳转的时候没有题目的id就无法查询题目下的选项
在questionItem/list.jsp
页面上修改编辑按钮,添加题目id的参数
1 <button type="button" class="btn bg-olive btn-xs" onclick='location.href="${ctx}/store/questionItem?operation=toEdit&questionId=${questionId}&id=${o.id}"'>编辑</button>
(3)然后在解决点完编辑后对应编辑的数据无法展示的问题,需要调整questionItem/list.jsp
页面表单,添加数据的展示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 <form id="editForm" action="${ctx}/store/questionItem?operation=saveOrUpdate" method="post" > <input type="hidden" name="questionId" value="${questionId}" > <input type="hidden" name="id" value="${questionItem.id}" > <div class ="row data-type" style="margin: 0px" > <div class="col-md-2 title">选项内容</div> <div class ="col-md-4 data" > <input type="text" class ="form-control" placeholder="选项内容" name="content" value="${questionItem.content}" > </div> <div class="col-md-2 title">选项图片</div> <div class ="col-md-4 data" > <input type="file" class ="form-control" placeholder="请选择" name="picture" > </div> <%--<div class="col-md-2 title">是否正确答案</div> <div class ="col-md-4 data" > <select class ="form-control" name="isRight" > <option value="">请选择</option> <option value="1">正确答案</option> <option value="0">错误选项</option> </select> </div>--%> <div class="col-md-2 title">是否正确答案</div> <div class ="col-md-4 data" > <select class ="form-control" name="isRight" > <option value="">请选择</option> <option value="1" ${questionItem.isRight eq "1" ? "selected" : ""}>正确答案</option> <option value="0" ${questionItem.isRight eq "0" ? "selected" : ""}>错误选项</option> </select> </div> </div> </form>
(4)启动后测试,发现了新的问题,我们要提交编辑的数据,但结果却变成了保存,问题的原因是什么呢?
经过分析发现是因为表单的提交路径一直写的就是保存的路径,如何解决呢?
通过后台传递一个操作类型的变量值到前端,前端在表单的action
里面使用该变量值,通过这个变量我们来控制是新增还是编辑
在后台的list
和toEdit
方法中来操作该变量值
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 private void list2 (HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { String questionId = request.getParameter("questionId" ); request.setAttribute("questionId" ,questionId); PageInfo all = questionItemService.findAll(questionId, 1 , 100 ); request.setAttribute("page" ,all); if (request.getAttribute("operation" ) == null ) { request.setAttribute("operation" , "save" ); } request.getRequestDispatcher("/WEB-INF/pages/store/questionItem/list.jsp" ).forward(request,response); }private void toEdit (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String id = request.getParameter("id" ); QuestionItem questionItem = questionItemService.findById(id); request.setAttribute("questionItem" ,questionItem); request.setAttribute("operation" ,"edit" ); list(request,response); }
然后需要在页面的表单action
属性上接收该值
1 <form id="editForm" action="${ctx}/store/questionItem?operation=${operation}" method="post" >
(5)启动项目进行测试
(6)测试发现编辑后,提交编辑的数据完成编辑哦呼跳转回页面,页面所有的数据又消失了,回到后台servlet查看edit
方法,发现是页面跳转的问题
1 2 3 4 5 6 7 8 private void edit (HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { QuestionItem questionItem = BeanUtil.fillBean(request,QuestionItem.class,"yyyy-MM-dd"); questionItemService.update(questionItem); list(request,response); }
(7)数据显示的问题解决后我们发现数据并没有真正的修改完成,分析原因发现是因为编辑后提交编辑的数据进行修改,但是没有提交问题选项的id值,我们需要在表单中接收问题选项的id值,能够让它在编辑的时候被提交到后台
1 <input type="hidden" name="id" value="${questionItem.id}" >
(8)启动项目进行测试
5.5 添加修改功能合并 (1)把questionItem/list.jsp
进行备份,questionItem/list2.jsp
(2)将后台list,toEdit
方法进行备份,分别叫做list2,toEdit2
,与前台的list2.jsp
配套,
(3)在后台servlet中封装一个saveOrUpdate
方法,同时需要修改doGet
方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 @Override protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String operation = request.getParameter("operation" ); if ("list" .equals(operation)){ this .list(request,response); }else if ("save" .equals(operation)){ this .save(request, response); }else if ("toEdit" .equals(operation)){ this .toEdit(request,response); }else if ("edit" .equals(operation)){ this .edit(request,response); }else if ("delete" .equals(operation)){ this .delete(request,response); }else if ("saveOrUpdate" .equals(operation)){ this .saveOrUpdate(request,response); } }private void saveOrUpdate (HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { QuestionItem questionItem = BeanUtil.fillBean(request,QuestionItem.class,"yyyy-MM-dd"); if (StringUtils.isNotBlank(questionItem.getId())){ questionItemService.update(questionItem); }else { questionItemService.save(questionItem); } list(request,response); }
(4)修改原始的list,toEdit
方法,不需要之前添加操作标识的变量了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 private void list (HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException { String questionId = request.getParameter("questionId" ); request.setAttribute("questionId" ,questionId); PageInfo all = questionItemService.findAll(questionId, 1 , 100 ); request.setAttribute("page" ,all); request.getRequestDispatcher("/WEB-INF/pages/store/questionItem/list.jsp" ).forward(request,response); }private void toEdit (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String id = request.getParameter("id" ); QuestionItem questionItem = questionItemService.findById(id); request.setAttribute("questionItem" ,questionItem); list(request,response); }
(5)修改list.jsp
页面表单的action
属性
1 <form id="editForm" action="${ctx}/store/questionItem?operation=saveOrUpdate" method="post" >
(6)启动项目测试
5.6 删除功能相关问题及解决方案 题目选项功能完成后,伴随而来的是题目的有些功能出现了问题,比如:删除题目,题目数据删除了,那该题目下的选项数据呢?目前是没有删除,
因此我们要解决的是:删除题目数据的时候伴随着删除该题目下的选项数据
解决方案
解决方案一:触发器
◆注意使用触发器实现是将业务绑定到了数据库端,在进行系统设计时要确认方案
解决方案二:业务层删除操作中分别调用两个模块的删除功能
◆注意删除主使用按id删除,删除从使用按关联id删除
◆注意删除的顺序,先删从,后删主
解决方案三:存储过程
◆整套的数据层解决方案,没有单一功能使用的
解决方案四:依赖框架提供的级联删除功能
解决方案五:定时维护/垃圾数据清理