一、MVC
1.1概念
Model-View-Controller(模型—視圖—控制器)
視圖:頁面。作用 :
顯示相關數據、接受用戶輸入、不進行實際的業務處理(Model做)
控制器:接收用戶的輸入並調用模型處理請求,調用視圖返回數據
模型:是應用程序的主體部分,表示業務邏輯和業務數據
一個模型能爲多個視圖提供數據
Servlet——控制器。接收請求,調用類方法。 POJO——處理邏輯、業務邏輯、處理數據庫 轉向——目前兩種方式:轉發,重定向 |
二、簡單MVC案例
2.1 設計原理
簡單MVC設計模式:
① test.jsp——發送請求到Servlet(listAllStudents)
<a href="listAllStudents">List All Students</a> |
② Servlet——daGet方法:往屬性域裏放一個屬性
通過轉發的方式到頁面/students.jsp
public class ListAllStudentServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setAttribute("student", Arrays.asList("AA","BB","XX")); request.getRequestDispatcher("/students.jsp").forward(request, response); } } |
③ student.jsp——獲取屬性值,顯示
<%=request.getAttribute("student") %> //得到request <br> <% List<String> names = (List)request.getAttribute("student"); //顯示 for(String name:names){ %> <%=name %><br> <% } %> |
2.2連接數據庫
M——Dao
V——JSP,在頁面上填寫JAVA代碼實現顯示
C——Servlet:
代碼:
testAllUsers.jsp |
<a href="listAllStudents">List All Users</a> |
ListAllStudentServlet |
StudentDao studentDao = new StudentDao(); List<Student> students = studentDao.getAll();
request.setAttribute("studens", students); request.getRequestDispatcher("/students.jsp").forward(request, response); |
students.jsp |
<% List<Student> stus = (List)request.getAttribute("studens"); %> <table border="1" cellpadding="10" cellspacing="0"> <tr> <th>Id</th> <th>username</th> <th>password</th> <th>Delete</th> </tr>
<% for(Student student : stus){ %> <tr> <td><%=student.getId() %></td> <td><%=student.getUsername() %></td> <td><%=student.getPassword() %></td> <td><a href="deleteUsers?Id=<%=student.getId() %>">Delete</a></td> </tr> <% } %> </table> |
DeleteUsersServlet |
String Id = request.getParameter("Id"); StudentDao studentDao = new StudentDao(); studentDao.deleteById(Integer.parseInt(Id));
request.getRequestDispatcher("/success.jsp").forward(request, response); |
success.jsp |
操作成功 <br><br> <a href="listAllStudents">List All Users</a> |
StudentDao.java |
public List<Student> getAll() {
List<Student> students = new ArrayList<>();
Connection connection =null; PreparedStatement preparedStatement = null; ResultSet resultSet = null;
try { String url = "jdbc:mysql:///test"; String user = "root"; String pw = "1234"; Class.forName("com.mysql.jdbc.Driver"); connection=DriverManager.getConnection(url, user, pw);
String sql = "SELECT Id,username,password FROM test_users"; preparedStatement = connection.prepareStatement(sql); resultSet = preparedStatement.executeQuery(); while(resultSet.next()){ int id=resultSet.getInt(1); String username = resultSet.getString(2); String password = resultSet.getString(3);
Student student = new Student(id, username, password); students.add(student); } } catch (Exception e) { e.printStackTrace(); }finally{ try { if(resultSet!=null){ resultSet.close(); } } catch (Exception e) { e.printStackTrace(); } try { if(preparedStatement!=null){ preparedStatement.close(); } } catch (Exception e) { e.printStackTrace(); } try { if(connection!=null){ connection.close(); } } catch (Exception e) { e.printStackTrace(); } }
return students; }
public void deleteById(int Id) {
Connection connection =null; PreparedStatement preparedStatement = null;
try { String url = "jdbc:mysql:///test"; String user = "root"; String pw = "1234"; Class.forName("com.mysql.jdbc.Driver"); connection=DriverManager.getConnection(url, user, pw);
String sql = "DELETE FROM test_users WHERE Id=?"; preparedStatement = connection.prepareStatement(sql); preparedStatement.setInt(1, Id);
//重要 preparedStatement.executeUpdate();
} catch (Exception e) { e.printStackTrace(); }finally{ try { if(preparedStatement!=null){ preparedStatement.close(); } } catch (Exception e) { e.printStackTrace(); } try { if(connection!=null){ connection.close(); } } catch (Exception e) { e.printStackTrace(); } } } |
Student.java |
privateintId; private String username; private String password; getter/setter/有參、無參構造器 |
2.3不足之處
1. 使用數據連接池,DBUtils,JDBCUtil工具類,DAO基類
2.一個請求Servlet不好!一個模塊使用一個Servlet,即多個請求可以使用一個Servlet
3.在頁面上加入jQuery提示
三、MVC綜合案例
3.1案例技術選型
技術 |
技術難點 |
使用C3P0連接池 JDBC工具採用DBUtils 頁面提示操作使用jQuery |
① 多個請求使用一個Servlet ② 模糊查詢 ③ 創建秀給,驗證用戶名 是否已經被使用,提示 |
圖1.1 MVC框架各部分功能
在實際書寫項目時,倒序(從後(mysql)往前(view)寫)
3.2創建數據表
Create table MVC_Customers( id int primary key auto_increment, name varchar(30) not null unique,password varchar(30),phone varchar(30)); |
|
爲name字段添加唯一約束 alter table mvc_customers add constraint name_uk unique(name); |
不懂 Create中沒有麼? |
3.3 DAO工具類
l 加入C3P0數據源
n C3P0
n 數據庫驅動的jar包
C3P0—lib中複製c3p0-0.9.2.1.jar、、添加mysql.jar C3P0—doc—index.html |
在src下新建c3p0-config.xml <c3p0-config> <named-config name="mvcapp"> <property name="user">root</property> <property name="password">1234</property> <property name="driverClass">com.mysql.jdbs.Driver</property> <property name="jdbcUrl">jdbc:mysql:///test</property>
<property name="acquireIncrement">5</property> <property name="initialPoolSize">10</property> <property name="minPoolSize">10</property> <property name="maxPoolSize">50</property>
<property name="maxStatements">20</property> <property name="maxStatementsPerConnection">5</property>
</named-config> </c3p0-config> |
在Jdbc中添加dataSource連接c3p0 privatestatic DataSource dataSource = null; static{ dataSource = new ComboPooledDataSource("mvcapp"); } |
測試類Junit
點擊next,選擇getConnection getConnection 中return dataSource.getConnection() |
l 編寫DAO、JdbcUtils工具類和CustomerDAO接口
l 提供CustomerDAO接口的實現類:CustomerDAOJdbcImpl
3.4多個請求使用一個Servlet
方法一:
方法二:
3.4 查詢操作的實現
l 頁面
l 實現方法
Index.jsp頁面 |
<form action="query.do" method="post"> <table > <tr> <td>UserName</td> <td><input type="text" name="name"/></td> </tr>
<tr> <td>Password</td> <td><input type="text" name="name"/></td> </tr>
<tr> <td>Phone</td> <td><input type="text" name="name"/></td> </tr>
<tr> <td><input type="submit" value="Query"/></td> <td><a href="">Add New User</a></td> </tr> </table> </form>
<br><br> <% List<Customer> customers = (List<Customer>)request.getAttribute("customers"); if(customers!=null&&customers.size()>0){ %> <hr> <br><br> <table border="1" cellpadding="10" cellspacing="0"> <tr> <th>ID</th> <th>UserName</th> <th>Password</th> <th>Phone</th> <th>UPDATE/DELETE</th> </tr> <% for(Customer customer : customers){ %> <tr> <td><%=customer.getId() %></td> <td><%=customer.getName() %></td> <td><%=customer.getPassword() %></td> <td><%=customer.getPhone() %></td> <td> <a href="">UPDATE</a> <a href="">DELETE</a> </td> </tr> <% } %> </table> <% } %> |
3.5 模糊查詢
1) 在CustomerDAO中封裝查詢條件getForListWithCriteriaCustomer
public List<Customer> getForListWithCriteriaCustomer(CriteriaCustomer cc); |
2) 在CustomerDAOJdbcImpl中完成對應方法
public List<Customer> getForListWithCriteriaCustomer(CriteriaCustomer cc) { String sql = "SELECT id,name,password,phone FROM mvc_customers WHERE " + "name LIKE ? AND password LIKE ? AND phone LIKE ?"; return getForList(sql, cc.getName(),cc.getPassword(),cc.getPhone()); } |
3) CustomerReflectServlet中
3.6刪除操作
l 加入jQuery的方法
n 在WebContent下建scripts文件夾,將jquery-1.7.2.js導入
n 在index中的<head></head>中添加如下代碼
<title>Insert title here</title> <script type="text/javascript" src="scripts/jquery-1.7.2.js"></script> <script type="text/javascript"> $(function(){ $(".delete").click(function(){ var content = $(this).parent().parent().find("td:eq(1)").text(); var flag = confirm("確定要刪除"+content+"的信息麼?"); return flag; }); }); </script> </head> |
3.7添加操作
1)Register New User 超鏈接連接到newUser.jsp
2)新建newUser.jsp
3)在Servlet的addUser()中
privatevoid addCustomer(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //1.獲取表單參數:name,password,phone String name = request.getParameter("name"); String password = request.getParameter("password"); String phone = request.getParameter("phone"); // 檢驗name是否被佔用 // ①調用CustomerDAO的getCountWithName(String name)獲取那麼在數據庫中的個數 long count = customerDAO.getCountWithName(name); // ②若返回值大於零,則響應newUser.jsp頁面(轉發): System.out.println("Count::::"+count); if (count > 0){ // a顯示錯誤消息:在request中放入一個屬性message:用戶名name已經被佔用,請重新選擇! // 在頁面上通過request.getAttribute("message")的方式顯示 request.setAttribute("message", "用戶名"+name+"已經被佔用,請重新選擇!"); // b表單值回顯: value="<%=request.getParameter("name")==null?"":request.getParameter("name")%>" // c結束方法:return request.getRequestDispatcher("/newUser.jsp").forward(request, response); //大於零不用往後執行,不用else,直接可以用return return ;
} //2.若驗證通過,則把表單參數封裝在一個Customer對象中 Customer customer = new Customer(name, password, phone); //3.調用CustomerDao的save(Customer customer)執行保存操作 customerDAO.save(customer); //4.重定向到success.jsp頁面(用轉發,表單會重複提交) response.sendRedirect("success.jsp"); } |
3.8修改操作
1)先顯示(SELECT操作)修改的頁面,在進行(UPDATE)
2)顯示修改的頁面
①Update的超鏈接 |
<a href="edit.do?id=<%=customer.getId() %>">UPDATE</a> |
②edit方法:獲取id,調用CustomerDAO的方法獲取id對應的Customer對象 |
④ 應一個頁面:使用隱藏域來保存要求改的Customer對象的id <input type=”hidden” name=”id” value=”<%= customer.getid%>”/> 提交到Update.do |
3)修改操作
四、老師MVC案例小結(1)
4.1 整體架構:MVC設計模式到底如何落地
4.2多個請求對應一個servlet
1)Servlet映射爲*.do :可以接受一切.do 結尾的請求
創建CustomerReflectServlet時edit |
2)在Servlet的doGet和doPost方法中:
//1. 獲取ServletPath: /edit.do或/addCustomer.do String servletPath = request.getServletPath(); //2. 去除/ he .do, 得到類似於edit或addCustomer這樣的字符串 String methodName = servletPath.substring(1, servletPath.length() - 3); try { //3.利用反射獲取methodName對應的方法 Method method = getClass().getDeclaredMethod(methodName, HttpServletRequest.class,HttpServletResponse.class); //4.利用反射調用對應的方法 method.invoke(this, request, response); } catch (Exception e) { //人性化設計有一些相應(若要調用的方法不存在,相應一個error.jsp頁面) response.sendRedirect("error.jsp"); } |
4.3查詢:MVC的整個流程
query.Do—>doPost—>query—>JSP
query方法的代碼 |
//1.調用CustomerDAO的()得到Customer的集合 List<Customer> customers = customerDAO.getForListWithCriteriaCustomer(cc); //利用反射調用 //2.把Customer的集合放入request中 request.setAttribute("customers", customers); //3.轉發頁面到index.jsp(不能使用重定向) request.getRequestDispatcher("/index.jsp").forward(request, response); |
JSP:獲取request中的customer屬性,遍歷顯示 |
<% List<Customer> customers = (List<Customer>)request.getAttribute("customers"); if(customers!=null&&customers.size()>0){ %> <% for(Customer customer : customers){ %> <tr> <td><%=customer.getId() %></td> <td><%=customer.getName() %></td> <td><%=customer.getPassword() %></td> <td><%=customer.getPhone() %></td> <td> <a href="">UPDATE</a> </td> <td> <a href="delete.do?id=<%=customer.getId() %>" class="delete">DELETE</a> </td> </tr> <% } %> |
4.4模糊查詢
1)正常的SQL
String sql = "SELECT id,name,password,phone FROM mvc_customers WHERE " + "name LIKE ? AND password LIKE ? AND phone LIKE ?"; |
2)填充佔位符的技巧:以name屬性爲例:若name字段爲null,返回“%%”;若不爲null,返回“%”+name+“%”
if (name == null) name = "%%"; else name = "%" + name + "%"; returnname; |
3)把查詢條件封裝爲一個JavaBean
publicclass CriteriaCustomer { private String name; private String password; private String phone; //…… } |