JavaWeb学习笔记(四)

4 篇文章 0 订阅
3 篇文章 0 订阅

JavaWeb学习笔记(四)一个MVCDAO小项目

注:本文内容是建立在佟刚老师的JavaWeb教程上写的,如有侵犯,联系删除

项目效果

项目所用技术

采取 MVC 设计模式及难点

使用到的技术:

  1. MVC 设计模式:JSP、Servlet,POJO
  2. 数据库使用 MySQL
  3. 连接数据库需要使用 C3P0 数据库连接池
  4. JDBC 工具采用 DBUtils
  5. 页面上的提示操作使用 jQuery

技术难点:

  1. 多个请求如何使用一个 Servlet ?
  2. 如何模糊查询 ?
  3. 如何在创建 或 修改 的情况下,验证用户名是否已经被使用,并给出提示?

项目流程图 及 idea工程

在这里插入图片描述

项目的实现

数据表建立

sql语句

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

建立C3P0数据连接池

ps:这部分不是很明白

1、现在src目录下建立一个 c3p0-config.xml ,在里面添加如下代码

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>

    <!-- This is my config for mysql-->
    <named-config name="mvcapp">
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/data?serverTimezone=GMT</property>
        <!--MySQL账户密码-->
        <property name="user">root</property>
        <property name="password">123456</property>
        <!-- 初始化连接池中的连接数,取值应在minPoolSize与maxPoolSize之间,默认为3-->
        <property name="initialPoolSize">10</property>
        <!--最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。默认值: 0 -->
        <property name="maxIdleTime">30</property>
        <!--连接池中保留的最大连接数。默认值: 15 -->
        <property name="maxPoolSize">100</property>
        <!-- 连接池中保留的最小连接数,默认为:3-->
        <property name="minPoolSize">10</property>
        <!--c3p0全局的PreparedStatements缓存的大小。如果maxStatements与maxStatementsPerConnection均为0,则缓存不生效,只要有一个不为0,则语句的缓存就能生效。如果默认值: 0-->
        <property name="maxStatements">200</property>
        <!-- 当连接池连接耗尽时,客户端调用getConnection()后等待获取新连接的时间,超时后将抛出SQLException,如设为0则无限期等待。单位毫秒。默认: 0 -->

    </named-config>

</c3p0-config>

2、JdbcUtils工具类实现连接池的链接和关闭

public class JdbcUtils {

    /**
     * 释放Connection 连接
     * @param connection
     */
    public static void releaseConnection(Connection connection){

    }

    private static DataSource dataSource = null;

    static {
        dataSource = new ComboPooledDataSource("mvcapp");
    }

    /**
     * 返回一个Connection 对象
     * @return
     */
    public static Connection getConnection(){
        Connection conn=null;
        try {
            conn=dataSource.getConnection();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return conn;
    }

}

注意:c3p0-config.xml的 < named-config name="mvcapp"> 应该与JdbcUtils的dataSource = new ComboPooledDataSource("mvcapp");相匹配

源码

编写 DAO、JdbcUtils工具类 、 CustomerDAO 接口和CustomerDAO 接口的实现类:CustomerDAOJDBCImpl,请见源码。

实现的一些难点

多个请求使用同一个 Servlet

多个请求使用一个Servlet有两种方法:
1、在同一个Servlet后面接不同的method,例如:

在这里插入图片描述
在CustomerServlet里实现如下:

@Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        
        //获取对应的操作方式,例如:customerServlet?method=delete
		String method = req.getParameter("method");

        switch (method){
            case "add": add(req,resp);break;
            case "query": query(req,resp);break;
            case "delete": delete(req,resp);break;
            case "update": update(req,resp);break;
        }
    }
    
//add、query、delete分别是CustomerDAO的具体实现方法

private void delete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String idStr = req.getParameter("id");
        int id = 0;

        //try-catch 作用防止id不能转化为整数;若不能,则id=0
        try {
            id = Integer.parseInt(idStr);
            customerDAO.delete(id);
        } catch (NumberFormatException e) {
            e.printStackTrace();
        }

        resp.sendRedirect("query.do");
    }

虽然这种方法也经常被使用,但是有明显的缺点:
①、当添加一个请求时,需要在 Servlet 中修改两处代码:switch、添加方;
②、在请求后面暴露了请求的方式,不私密,存有安全隐患。

2、利用 *do 的Servlet映射方式,实现多个请求使用一个Servle
在这里插入图片描述
在这里要注意一下,Servlet映射的配置样式<url-pattern>*.do</url-pattern>

 <servlet>
        <servlet-name>customerServlet</servlet-name>
        <servlet-class>cqy.dao.mvc.servlet.CustomerServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>customerServlet</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>

在CustomerServlet里实现如下(这部分的反射调用对应的方法不是很理解):

@Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //1、获取ServletPath:/edit.do 或 addCustomer.do 等
        String servletPath = req.getServletPath();
        //System.out.println(servletPath);
        //2、去除 / 和 do, 得到类似于 edit 或 addCustomer 这样的字符串
        String methodName = servletPath.substring(1);
        methodName = methodName.substring(0,methodName.length()-3);
        //System.out.println(methodName);

        try {
            //3、利用反射获取methodName 对应的方法
            Method method = getClass().getDeclaredMethod(methodName,HttpServletRequest.class,HttpServletResponse.class);
            //4、利用反射调用对应的方法
            method.invoke(this,req,resp);
        } catch (Exception e){
            resp.sendRedirect("error.jsp");
        }
    }
    
//method.invoke(this,req,resp);是调用delete等方法

 private void delete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String idStr = req.getParameter("id");
        int id = 0;

        //try-catch 作用防止id不能转化为整数;若不能,则id=0
        try {
            id = Integer.parseInt(idStr);
            customerDAO.delete(id);
        } catch (NumberFormatException e) {
            e.printStackTrace();
        }

        resp.sendRedirect("query.do");
    }   

模糊查询的实现

根据页面上name,address和phone来进行匹配,调用CustomerDAOpublic List<Customer> getForListWithCriteriaCustomer(CriteriaCustomer cc)来实现

在这里插入图片描述
在CustomerServlet中的query方法:

 private void query(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        // 获取模糊查询的请求参数
        String name = req.getParameter("name");
        String address = req.getParameter("address");
        String phone = req.getParameter("phone");

        //封装成 CriteriaCustomer
        CriteriaCustomer criteriaCustomer = new CriteriaCustomer(name,address,phone);
        //1、调用CustomerDAO 的 getAll()方法 得到 Customer 的集合
        //List<Customer> customers = customerDAO.getAll();
        List<Customer> customers =customerDAO.getForListWithCriteriaCustomer(criteriaCustomer);

        //2、把Customer 的集合放入request中
        req.setAttribute("customers",customers);

        //3、转发页面到 index.jsp(不能使用重定向)
        req.getRequestDispatcher("/index.jsp").forward(req,resp);
}

上面的方法与普通的查询方法无异,下面才是我们实现模糊查询的重点
public List getForListWithCriteriaCustomer(CriteriaCustomer cc)在CustermDAOJdbcImpl实现类的实现

@Override
    public List<Customer> getForListWithCriteriaCustomer(CriteriaCustomer cc) {
        String sql = "SELECT id,name,address,phone FROM customers where " +
                " name like ? and address like ? and phone like ?";
        //cc.getName()==null?"%%":"%"+cc.getName()+"%"
        // 修改了CriteriaCustomer 的getter 方法:使其返回的字符串中含有  "%%"
        //若返回值为 null 则返回 "%%"  ,若不为 null 则返回 “%” + value + “%” ,value 位原来的值
        return getForList(sql,cc.getName(),cc.getAddress(),cc.getPhone());
    }

注意到上面的SQL语句:

   String sql = "SELECT id,name,address,phone FROM customers where " +
                " name like ? and address like ? and phone like ?";

采用了的方法来匹配
而且采用了一个 CriteriaCustomer 类来把搜索的数据收集打包起来,CriteriaCustomer 类包括name、address和phone等私有成员,这些成员的setter方法为(以getName为例):

public String getName() {
        if(name == null)
            name = "%%";
        else
            name = "%" + name +"%";
        return name;
    }

为什么采取这样的setter方法呢?
这样是为了使得SQL语句中 ***%%***匹配(相似)方法得以实现。

JSP 上的 jQuery 提示

在这一部分,由于佟刚老师的IDE是eclipse,而用的idea,在MVC工程中引入jQuery的方式不一样,导致我被坑了好久T_T
那么在idea工程中,在JSP中改如何引入jQuery呢?
最简单的添加方式就是,直接在JSP中写入:

<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>

然后,将鼠标光标放在这行代码上按下Alt+enter。具体可以看这个教程(传送门)

不过,引入后可能还要到一个地方删除掉,这个要看到时候是否会报什么错误。
js+jQuery实现:“确定要删除 xx 的信息吗?”
方法①

<script src="https://code.jquery.com/jquery-3.3.1.min.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>

方法②

<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script>
    function deli()
    {

        //var content = $(this).parent().parent().find("td:eq(1)").text()
        //var content = document.getElementById("deleteName").value;
        if(confirm("确定要删除的信息吗?"))
        {
            return true;
        }
        else
        {
            return false;
        }
    }
</script>

至此,这个MVC小项目就结束啦!

JavaWeb学习笔记–其他文章

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值