zoukankan      html  css  js  c++  java
  • JavaWeb:基于MVC设计模式的一个小案例(一)

    (未经允许,请勿转载,谢谢。)

    本案例的处理过程:

    客户端发送一个请求给服务器,服务器把这个请求给Servlet,Servlet 获取请求信息,根据请求信息的情况去调用 model (在这里是一个普通的 Java 类),然后把返回结果给 Servlet ,然后Servlet 根据返回结果 转向一个 JSP,JSP是用来呈现数据的 (这里用的是Java 代码),生成一个HTML 页面显给客户。

    使用到的技术:

    MVC 设计模式:JSP、Servlet、POJO

    数据库:MySQL

    连接数据库使用 c3p0 数据库连接池

    JDBC 工具使用 DBUtils

    页面上的提示操作使用 jQuery

    具体实现步骤:

    1、建立数据表

    代码: 

    Create table customer(
    id int(10) primary key auto_increment,
    name varchar(30) not null unique,
    address varchar(30),
    phone varchar(30)
    );

    为 name 字段添加唯一约束:
    alter table customers add constraint name_uk unique(name);

    2、底层实现

    ①、加入c3p0 数据源:导入两个 jar 包(c3p0 和 数据库驱动),在 src 下新建配置文件:c3p0-config.xml ,修改一下要有连接数据库的基本信息(driverClass、jdbcUrl、user、password)。

    c3p0-config.xml 代码:

     1 <?xml version="1.0" encoding="UTF-8" ?>
     2 <c3p0-config>
     3 
     4   <named-config name="mvcapp"> 
     5   
     6       <!--指定连接数据源的基本信息  -->
     7       <property name="driverClass">com.mysql.jdbc.Driver</property>
     8       <property name="jdbcUrl">jdbc:mysql:///javawebdb</property>
     9       <property name="user">root</property>
    10       <property name="password">root</property>
    11       
    12       <!-- 若数据库中连接不足时,一次性向数据库服务器申请多少个连接-->
    13     <property name="acquireIncrement">5</property>
    14     <!-- 初始化数据库连接池时连接的数量-->
    15     <property name="initialPoolSize">10</property>
    16     <!-- 数据库连接池中的最小的数据库连接数-->
    17     <property name="minPoolSize">10</property>
    18     <!-- 数据库连接池中的最大的数据库连接数-->
    19     <property name="maxPoolSize">50</property>
    20     
    21     <!-- c3p0 数据库连接池可以维护的 Statement 的个数-->
    22     <property name="maxStatements">20</property> 
    23     <!-- 每个连接同时可以使用的Statement 对象的个数-->
    24     <property name="maxStatementsPerConnection">5</property>
    25 
    26   
    27   </named-config>
    28 </c3p0-config>

    ②、编写DAO 工具类、JdbcUtils 工具类和 CustomerDao 接口(以下有具体说明和代码)

    DAO 工具类:封装了基本的增删改查的方法,以供子类继承使用。当前DAO 没有事务,直接在方法中获取数据库连接。导入了DBUtils 的 jar 包,整个 DAO 采取 DBUtils 的解决方案。

    实现方法:

    update(封装了insert、delete、update)操作:public void update(String sql, Object...args){  }

    查询 返回 T 对应的实体类的对象:public T get(String sql, Object...args){  }

    查询 返回 T 对应的List :public List<T> getForList(String sql, Object...args){  }

    查询 返回一个字段的值: public <E> E getForValue(String sql, Object...args){  }

    DAO.java 代码:

      1 package com.hnust.mvcapp.dao;
      2 
      3 import java.lang.reflect.ParameterizedType;
      4 import java.lang.reflect.Type;
      5 import java.sql.Connection;
      6 import java.sql.SQLException;
      7 import java.util.List;
      8 
      9 import org.apache.commons.dbutils.QueryRunner;
     10 import org.apache.commons.dbutils.handlers.BeanHandler;
     11 import org.apache.commons.dbutils.handlers.BeanListHandler;
     12 import org.apache.commons.dbutils.handlers.ScalarHandler;
     13 
     14 import com.hnust.mvcapp.utils.JdbcUtils;
     15 
     16 /**
     17  * 封装了基本的增删改查的方法,以供子类继承使用。
     18  * 当前DAO 直接在方法中获取数据库连接。
     19  * 整个DAO 采取DBUtils 解决方案。
     20  * @author User
     21  *
     22  * @param <T> 当前 DAO 处理的实体类的类型是什么
     23  */
     24 public class Dao<T> {
     25 
     26     private QueryRunner queryRunner = new QueryRunner();
     27     
     28     private Class<T> clazz;
     29     
     30     /**
     31      * 需要确定 clazz
     32      */
     33     public Dao(){
     34         //由得到子类的 Class得到父类 带泛型的那个类型。
     35         Type superClass = getClass().getGenericSuperclass();
     36         //先判断是不是那个类型
     37         if(superClass instanceof ParameterizedType){
     38             //是的话,强转一下
     39             ParameterizedType parameterizedType = (ParameterizedType) superClass;
     40             //获取真正的泛型的参数
     41             Type[] typeArgs = parameterizedType.getActualTypeArguments();
     42             if(typeArgs != null && typeArgs.length >0){
     43                 if(typeArgs[0] instanceof Class){
     44                     clazz = (Class<T>) typeArgs[0];
     45                 }
     46             }
     47         }
     48     }
     49     
     50     
     51     /**
     52      * 查询,返回某一个字段的值
     53      */
     54     public <E> E getForValue(String sql, Object...args){
     55         Connection connection = null;
     56         try {
     57             connection = JdbcUtils.getConnection();
     58             return (E) queryRunner.query(connection, sql, new ScalarHandler(), args);
     59         } catch (SQLException e) {
     60             e.printStackTrace();
     61         }finally{
     62             JdbcUtils.releaseConnection(connection);
     63         }
     64         return null;
     65     }
     66     
     67     /**
     68      * 查询,返回T 所对应的 List
     69      */
     70     public List<T> getForList(String sql, Object...args){
     71         Connection connection = null;
     72         try {
     73             connection = JdbcUtils.getConnection();
     74             return queryRunner.query(connection, sql, new BeanListHandler<>(clazz), args);
     75         } catch (SQLException e) {
     76             e.printStackTrace();
     77         }finally{
     78             JdbcUtils.releaseConnection(connection);
     79         }
     80         return null;
     81     }
     82     
     83     /**
     84      * 查询,返回一个T 的实体类对象
     85      */
     86     public T get(String sql, Object...args){
     87         Connection connection = null;
     88         
     89         try {
     90             connection = JdbcUtils.getConnection();
     91             return queryRunner.query(connection, sql, new BeanHandler<>(clazz), args);
     92         } catch (SQLException e) {
     93             e.printStackTrace();
     94         }finally{
     95             JdbcUtils.releaseConnection(connection);
     96         }
     97         return null;
     98     }
     99     
    100     /**
    101      * 通用的 insert 、delete、update 方法
    102      */
    103     public void update(String sql, Object...args){
    104         Connection connection = null;
    105         try {
    106             connection = JdbcUtils.getConnection();
    107             queryRunner.update(connection, sql, args);
    108         } catch (Exception e) {
    109             e.printStackTrace();
    110         }finally{
    111             JdbcUtils.releaseConnection(connection);
    112         }
    113     }
    114 }

    JdbcUtils 工具类:JDBC 操作的工具类。

    实现方法:

    返回数据源的一个 Connection 对象:public static Connection getConnection(){  }

    释放 Connection 的连接:public static void releaseConnection(Connection connection){  }

    注意:数据源的初始化一定要放在静态代码块中,数据源被创建一次就够了。写完一个可以用单元测试检验以下。

    JdbcUtils.java 代码:

     1 package com.hnust.mvcapp.utils;
     2 
     3 import java.sql.Connection;
     4 import java.sql.SQLException;
     5 
     6 import javax.sql.DataSource;
     7 
     8 import com.mchange.v2.c3p0.ComboPooledDataSource;
     9 
    10 /**
    11  * JDBC 操作的工具类
    12  * @author User
    13  *
    14  */
    15 public class JdbcUtils {
    16 
    17     /**
    18      * 释放连接
    19      */
    20     public static void releaseConnection(Connection connection){
    21         
    22         try {
    23             if(connection != null){
    24                 connection.close();
    25             }
    26         } catch (Exception e) {
    27             e.printStackTrace();
    28         }
    29     }
    30     
    31     private static DataSource dataSource = null;
    32     static{
    33         dataSource = new ComboPooledDataSource("mvcapp"); //传入的是 configName
    34     }
    35     /**
    36      * 获取连接
    37      * @throws SQLException 
    38      */
    39     public static Connection getConnection() throws SQLException{
    40         
    41         return dataSource.getConnection();
    42     }
    43 }

    CustomerDao 接口:

    实现的方法:

    模糊查询 返回满足条件的List :public List<Customer> getForListWithCriteriaCustomer(CriteriaCustomer cc);

    查询 返回List:public List<Customer> getAll();

    添加:poublic void save(Customer customer);

    修改时要根据id 的查询显示:public Customer get(Inreger id);

    删除(根据 id):public void delete(Integer id);

    查询 和这个名字一样的 记录数(根据 name):public long getCountWithName(String name);

    CustomerDao.java 代码:

     1 package com.hnust.mvcapp.dao;
     2 
     3 import java.util.List;
     4 
     5 import com.hnuct.mvcapp.entity.Customer;
     6 
     7 public interface CustomerDao {
     8     
     9     /**
    10      * 模糊查询 返回满足条件的List
    11      * @param cc :封装了查询条件
    12      * @return
    13      */
    14     public List<Customer> getForListWithCriteriaCustomer(CriteriaCustomer cc);
    15 
    16     /**
    17      * 查询 返回 List
    18      */
    19     public List<Customer> getAll();
    20     
    21     /**
    22      * 增加
    23      */
    24     public void save(Customer customer);
    25     
    26     /**
    27      * 修改 更新时候的查询(根据id)显示
    28      */
    29     public Customer get(Integer id);
    30     
    31     /**
    32      * 删除
    33      */
    34     public void delete(Integer id);
    35     
    36     /**
    37      * 返回和name 相同的记录数
    38      */
    39     public long getCountWithName(String name);
    40 }

    实体类 Customer:

    Customer.java 代码:

     1 package com.hnuct.mvcapp.entity;
     2 
     3 public class Customer {
     4 
     5     private Integer id;
     6     private String name;
     7     private String address;
     8     private String phone;
     9     public Integer getId() {
    10         return id;
    11     }
    12     public void setId(Integer id) {
    13         this.id = id;
    14     }
    15     public String getName() {
    16         return name;
    17     }
    18     public void setName(String name) {
    19         this.name = name;
    20     }
    21     public String getAddress() {
    22         return address;
    23     }
    24     public void setAddress(String address) {
    25         this.address = address;
    26     }
    27     public String getPhone() {
    28         return phone;
    29     }
    30     public void setPhone(String phone) {
    31         this.phone = phone;
    32     }
    33     public Customer(Integer id, String name, String address, String phone) {
    34         super();
    35         this.id = id;
    36         this.name = name;
    37         this.address = address;
    38         this.phone = phone;
    39     }
    40     public Customer() {
    41         super();
    42     }
    43     
    44     @Override
    45     public String toString() {
    46         return "Customers [id=" + id + ", name=" + name + ", address="
    47                 + address + ", phone=" + phone + "]";
    48     }
    49     
    50     
    51 }

    Dao 接口的实现:

    CustomerDaoJdbcImpl.java 代码:

     1 package com.hnuct.mvcapp.dao.impl;
     2 
     3 import java.util.List;
     4 
     5 import com.hnuct.mvcapp.entity.Customer;
     6 import com.hnust.mvcapp.dao.CriteriaCustomer;
     7 import com.hnust.mvcapp.dao.CustomerDao;
     8 import com.hnust.mvcapp.dao.Dao;
     9 
    10 public class CustomerDaoJdbcImpl extends Dao<Customer> implements CustomerDao{
    11 
    12     @Override
    13     public List<Customer> getAll() {
    14         String sql = "select * from customer";
    15         return getForList(sql);
    16     }
    17 
    18     @Override
    19     public void save(Customer customer) {
    20         String sql = "insert into customer(name,address,phone) values (?,?,?)";
    21         update(sql, customer.getName(), customer.getAddress(), customer.getPhone());
    22     }
    23 
    24     @Override
    25     public Customer get(Integer id) {
    26         String sql = "select * from customer where id = ?";
    27         return get(sql, id);
    28     }
    29 
    30     @Override
    31     public void delete(Integer id) {
    32         String sql = "delete from customer where id = ? ";
    33         update(sql, id);
    34     }
    35 
    36     @Override
    37     public long getCountWithName(String name) {
    38         String sql = "select count(id) from customer where name = ?";
    39         return getForValue(sql, name);
    40     }
    41 
    42     @Override
    43     public List<Customer> getForListWithCriteriaCustomer(CriteriaCustomer cc) {
    44         String sql = "SELECT id,name,address,phone FROM customer WHERE name LIKE ? AND "
    45                 + "address LIKE ? AND phone LIKE ?";
    46         //注意:修改了 CriteriaCustomer 的 getter 方法,使其返回的字符串中有 "%%",
    47         //若返回值为 null 则返回 "%%" ,若不为 null, 则返回 "% " + 字段本身的值 + " %"
    48         return getForList(sql, cc.getName(), cc.getAddress(), cc.getPhone());
    49     }
    50 
    51 }

    ps:注意因为查询条件很多时候 和 实体类 并不相同,所以要做成一个单独的类,这里是 CriteriaCustomer 类,其中里面的getter 方法做了修改,是为了正确的填充占位符。

    CriteriaCustomer.java 代码:

     1 package com.hnust.mvcapp.dao;
     2 
     3 public class CriteriaCustomer {
     4 
     5     private String name;
     6     private String address;
     7     private String phone;
     8     public String getName() {
     9         if(name == null)
    10             name = "%%";
    11         else
    12             name = "%" + name + "%";
    13         return name;
    14     }
    15     public void setName(String name) {
    16         this.name = name;
    17     }
    18     public String getAddress() {
    19         if(address == null)
    20             address = "%%";
    21         else 
    22             address = "%" + address + "%";
    23         return address;
    24     }
    25     public void setAddress(String address) {
    26         this.address = address;
    27     }
    28     public String getPhone() {
    29         if(phone == null)
    30             phone = "%%";
    31         else 
    32             phone = "%" + phone + "%";
    33         return phone;
    34     }
    35     public void setPhone(String phone) {
    36         this.phone = phone;
    37     }
    38     
    39     
    40     
    41     public CriteriaCustomer() {
    42         super();
    43     }
    44     public CriteriaCustomer(String name, String address, String phone) {
    45         super();
    46         this.name = name;
    47         this.address = address;
    48         this.phone = phone;
    49     }
    50     
    51     
    52 }

    3、Servlet 的实现:获取请求信息的参数,根据请求信息调用 DAO 的对应的方法。

    先写了一个 test.jsp 页面 放了三个超链接。

    test.jsp 代码:

     1 <%@ page language="java" contentType="text/html; charset=UTF-8"
     2     pageEncoding="UTF-8"%>
     3 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
     4 <html>
     5 <head>
     6 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
     7 <title>Insert title here</title>
     8 </head>
     9 <body>
    10         <%-- 
    11         <a href="customerServlet?method=add">add</a>
    12         <br><br>
    13         <a href="customerServlet?method=query">query</a>
    14         <br><br>    
    15         <a href="customerServlet?method=delete">delete</a>
    16         --%>
    17         
    18         <a href="addCustomer.do">add</a>
    19         <br><br>
    20         <a href="query.do">query</a>
    21         <br><br>
    22         <a href="delete.do">delete</a>
    23         <br><br>
    24         
    25         
    26         
    27 </body>
    28 </html>

    注意你的 web.xml 里的 url-pattern:<url-pattern>*.do</url-pattern>

    然后 创建了CustomerServlet :去响应服务器的请求,调用对应的model,返回结果(我这里暂时实现了 模糊查询和 删除的功能)。

    CustomerServlet.java 代码:

      1 package com.hnust.mvcapp.servlet;
      2 
      3 import java.io.IOException;
      4 import java.lang.reflect.InvocationTargetException;
      5 import java.lang.reflect.Method;
      6 import java.util.List;
      7 
      8 import javax.servlet.ServletException;
      9 import javax.servlet.http.HttpServlet;
     10 import javax.servlet.http.HttpServletRequest;
     11 import javax.servlet.http.HttpServletResponse;
     12 
     13 import com.hnuct.mvcapp.dao.impl.CustomerDaoJdbcImpl;
     14 import com.hnuct.mvcapp.entity.Customer;
     15 import com.hnust.mvcapp.dao.CriteriaCustomer;
     16 import com.hnust.mvcapp.dao.CustomerDao;
     17 
     18 
     19 public class CustomerServlet extends HttpServlet {
     20     private static final long serialVersionUID = 1L;
     21 
     22     private CustomerDao customerDao = new CustomerDaoJdbcImpl();
     23     
     24     protected void doGet(HttpServletRequest request, HttpServletResponse response) 
     25             throws ServletException, IOException {
     26         
     27             this.doPost(request, response);
     28     }
     29     
     30     @Override
     31     protected void doPost(HttpServletRequest req, HttpServletResponse resp)
     32             throws ServletException, IOException {
     33         
     34         //1、获取servletPath
     35         String servletPath = req.getServletPath();
     36         //System.out.println(servletPath);  //得到的是  /addCustomer.do
     37         
     38         //2、去除 / 和 .do ,得到 addCustomer 这样的字符串
     39         String methodName = servletPath.substring(1);
     40         methodName = methodName.substring(0, methodName.length() - 3);
     41         //System.out.println(methodName);  // 得到的是 addCustomer
     42         
     43         try {
     44             //3、利用反射,根据获取的 方法名,获取对应的方法。
     45             Method method = getClass().getDeclaredMethod(methodName, HttpServletRequest.class,
     46                                                     HttpServletResponse.class);
     47             //4、利用反射调用对应的方法    
     48             method.invoke(this, req, resp);
     49             
     50         } catch (Exception e) {
     51             e.printStackTrace();
     52             //可以有一些响应
     53             resp.sendRedirect("error.jsp");
     54         }
     55         
     56     }
     57 
     58     private void delete(HttpServletRequest request, HttpServletResponse response) 
     59             throws ServletException, IOException {
     60         //1、获取 id
     61         String idStr = request.getParameter("id");
     62         int id = 0;
     63         //为了避免输入的 id 是不 合法的。 idStr 不能转为 int 类型。若不能转,则 id 为0,无法执行任何的操作。
     64         try {
     65             id = Integer.parseInt(idStr);
     66             //2、调用 CustomerDAO 的 delete 方法
     67             customerDao.delete(id);
     68             //3、页面的重定向
     69             response.sendRedirect("query.do");
     70         } catch (Exception e) {
     71             e.printStackTrace();
     72         }
     73     }
     74 
     75     private void query(HttpServletRequest request, HttpServletResponse response) 
     76             throws ServletException, IOException {
     77         //1、获取模糊查询的请求参数
     78         String name = request.getParameter("name");
     79         String address = request.getParameter("address");
     80         String phone = request.getParameter("phone");
     81         
     82         //2、把请求参数封装为 CriteriaCustomer 对象
     83         CriteriaCustomer cc = new CriteriaCustomer(name, address, phone);
     84         
     85         //3、再调用CustomerDao 的 getForListWithCriteriaCustomer() 方法
     86         List<Customer> customers = customerDao.getForListWithCriteriaCustomer(cc);
     87          
     88         //调用CustomerDao 的 getAll() 方法 查询。
     89         //List<Customer> customers = customerDao.getAll();
     90         
     91         //4、把查询到的结果集放入 request 中
     92         request.setAttribute("customers", customers);
     93         //5、请求的转发
     94         request.getRequestDispatcher("/index.jsp").forward(request, response);
     95         
     96     }
     97 
     98     private void addCustomer(HttpServletRequest request, HttpServletResponse response) 
     99             throws ServletException, IOException {
    100 
    101         System.out.println("add");
    102     }
    103 
    104 }

    4、返回结果 的 JSP 页面:获取返回结果,遍历显示。

    index.jsp 代码:

     1 <%@page import="com.hnuct.mvcapp.entity.Customer"%>
     2 <%@page import="java.util.List"%>
     3 <%@ page language="java" contentType="text/html; charset=UTF-8"
     4     pageEncoding="UTF-8"%>
     5 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
     6 <html>
     7 <head>
     8 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
     9 <title>Insert title here</title>
    10 <script type="text/javascript" src="Scripts/jquery-1.7.2.js"></script>
    11 <script type="text/javascript">
    12         $(function(){
    13             $(".delete").click(function(){
    14                 var content = $(this).parent().parent().find("td:eq(1)").text();
    15                 var flag = confirm("确定要删除 " + content + " 的信息吗?");
    16                 return flag;
    17             });
    18         })
    19 </script>
    20 </head>
    21 <body>
    22         <form action="query.do" method="post">
    23                 <table>
    24                     <tr>
    25                         <td>name:</td>
    26                         <td><input type="text" name="name"/></td>
    27                     </tr>
    28                     <tr>
    29                         <td>address:</td>
    30                         <td><input type="text" name="address"/></td>
    31                     </tr>
    32                     <tr>
    33                         <td>phone:</td>
    34                         <td><input type="text" name="phone"/></td>
    35                     
    36                     <tr>
    37                         <td><input type="submit" value="Query"/></td>
    38                         <td><a href="">Add new Customer</a></td>
    39                     </tr>
    40                 </table>
    41         </form>
    42         <br><br>
    43         
    44         <%
    45             List<Customer> customers = (List<Customer>) request.getAttribute("customers");
    46             if(customers != null && customers.size() > 0){
    47         %>
    48         <hr>
    49         <br><br>
    50         <table border="1" cellpadding="10" cellspacing="0">
    51             <tr>
    52                 <th>ID</th>
    53                 <th>NAME</th>
    54                 <th>ADDRESS</th>
    55                 <th>PHONE</th>
    56                 <th>UPDATE/DELETE</th>
    57             </tr>
    58             <% for(Customer cust : customers){
    59             
    60             %>
    61             <tr>
    62                 <td><%= cust.getId() %></td>
    63                 <td><%= cust.getName() %></td>
    64                 <td><%= cust.getAddress() %></td>
    65                 <td><%= cust.getPhone() %></td>
    66                 <td>
    67                     <a href="">Update</a>
    68                     <a href="delete.do?id=<%=cust.getId() %>" class="delete">Delete</a>
    69                 </td>
    70             </tr>
    71             <%
    72                 }
    73             %>
    74         </table>
    75         <%
    76             }
    77         %>
    78 </body>
    79 </html> 

    最后结果:

    点击query

    可以实现模糊查询,和删除的功能。

     这是今天的学习内容。

  • 相关阅读:
    保存windows 10的登录界面壁纸
    Python 从剪贴板中生成二维码
    SpringBoot
    IDEA8条配置
    Nodejs-hexoBlog
    Mybatis-Plus
    Javaweb文件上传
    GIt基本语法
    JS常用部分整合
    javaweb-maven学习总结
  • 原文地址:https://www.cnblogs.com/daoxiaobai/p/6267464.html
Copyright © 2011-2022 走看看