長(zhǎng)春做網(wǎng)站企業(yè)重慶網(wǎng)站seo好不好
MVC設(shè)計(jì)模式
概念 - 代碼的分層
MVC:項(xiàng)目分層的思想
字母 | 表示 | 層 | 理解 |
---|---|---|---|
M | Modle | 模型層 | 業(yè)務(wù)的具體實(shí)現(xiàn) |
V | View | 視圖層 | 展示數(shù)據(jù) |
C | Controller | 控制器層 | 控制業(yè)務(wù)流程(跳轉(zhuǎn)) |
1.細(xì)化理解層數(shù)
Controller:控制器層,用于存放Servlet(頁面跳轉(zhuǎn))
View:視圖層,用于存放前端頁面(jsp)
Modle-Biz/service:邏輯業(yè)務(wù)層,用于存放業(yè)務(wù)具體的實(shí)現(xiàn)
Modle-Dao/mapper:數(shù)據(jù)持久層,用于存放操作數(shù)據(jù)的實(shí)現(xiàn)(數(shù)據(jù)的增刪改查)
MVC涉及到了前端,而后端只涉及到了MC
1.1 優(yōu)缺點(diǎn)
缺點(diǎn):使用MVC不能減少代碼量, 還會(huì)增加系統(tǒng)結(jié)構(gòu)和實(shí)現(xiàn)的復(fù)雜性
優(yōu)點(diǎn):整個(gè)項(xiàng)目結(jié)構(gòu)清晰,業(yè)務(wù)邏輯清晰,降低了代碼的耦合性,代碼的重用性高
注意:一般來說,使用設(shè)計(jì)模式都會(huì)增加代碼量
1.2 各層的命名規(guī)范
Controller控制器層:controller/servlet/action/web
Modle-Biz 邏輯業(yè)務(wù)層:service/biz
Modle-Dao 數(shù)據(jù)持久層:dao/persist/mapper
2.學(xué)生管理系統(tǒng) web2.0 mvc版本
具體的業(yè)務(wù)邏輯詳情請(qǐng)見 Day59 學(xué)生管理系統(tǒng) web1.0(直接使用servlet+jsp寫的),v2.0只是使用mvc分層思想進(jìn)行構(gòu)造
項(xiàng)目結(jié)構(gòu):(總結(jié)里有展示所有層)
注意:mapper層、service層、controller層
2.1 學(xué)生 student
StudentMapper
通過具體的業(yè)務(wù),判斷需要用到什么增刪查改,然后寫數(shù)據(jù)庫增刪查改的接口,讓實(shí)現(xiàn)類去實(shí)現(xiàn)
public interface StudentMapper {//添加學(xué)生public void add(String username,String password,String name,String sex,int age,String hobbies,String photo);//刪除學(xué)生,通過usernamepublic void delete(String username);//更新學(xué)生的密碼,通過username和newPasswordpublic void update(String username,String newPassword);//更新學(xué)生信息(除了密碼),通過username去操作,沒有更新照片public void update(String username,String name,String sex,int age,String hobbies);//更新學(xué)生信息(除了密碼),通過username更新,有更新照片public void update(String username,String name,String sex,int age,String hobbies,String photo);//獲取學(xué)生信息,通過usernamepublic Student getStudent(String username);//獲取學(xué)生信息,通過username和usernamepublic Student getStudent(String username,String password);//獲取學(xué)生的所有集合信息,用于分頁,offset--偏移量,count--數(shù)據(jù)條數(shù)public List<Student> getStudents(int offset,int count);//獲取當(dāng)前表的總條數(shù)public int getAllCount();
}
StudentMapperImpl
具體操作數(shù)據(jù)庫的增刪查改,可以使用自己寫的DBUtils 工具類
public class StudentMapperImpl implements StudentMapper {@Overridepublic void add(String username, String password, String name, String sex, int age, String hobbies, String photo) {try {DBUtils.commonUpdate("insert into student(username,password,name,sex,age,hobbies,photo) values(?,?,?,?,?,?,?)",username,password,name,sex,age, hobbies,photo);} catch (SQLException e) {throw new RuntimeException(e);}}@Overridepublic void delete(String username) {try {DBUtils.commonUpdate("delete from student where username = ?",username);} catch (SQLException e) {throw new RuntimeException(e);}}@Overridepublic void update(String username, String newPassword) {try {DBUtils.commonUpdate("update student set password=? where username=?",newPassword,username);} catch (SQLException e) {throw new RuntimeException(e);}}@Overridepublic void update(String username, String name, String sex, int age, String hobbies) {try {DBUtils.commonUpdate("update student set name=?,sex=?,age=?,hobbies=? where username=?",name,sex,age,hobbies,username);} catch (SQLException e) {throw new RuntimeException(e);}}@Overridepublic void update(String username, String name, String sex, int age, String hobbies, String photo) {try {DBUtils.commonUpdate("update student set name=?,sex=?,age=?,hobbies=?,photo=? where username=?",name,sex,age,hobbies,photo,username);} catch (SQLException e) {throw new RuntimeException(e);}}@Overridepublic Student getStudent(String username) {Student student = null;try {student = DBUtils.commonQueryObj(Student.class, "select * from student where username = ?", username);} catch (SQLException e) {throw new RuntimeException(e);}return student;}@Overridepublic Student getStudent(String username, String password) {Student student = null;try {student = DBUtils.commonQueryObj(Student.class, "select * from student where username = ? and password = ?", username, password);} catch (SQLException e) {throw new RuntimeException(e);}return student;}@Overridepublic List<Student> getStudents(int offset, int count) {List<Student> students = null;try {students = DBUtils.commonQueryList(Student.class, "select * from student limit ?,?", offset, count);} catch (SQLException e) {throw new RuntimeException(e);}return students;}@Overridepublic int getAllCount() {int allcount = 0;try {allcount = DBUtils.getAllCount("student");} catch (SQLException e) {throw new RuntimeException(e);}return allcount;}
}
service業(yè)務(wù)邏輯層
具體的業(yè)務(wù)流程,存放Servlet
不用進(jìn)行跳轉(zhuǎn),在Controller層進(jìn)行跳轉(zhuǎn)
有返回值的返回true/false就可以了
StudentService
public interface StudentService {//是否成功注冊(cè)功能public boolean isRegister(String username);//注冊(cè)功能public boolean register(HttpServletRequest request, HttpServletResponse response);//初始化學(xué)生信息功能public void initModify(HttpServletRequest request, HttpServletResponse response);//修改學(xué)生信息功能public void modify(HttpServletRequest request, HttpServletResponse response);//獲取學(xué)生信息列表,方便分頁public void getStudents(HttpServletRequest request, HttpServletResponse response);//刪除學(xué)生功能public void delete(HttpServletRequest request, HttpServletResponse response);//添加學(xué)生的功能public boolean add(HttpServletRequest request, HttpServletResponse response);
}
StudentServiceImpl
實(shí)現(xiàn) StudentService接口,寫具體的業(yè)務(wù)邏輯
public class StudentServiceImpl implements StudentService {private StudentMapper studentMapper = new StudentMapperImpl();//是否成功注冊(cè)功能@Overridepublic boolean isRegister(String username) {Student student = studentMapper.getStudent(username);if(student == null){//允許注冊(cè)return true;}return false;}//注冊(cè)功能(注冊(cè)表單是二進(jìn)制流,涉及到了圖片上傳)@Overridepublic boolean register(HttpServletRequest request, HttpServletResponse response) {ParseRequestData<Student> parseRequestData = ParseRequestDataUtils.parseRequest(request, Student.class, "upload\\student");Student stu = parseRequestData.getT();InputStream in = parseRequestData.getIn();OutputStream out = parseRequestData.getOut();boolean register = isRegister(stu.getUsername());if(register){//將數(shù)據(jù)插入到學(xué)生表中studentMapper.add(stu.getUsername(),stu.getPassword(),stu.getName(),stu.getSex(),stu.getAge(),stu.getHobbies(),stu.getPhoto());//將頭像存儲(chǔ)到本地磁盤try {IOUtils.copy(in,out);in.close();out.close();} catch (IOException e) {throw new RuntimeException(e);}return true;}else{try {in.close();out.close();} catch (IOException e) {throw new RuntimeException(e);}request.setAttribute("msg","注冊(cè)失敗 -- 賬號(hào)已注冊(cè)");return false;}}//初始化學(xué)生信息功能@Overridepublic void initModify(HttpServletRequest request, HttpServletResponse response) {String username = request.getParameter("username");Student student = studentMapper.getStudent(username);request.setAttribute("student",student);}//修改學(xué)生信息功能@Overridepublic void modify(HttpServletRequest request, HttpServletResponse response) {ParseRequestData<Student> parseRequestData = ParseRequestDataUtils.parseRequest(request, Student.class, "upload\\student");Student stu = parseRequestData.getT();InputStream in = parseRequestData.getIn();OutputStream out = parseRequestData.getOut();try {if(stu.getPhoto() != null){//說明用戶修改頭像studentMapper.update(stu.getUsername(),stu.getName(), stu.getSex(), stu.getAge(),stu.getHobbies(),stu.getPhoto());IOUtils.copy(in,out);//文件復(fù)制}else{studentMapper.update(stu.getUsername(),stu.getName(), stu.getSex(), stu.getAge(),stu.getHobbies());}if(in != null){in.close();}if(out != null){out.close();}} catch (IOException e) {throw new RuntimeException(e);}String role = (String) request.getSession().getAttribute("role");if("student".equals(role)){//更新Session里的數(shù)據(jù)request.getSession().setAttribute("name",stu.getName());//更新Cookie里的數(shù)據(jù)response.addCookie(CookieUtils.createCookie("name",stu.getName(),60*60*24*5));if(stu.getPhoto() != null){request.getSession().setAttribute("photo",stu.getPhoto());response.addCookie(CookieUtils.createCookie("photo",stu.getPhoto(),60*60*24*5));}}}//獲取學(xué)生信息列表,方便分頁@Overridepublic void getStudents(HttpServletRequest request, HttpServletResponse response) {//獲取當(dāng)前頁數(shù)int curPage = Integer.parseInt(request.getParameter("curPage"));//設(shè)置URLString url = "student?action=doGetStudents&curPage=";//設(shè)置當(dāng)前頁的數(shù)據(jù)條數(shù)int count = 15;//計(jì)算偏移量int offset = (curPage-1)*count;//計(jì)算總頁數(shù)int allCount = studentMapper.getAllCount();int totalPage = PageUtils.getTotalPage(allCount,count);//從數(shù)據(jù)庫獲取學(xué)生的集合List<Student> students = studentMapper.getStudents(offset,count);//處理學(xué)生集合List<StudentDto> studentDtos = DtoUtils.studentDtoListHandler(students);//封裝Page對(duì)象Page<StudentDto> page = new Page<>(url, curPage, totalPage, studentDtos);//將數(shù)據(jù)存入到請(qǐng)求對(duì)象中request.setAttribute("page",page);}//刪除學(xué)生功能@Overridepublic void delete(HttpServletRequest request, HttpServletResponse response) {String username = request.getParameter("username");studentMapper.delete(username);}//添加學(xué)生的功能@Overridepublic boolean add(HttpServletRequest request, HttpServletResponse response) {ParseRequestData<Student> parseRequestData = ParseRequestDataUtils.parseRequest(request, Student.class, "upload\\student");Student stu = parseRequestData.getT();InputStream in = parseRequestData.getIn();OutputStream out = parseRequestData.getOut();boolean register = isRegister(stu.getUsername());if(register){//將數(shù)據(jù)插入到學(xué)生表中studentMapper.add(stu.getUsername(),stu.getPassword(),stu.getName(),stu.getSex(),stu.getAge(),stu.getHobbies(),stu.getPhoto());//將頭像存儲(chǔ)到本地磁盤try {IOUtils.copy(in,out);in.close();out.close();} catch (IOException e) {throw new RuntimeException(e);}return true;}else{try {in.close();out.close();} catch (IOException e) {throw new RuntimeException(e);}request.setAttribute("msg","添加失敗 -- 賬號(hào)已添加");return false;}}}
ParseRequestDataUtils
package com.qf.utils;public class ParseRequestDataUtils {public static <T> ParseRequestData parseRequest(HttpServletRequest request,Class<T> clazz,String path){ParseRequestData<T> parseRequestData = new ParseRequestData<>();//創(chuàng)建文件上傳工廠類的對(duì)象DiskFileItemFactory factory = new DiskFileItemFactory();//創(chuàng)建文件上傳類的對(duì)象ServletFileUpload upload = new ServletFileUpload(factory);HashMap<String, String> map = new HashMap<>();try {//解析請(qǐng)求List<FileItem> list = upload.parseRequest(request);for (FileItem fileItem : list) {if(fileItem.isFormField()){//文本數(shù)據(jù)String name = fileItem.getFieldName();String value = fileItem.getString("UTF-8");String v = map.get(name);if(v == null){//說明是第一次添加map.put(name,value);}else{//不是第一次添加就需要拼接(多選框的情況)map.put(name,v + "," + value);}}else{//二進(jìn)制數(shù)據(jù)//D:\\apache-tomcat-8.0.49\\webapps\\Day23_upload_war_exploded\\upload\\student//D:\\apache-tomcat-8.0.49\\webapps\\Day23_upload_war_exploded\\upload\\teacherString realPath = request.getServletContext().getRealPath(path);//文件存儲(chǔ)目錄 -- 自定義路徑\\用戶名realPath = realPath + File.separator + map.get("username");File file = new File(realPath);if(!file.exists()){file.mkdirs();}String fileName = fileItem.getName();//獲取文件名//自定義路徑\\用戶名\\tx01.jpgrealPath = realPath + File.separator + fileName;//拼接路徑InputStream in = fileItem.getInputStream();if(in.available() != 0){FileOutputStream out = new FileOutputStream(realPath);parseRequestData.setIn(in);parseRequestData.setOut(out);map.put("photo",path + File.separator + map.get("username") + File.separator + fileName);}}}} catch (FileUploadException e) {throw new RuntimeException(e);} catch (FileNotFoundException e) {throw new RuntimeException(e);} catch (IOException e) {throw new RuntimeException(e);}Set<Map.Entry<String, String>> entries = map.entrySet();for (Map.Entry<String, String> entry : entries) {System.out.println(entry);}T t = null;try {t = clazz.newInstance();//將map中的數(shù)據(jù)映射到實(shí)體類對(duì)象中BeanUtils.populate(t,map);} catch (IllegalAccessException e) {throw new RuntimeException(e);} catch (InvocationTargetException e) {throw new RuntimeException(e);} catch (InstantiationException e) {throw new RuntimeException(e);}parseRequestData.setT(t);return parseRequestData;}
}
controller
根據(jù)每一個(gè)前端傳過來的action功能來判斷跳轉(zhuǎn)
判斷功能進(jìn)行頁面跳轉(zhuǎn)
action=“student?action=doRegister”,前端設(shè)置路徑加上action=xxx功能
Controller進(jìn)行具體的判斷,成功就重定向,失敗就轉(zhuǎn)發(fā)
@WebServlet("/student")
public class StudentController extends BaseServlet {private StudentService studentService = new StudentServiceImpl();//注冊(cè)功能public void doRegister(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {boolean register = studentService.register(request, response);if(register){response.sendRedirect("login.jsp");}else{request.getRequestDispatcher("register.jsp").forward(request,response);}}//初始化修改功能public void doInitModify(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {studentService.initModify(request,response);request.getRequestDispatcher("stuInfo.jsp").forward(request,response);}//修改功能public void doModify(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {studentService.modify(request,response);String role = (String) request.getSession().getAttribute("role");if("student".equals(role)){response.sendRedirect("index.jsp");}else if("teacher".equals(role)){request.getRequestDispatcher("student?action=doGetStudents&curPage=1").forward(request,response);}else if("admin".equals(role)){request.getRequestDispatcher("student?action=doGetStudents&curPage=1").forward(request,response);}}//展示數(shù)據(jù)功能public void doGetStudents(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {studentService.getStudents(request,response);request.getRequestDispatcher("stuList.jsp").forward(request,response);}//刪除功能public void doDelete(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {studentService.delete(request,response);request.getRequestDispatcher("student?action=doGetStudents&curPage=1").forward(request,response);}//添加學(xué)生功能public void doAddStu(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {boolean register = studentService.register(request, response);if(register){request.getRequestDispatcher("student?action=doGetStudents&curPage=1").forward(request,response);}else{request.getRequestDispatcher("stuAdd.jsp").forward(request,response);}}//是否注冊(cè)學(xué)生的提示功能(ajax)public void isRegister(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {String username = request.getParameter("username");boolean register = studentService.isRegister(username);String code;if(register){code="1";}else {code="-1";}response.getWriter().write(code);}
}
BaseServlet
給控制層重寫的servlet,以前繼承HttpServlet,就會(huì)寫很多的if-else判斷,太麻煩了
package com.qf.servlet;public class BaseServlet extends HttpServlet {@Overrideprotected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {this.doPost(request, response);}@Overrideprotected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//url -- http://localhost:8080/Day24_MVC_war_exploded/user?action=doLoginString action = request.getParameter("action");//doLogin//獲取Controller類的class對(duì)象Class<? extends BaseServlet> clazz = this.getClass();try {//根據(jù)action獲取Controller類對(duì)應(yīng)的方法對(duì)象Method method = clazz.getDeclaredMethod(action, HttpServletRequest.class, HttpServletResponse.class);//設(shè)置操作權(quán)限method.setAccessible(true);//調(diào)用方法method.invoke(this,request,response);} catch (NoSuchMethodException e) {throw new RuntimeException(e);} catch (InvocationTargetException e) {throw new RuntimeException(e);} catch (IllegalAccessException e) {throw new RuntimeException(e);}}
}
2.2 老師 teacher
TeacherMapper
明確數(shù)據(jù)庫的功能
public interface TeacherMapper {//添加老師public void add(String username,String password,String name,String sex,int age,int courseId,String photo);//刪除老師,通過usernamepublic void delete(String username);//更新老師的密碼,通過username和newPasswordpublic void update(String username,String newPassword);//更新老師信息(除了密碼),通過username去操作,沒有更新照片public void update(String username,String name,String sex,int age,int courseId);//更新老師信息(除了密碼),通過username更新,有更新照片public void update(String username,String name,String sex,int age,int courseId,String photo);//獲取老師信息,通過usernamepublic Teacher getTeacher(String username);//獲取老師信息,通過username和usernamepublic Teacher getTeacher(String username,String password);//獲取老師的所有集合信息,用于分頁,offset--偏移量,count--數(shù)據(jù)條數(shù)public List<Teacher> getTeachers(int offset,int count);//獲取當(dāng)前表的總條數(shù)public int getAllCount();
}
StudentMapperImpl
public class StudentMapperImpl implements StudentMapper {@Overridepublic void add(String username, String password, String name, String sex, int age, String hobbies, String photo) {try {DBUtils.commonUpdate("insert into student(username,password,name,sex,age,hobbies,photo) values(?,?,?,?,?,?,?)",username,password,name,sex,age, hobbies,photo);} catch (SQLException e) {throw new RuntimeException(e);}}@Overridepublic void delete(String username) {try {DBUtils.commonUpdate("delete from student where username = ?",username);} catch (SQLException e) {throw new RuntimeException(e);}}@Overridepublic void update(String username, String newPassword) {try {DBUtils.commonUpdate("update student set password=? where username=?",newPassword,username);} catch (SQLException e) {throw new RuntimeException(e);}}@Overridepublic void update(String username, String name, String sex, int age, String hobbies) {try {DBUtils.commonUpdate("update student set name=?,sex=?,age=?,hobbies=? where username=?",name,sex,age,hobbies,username);} catch (SQLException e) {throw new RuntimeException(e);}}@Overridepublic void update(String username, String name, String sex, int age, String hobbies, String photo) {try {DBUtils.commonUpdate("update student set name=?,sex=?,age=?,hobbies=?,photo=? where username=?",name,sex,age,hobbies,photo,username);} catch (SQLException e) {throw new RuntimeException(e);}}@Overridepublic Student getStudent(String username) {Student student = null;try {student = DBUtils.commonQueryObj(Student.class, "select * from student where username = ?", username);} catch (SQLException e) {throw new RuntimeException(e);}return student;}@Overridepublic Student getStudent(String username, String password) {Student student = null;try {student = DBUtils.commonQueryObj(Student.class, "select * from student where username = ? and password = ?", username, password);} catch (SQLException e) {throw new RuntimeException(e);}return student;}@Overridepublic List<Student> getStudents(int offset, int count) {List<Student> students = null;try {students = DBUtils.commonQueryList(Student.class, "select * from student limit ?,?", offset, count);} catch (SQLException e) {throw new RuntimeException(e);}return students;}@Overridepublic int getAllCount() {int allcount = 0;try {allcount = DBUtils.getAllCount("student");} catch (SQLException e) {throw new RuntimeException(e);}return allcount;}
}
業(yè)務(wù)邏輯層
TeacherService
public interface TeacherService {public boolean isAdd(String username);public boolean add(HttpServletRequest request, HttpServletResponse response);public void initModify(HttpServletRequest request, HttpServletResponse response);public void modify(HttpServletRequest request, HttpServletResponse response);public void getTeachers(HttpServletRequest request, HttpServletResponse response);public void delete(HttpServletRequest request, HttpServletResponse response);
}
TeacherServiceImpl
public class TeacherServiceImpl implements TeacherService {private TeacherMapper teacherMapper = new TeacherMapperImpl();private CourseService courseService = new CourseServiceImpl();@Overridepublic boolean isAdd(String username) {Teacher teacher = teacherMapper.getTeacher(username);if(teacher == null){return true;}return false;}@Overridepublic boolean add(HttpServletRequest request, HttpServletResponse response) {ParseRequestData<Teacher> parseRequestData = ParseRequestDataUtils.parseRequest(request, Teacher.class, "upload\\teacher");Teacher t = parseRequestData.getT();InputStream in = parseRequestData.getIn();OutputStream out = parseRequestData.getOut();boolean add = isAdd(t.getUsername());if(add){//將數(shù)據(jù)插入到老師表中teacherMapper.add(t.getUsername(),t.getPassword(),t.getName(),t.getSex(),t.getAge(),t.getCourseId(),t.getPhoto());//將頭像存儲(chǔ)到本地磁盤try {IOUtils.copy(in,out);in.close();out.close();} catch (IOException e) {throw new RuntimeException(e);}return true;}else{try {in.close();out.close();} catch (IOException e) {throw new RuntimeException(e);}request.setAttribute("msg","添加失敗 -- 賬號(hào)已存在");return false;}}@Overridepublic void initModify(HttpServletRequest request, HttpServletResponse response) {String username = request.getParameter("username");Teacher teacher = teacherMapper.getTeacher(username);request.setAttribute("teacher",teacher);courseService.getCourses(request,response);}@Overridepublic void modify(HttpServletRequest request, HttpServletResponse response) {ParseRequestData<Teacher> parseRequestData = ParseRequestDataUtils.parseRequest(request, Teacher.class, "upload\\teacher");Teacher tea = parseRequestData.getT();InputStream in = parseRequestData.getIn();OutputStream out = parseRequestData.getOut();try {if(tea.getPhoto() != null){//說明用戶修改頭像teacherMapper.update(tea.getUsername(),tea.getName(), tea.getSex(), tea.getAge(),tea.getCourseId(),tea.getPhoto());IOUtils.copy(in,out);}else{teacherMapper.update(tea.getUsername(),tea.getName(), tea.getSex(), tea.getAge(),tea.getCourseId());}if(in != null){in.close();}if(out != null){out.close();}} catch (IOException e) {throw new RuntimeException(e);}String role = (String) request.getSession().getAttribute("role");if("teacher".equals(role)){//更新Session里的數(shù)據(jù)request.getSession().setAttribute("name",tea.getName());//更新Cookie里的數(shù)據(jù)response.addCookie(CookieUtils.createCookie("name",tea.getName(),60*60*24*5));if (tea.getPhoto() != null){request.getSession().setAttribute("photo",tea.getPhoto());response.addCookie(CookieUtils.createCookie("photo",tea.getPhoto(),60*60*24*5));}}}@Overridepublic void getTeachers(HttpServletRequest request, HttpServletResponse response) {//獲取當(dāng)前頁數(shù)int curPage = Integer.parseInt(request.getParameter("curPage"));//設(shè)置URLString url = "teacher?action=doGetTeachers&curPage=";//設(shè)置當(dāng)前頁的數(shù)據(jù)條數(shù)int count = 15;//計(jì)算偏移量int offset = (curPage-1)*count;//計(jì)算總頁數(shù)int allCount = teacherMapper.getAllCount();int totalPage = PageUtils.getTotalPage(allCount,count);//從數(shù)據(jù)庫獲取老師的集合List<Teacher> teachers = teacherMapper.getTeachers(offset,count);//處理老師集合List<TeacherDto> teacherDtos = DtoUtils.teacherDtoListHandler(teachers);//封裝Page對(duì)象Page<TeacherDto> page = new Page<>(url, curPage, totalPage, teacherDtos);//將數(shù)據(jù)存入到請(qǐng)求對(duì)象中request.setAttribute("page",page);}@Overridepublic void delete(HttpServletRequest request, HttpServletResponse response) {String username = request.getParameter("username");teacherMapper.delete(username);}
}
控制器層
TeacherController
@WebServlet("/teacher")
public class TeacherController extends BaseServlet {private TeacherService teacherService = new TeacherServiceImpl();public void doInitModify(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {teacherService.initModify(request,response);request.getRequestDispatcher("teaInfo.jsp").forward(request,response);}public void doModify(HttpServletRequest request,HttpServletResponse response) throws IOException, ServletException {teacherService.modify(request,response);request.getRequestDispatcher("teacher?action=doGetTeachers&curPage=1").forward(request,response);}public void doGetTeachers(HttpServletRequest request,HttpServletResponse response) throws IOException, ServletException {teacherService.getTeachers(request,response);request.getRequestDispatcher("TeaList.jsp").forward(request,response);}public void doDelete(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {teacherService.delete(request,response);request.getRequestDispatcher("teacher?action=doGetTeachers&curPage=1").forward(request,response);}public void doAddTea(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {boolean add = teacherService.add(request,response);if(add){request.getRequestDispatcher("teacher?action=doGetTeachers&curPage=1").forward(request,response);}else{request.getRequestDispatcher("teaAdd.jsp").forward(request,response);}}}
2.3 用戶 user
user是學(xué)生和老師的父類,兩個(gè)都有的功能就寫在user里
注意:在數(shù)據(jù)庫中沒有user這個(gè)表,這是把學(xué)生和老師相同的功能提出來了,放在user里
UserService
public interface UserService {//繪制驗(yàn)證碼功能public void drawCode(HttpServletRequest request, HttpServletResponse response);//登錄功能public boolean login(HttpServletRequest request, HttpServletResponse response);//記住我功能public void rememberMe(HttpServletResponse response,String username,String name,String role,String photo);//安全退出功能public void loginOut(HttpServletRequest request, HttpServletResponse response);//修改驗(yàn)證碼功能public boolean resetPassword(HttpServletRequest request, HttpServletResponse response);}
UserServiceImpl
public class UserServiceImpl implements UserService {private StudentMapper studentMapper = new StudentMapperImpl();private TeacherMapper teacherMapper = new TeacherMapperImpl();private AdminMapper adminMapper= new AdminMapperImpl();//繪制驗(yàn)證碼功能@Overridepublic void drawCode(HttpServletRequest request, HttpServletResponse response) {//設(shè)置寬高的變量int width = 120;int height = 30;//創(chuàng)建畫布BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);//獲取畫筆Graphics graphics = image.getGraphics();//設(shè)置背景色 -- 填充矩形graphics.setColor(Color.BLUE);graphics.fillRect(0,0,width,height);//設(shè)置驗(yàn)證碼Random random = new Random();String[] codes = {"A","B","C","D","E","F","G","H","J","K","M","N","P","Q","R","S","T","U","V","W","X","Y","Z","0","1","2","3","4","5","6","7","8","9"};Color[] colors = {Color.CYAN,Color.BLACK,Color.GREEN,Color.PINK,Color.WHITE,Color.RED,Color.ORANGE};StringBuffer sb = new StringBuffer();for (int i = 0; i < 4; i++) {String randomCode = codes[random.nextInt(codes.length)];Color randomColor = colors[random.nextInt(colors.length)];graphics.setColor(randomColor);//設(shè)置隨機(jī)顏色graphics.setFont(new Font("宋體",Font.BOLD,20+random.nextInt(10)));//設(shè)置字體(字體,樣式,大小)graphics.drawString(randomCode,20+i*25,15+random.nextInt(10));//設(shè)置單個(gè)驗(yàn)證碼sb.append(randomCode);}//將系統(tǒng)驗(yàn)證碼設(shè)置到Session對(duì)象中(會(huì)話對(duì)象)HttpSession session = request.getSession();//獲取請(qǐng)求里的JSESSIONID(客戶端Cookie里的數(shù)據(jù)),如果沒有就創(chuàng)建Session對(duì)象,如果有就從Session容器中獲取會(huì)話對(duì)象session.setAttribute("sysCode",sb.toString());//設(shè)置干擾線graphics.setColor(Color.YELLOW);for (int i = 0; i < 3; i++) {graphics.drawLine(random.nextInt(width),random.nextInt(height),random.nextInt(width),random.nextInt(height));//繪制直線(x1,y1,x2,y2) -> 兩點(diǎn)為一線}//將畫布以jpg形式的文件傳出給客戶端try {ImageIO.write(image,"jpg",response.getOutputStream());} catch (IOException e) {throw new RuntimeException(e);}}//登錄功能@Overridepublic boolean login(HttpServletRequest request, HttpServletResponse response) {//獲取請(qǐng)求中的數(shù)據(jù)String username = request.getParameter("username");String password = request.getParameter("password");String userCode = request.getParameter("userCode");String rememberMe = request.getParameter("rememberMe");String role = request.getParameter("role");//從Session對(duì)象中獲取系統(tǒng)的驗(yàn)證碼String sysCode = (String) request.getSession().getAttribute("sysCode");if(sysCode.equalsIgnoreCase(userCode)){//驗(yàn)證碼正確User user = null;if("student".equals(role)){user = studentMapper.getStudent(username,password);}else if("teacher".equals(role)){user = teacherMapper.getTeacher(username,password);} else if ("admin".equals(role)) {user = adminMapper.getAdmin(username, password);}if(user != null){//登錄成功//判斷是否記住我if(rememberMe != null){if("admin".equals(role)){rememberMe(response,user.getUsername(),user.getPassword(),role);HttpSession session = request.getSession();session.setAttribute("username",user.getUsername());session.setAttribute("password",user.getPassword());session.setAttribute("role",role);return true;}else if ("student".equals(role) || "teacher".equals(role)){rememberMe(response,user.getUsername(),user.getName() ,role,user.getPhoto());//將數(shù)據(jù)存儲(chǔ)到Session中HttpSession session = request.getSession();session.setAttribute("username",user.getUsername());session.setAttribute("name",user.getName());session.setAttribute("role",role);session.setAttribute("photo",user.getPhoto());return true;}}if("admin".equals(role)){HttpSession session = request.getSession();session.setAttribute("username",user.getUsername());session.setAttribute("name",user.getPassword());session.setAttribute("role",role);}else if ("student".equals(role) || "teacher".equals(role)){//將數(shù)據(jù)存儲(chǔ)到Session中HttpSession session = request.getSession();session.setAttribute("username",user.getUsername());session.setAttribute("name",user.getName());session.setAttribute("role",role);session.setAttribute("photo",user.getPhoto());}return true;}else{//登錄失敗 -- 賬號(hào)或密碼錯(cuò)誤request.setAttribute("msg","登錄失敗 -- 賬號(hào)或密碼錯(cuò)誤");return false;}}else{//登錄失敗 - 驗(yàn)證碼錯(cuò)誤request.setAttribute("msg","登錄失敗 -- 驗(yàn)證碼錯(cuò)誤");return false;}}//管理員的記住我private void rememberMe(HttpServletResponse response, String username, String password, String role) {response.addCookie(CookieUtils.createCookie("username",username,60*60*24*5));response.addCookie(CookieUtils.createCookie("password",password,60*60*24*5));response.addCookie(CookieUtils.createCookie("role",role,60*60*24*5));}//記住我功能@Overridepublic void rememberMe(HttpServletResponse response,String username, String name, String role, String photo) {//將憑證添加到Cookie中response.addCookie(CookieUtils.createCookie("username",username,60*60*24*5));response.addCookie(CookieUtils.createCookie("name",name,60*60*24*5));response.addCookie(CookieUtils.createCookie("role",role,60*60*24*5));response.addCookie(CookieUtils.createCookie("photo",photo,60*60*24*5));}//安全退出功能@Overridepublic void loginOut(HttpServletRequest request, HttpServletResponse response) {//刪除Cookie里的數(shù)據(jù)response.addCookie(CookieUtils.createCookie("username","",0));response.addCookie(CookieUtils.createCookie("name","",0));response.addCookie(CookieUtils.createCookie("role","",0));response.addCookie(CookieUtils.createCookie("photo","",0));response.addCookie(CookieUtils.createCookie("password","",0));//刪除Session里的數(shù)據(jù)HttpSession session = request.getSession();session.removeAttribute("username");session.removeAttribute("name");session.removeAttribute("role");session.removeAttribute("photo");session.removeAttribute("password");}//修改密碼功能@Overridepublic boolean resetPassword(HttpServletRequest request, HttpServletResponse response) {//獲取請(qǐng)求中的數(shù)據(jù)String username = request.getParameter("username");String password = request.getParameter("password");String newPassword = request.getParameter("newPassword");String role = request.getParameter("role");User user = null;if("student".equals(role)){user = studentMapper.getStudent(username,password);}else if("teacher".equals(role)){user = teacherMapper.getTeacher(username,password);} else if ("admin".equals(role)) {user = adminMapper.getAdmin(username, password);}if(user != null){if("student".equals(role)){studentMapper.update(username,newPassword);}else if("teacher".equals(role)){teacherMapper.update(username,newPassword);} else if ("admin".equals(role)) {adminMapper.update(username,newPassword);}return true;}else{request.setAttribute("msg","修改密碼失敗 -- 原密碼不正確");return false;}}
}
UserController
,前端傳過來的路徑中帶有action=“xxx功能”,然后進(jìn)行xxx功能的相關(guān)業(yè)務(wù)的跳轉(zhuǎn)
@WebServlet("/user")
public class UserController extends BaseServlet {private UserService userService = new UserServiceImpl();public void doDrawCode(HttpServletRequest request,HttpServletResponse response){userService.drawCode(request,response);}public void doLogin(HttpServletRequest request,HttpServletResponse response) throws IOException, ServletException {boolean login = userService.login(request, response);if(login){response.sendRedirect("index.jsp");}else{request.getRequestDispatcher("login.jsp").forward(request,response);}}public void doLoginOut(HttpServletRequest request,HttpServletResponse response) throws IOException {userService.loginOut(request, response);response.sendRedirect("welcome.html");}public void doResetPassword(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {boolean resetPassword = userService.resetPassword(request, response);if(resetPassword){request.getRequestDispatcher("user?action=doLoginOut").forward(request,response);}else{request.getRequestDispatcher("resetPassword.jsp").forward(request,response);}}}
2.4 管理員
功能:
1.登錄(user里有)
2.修改密碼(user里有)
3.管理老師 – 老師列表頁面(分頁、修改、刪除、添加)
4.管理學(xué)科 – 學(xué)科列表頁面(展示所有學(xué)科、修改、刪除、添加)
5.管理學(xué)生 – 學(xué)生列表頁面(分頁、修改、刪除、添加)
實(shí)體類 Admin 直接繼承user類
SQL – admin :username、password
public class Admin extends User{}
AdminMapper
public interface AdminMapper {//獲取管理員信息,通過usernamepublic Admin getAdmin(String username);//獲取管理員信息,通過username和usernamepublic Admin getAdmin(String username,String password);//更新管理員的密碼,通過username和newPasswordpublic void update(String username,String newPassword);
}
AdminMapperImpl
public class AdminMapperImpl implements AdminMapper {@Overridepublic Admin getAdmin(String username) {Admin admin=null;try {admin = DBUtils.commonQueryObj(Admin.class, "select * from admin where username =?", username);} catch (SQLException e) {throw new RuntimeException(e);}return admin;}@Overridepublic Admin getAdmin(String username, String password) {Admin admin=null;try {admin = DBUtils.commonQueryObj(Admin.class, "select * from admin where username =? and password=?", username,password);} catch (SQLException e) {throw new RuntimeException(e);}return admin;}@Overridepublic void update(String username, String newPassword) {try {DBUtils.commonUpdate("update admin set password = ? where username =?", newPassword, username);} catch (SQLException e) {throw new RuntimeException(e);}}
}
AdminService
都是uer里寫了的,就沒有AdminServiceImpl,controller層也沒有,直接在index.jsp跳轉(zhuǎn)就可以了
public interface AdminService {//登錄功能public boolean login(HttpServletRequest request, HttpServletResponse response);//修改驗(yàn)證碼功能public boolean resetPassword(HttpServletRequest request, HttpServletResponse response);
}
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<head><title>Title</title>
</head>
<body><button οnclick="safeExit()">安全退出</button><h1>詳情頁面</h1><c:if test="${role eq 'admin'}"><h1>歡迎管理員進(jìn)入到學(xué)生管理系統(tǒng)</h1></c:if><c:if test="${role eq 'student' || role eq 'teacher'}"><h1>歡迎${name}${(role eq "student")?"學(xué)員":""}${(role eq "teacher")?"老師":""}進(jìn)入到學(xué)生管理系統(tǒng)</h1><img src="${photo}" width="100px" height="100px"><br/></c:if><a href="resetPassword.jsp">修改密碼</a><c:if test="${role eq 'admin'}"><a href="student?action=doGetStudents&curPage=1">管理學(xué)生</a><a href="teacher?action=doGetTeachers&curPage=1">管理老師</a><a href="course?action=doGetCourses">管理學(xué)科</a></c:if><c:if test="${role eq 'student'}"><a href="student?action=doInitModify&username=${username}">修改信息</a></c:if><c:if test="${role eq 'teacher'}"><a href="teacher?action=doInitModify&username=${username}">修改信息</a><a href="student?action=doGetStudents&curPage=1">查看所有學(xué)生</a></c:if><script type="text/javascript">function safeExit(){window.location = "user?action=doLoginOut";}</script>
</body>
</html>
2.5 其他補(bǔ)充
數(shù)據(jù)庫工具類DBUtils
package com.qf.utils;public class DBUtils {private static DruidDataSource pool;private static ThreadLocal<Connection> local;static{Properties properties = new Properties();try {properties.load(DBUtils.class.getClassLoader().getResourceAsStream("DBConfig.properties"));} catch (IOException e) {throw new RuntimeException(e);}String driverClassName = properties.getProperty("driverClassName");String url = properties.getProperty("url");String username = properties.getProperty("username");String password = properties.getProperty("password");int maxActive = Integer.parseInt(properties.getProperty("maxActive"));//初始化數(shù)據(jù)庫連接池pool = new DruidDataSource();//設(shè)置參數(shù)pool.setDriverClassName(driverClassName);pool.setUrl(url);pool.setUsername(username);pool.setPassword(password);pool.setMaxActive(maxActive);local = new ThreadLocal<>();}/*** 獲取連接對(duì)象*/public static Connection getConnection() throws SQLException {Connection connection = local.get();//獲取當(dāng)前線程的Connection對(duì)象if(connection == null){connection = pool.getConnection();//獲取數(shù)據(jù)庫連接池里的連接對(duì)象local.set(connection);//將Connection對(duì)象添加到local中}return connection;}/*** 關(guān)閉資源*/public static void close(Connection connection, Statement statement, ResultSet resultSet){if(resultSet != null){try {resultSet.close();} catch (SQLException e) {throw new RuntimeException(e);}}if(statement != null){try {statement.close();} catch (SQLException e) {throw new RuntimeException(e);}}if(connection != null){try {if(connection.getAutoCommit()){connection.close();local.set(null);}} catch (SQLException e) {throw new RuntimeException(e);}}}/*** 開啟事務(wù)*/public static void startTransaction() throws SQLException {Connection connection = getConnection();connection.setAutoCommit(false);}/*** 提交事務(wù)*/public static void commit() throws SQLException {Connection connection = local.get();if(connection != null){connection.commit();connection.close();local.set(null);}}public static void rollback() throws SQLException {Connection connection = local.get();if(connection != null){connection.rollback();connection.close();local.set(null);}}/*** 更新數(shù)據(jù)(添加、刪除、修改)*/public static int commonUpdate(String sql,Object... params) throws SQLException {Connection connection = null;PreparedStatement statement = null;try {connection = getConnection();statement = connection.prepareStatement(sql);paramHandler(statement,params);int num = statement.executeUpdate();return num;}finally {close(connection,statement,null);}}/*** 添加數(shù)據(jù) - 主鍵回填(主鍵是int類型可以返回)*/public static int commonInsert(String sql,Object... params) throws SQLException {Connection connection = null;PreparedStatement statement = null;ResultSet resultSet = null;try {connection = getConnection();statement = connection.prepareStatement(sql,PreparedStatement.RETURN_GENERATED_KEYS);paramHandler(statement,params);statement.executeUpdate();resultSet = statement.getGeneratedKeys();int primaryKey = 0;if(resultSet.next()){primaryKey = resultSet.getInt(1);}return primaryKey;}finally {close(connection,statement,resultSet);}}/*** 查詢多個(gè)數(shù)據(jù)*/public static <T> List<T> commonQueryList(Class<T> clazz,String sql, Object... params) throws SQLException{Connection connection = null;PreparedStatement statement = null;ResultSet resultSet = null;try {connection = getConnection();statement = connection.prepareStatement(sql);paramHandler(statement,params);resultSet = statement.executeQuery();//獲取表數(shù)據(jù)對(duì)象ResultSetMetaData metaData = resultSet.getMetaData();//獲取字段個(gè)數(shù)int count = metaData.getColumnCount();List<T> list = new ArrayList<>();while(resultSet.next()){T t = null;try {t = clazz.newInstance();} catch (InstantiationException e) {throw new RuntimeException(e);} catch (IllegalAccessException e) {throw new RuntimeException(e);}//獲取字段名及數(shù)據(jù)for (int i = 1; i <= count; i++) {String fieldName = metaData.getColumnName(i);Object fieldVal = resultSet.getObject(fieldName);setField(t,fieldName,fieldVal);}list.add(t);}return list;} finally {DBUtils.close(connection,statement,resultSet);}}/*** 查詢單個(gè)數(shù)據(jù)*/public static <T> T commonQueryObj(Class<T> clazz,String sql, Object... params) throws SQLException{Connection connection = null;PreparedStatement statement = null;ResultSet resultSet = null;try {connection = getConnection();statement = connection.prepareStatement(sql);paramHandler(statement,params);resultSet = statement.executeQuery();//獲取表數(shù)據(jù)對(duì)象ResultSetMetaData metaData = resultSet.getMetaData();//獲取字段個(gè)數(shù)int count = metaData.getColumnCount();if(resultSet.next()){T t = null;try {t = clazz.newInstance();} catch (InstantiationException e) {throw new RuntimeException(e);} catch (IllegalAccessException e) {throw new RuntimeException(e);}//獲取字段名及數(shù)據(jù)for (int i = 1; i <= count; i++) {String fieldName = metaData.getColumnName(i);Object fieldVal = resultSet.getObject(fieldName);setField(t,fieldName,fieldVal);}return t;}} finally {DBUtils.close(connection,statement,resultSet);}return null;}/*** 獲取當(dāng)前表的總條數(shù)*/public static int getAllCount(String table) throws SQLException {Connection connection = getConnection();String sql = "select count(1) from " + table;PreparedStatement statement = connection.prepareStatement(sql);ResultSet resultSet = statement.executeQuery();if(resultSet.next()){int allCount = resultSet.getInt(1);return allCount;}return 0;}/*** 處理statement對(duì)象參數(shù)數(shù)據(jù)的處理器*/private static void paramHandler(PreparedStatement statement,Object... params) throws SQLException {for (int i = 0; i < params.length; i++) {statement.setObject(i+1,params[i]);}}/*** 獲取當(dāng)前類及其父類的屬性對(duì)象* @param clazz class對(duì)象* @param name 屬性名* @return 屬性對(duì)象*/private static Field getField(Class<?> clazz,String name){for(Class<?> c = clazz;c != null;c = c.getSuperclass()){try {Field field = c.getDeclaredField(name);return field;} catch (NoSuchFieldException e) {} catch (SecurityException e) {}}return null;}/*** 設(shè)置對(duì)象中的屬性* @param obj 對(duì)象* @param name 屬性名* @param value 屬性值*/private static void setField(Object obj,String name,Object value){Field field = getField(obj.getClass(), name);if(field != null){field.setAccessible(true);try {field.set(obj, value);} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}}}}
其余代碼太多,不一一展示
總結(jié)
1…MVC
注意:MVC設(shè)計(jì)模式和服務(wù)端分層思想的區(qū)別2.MVC版本的學(xué)生管理系統(tǒng)