Javaweb07-三层架构(BaseDao)

1、BaseDao

持久层业务接口实现类的公共父类,定义了jdbc操作数据库的所有公共方法,方便子类继承;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Properties;

/**
 * 持久层业务接口实现类的公共父类,定义了jdbc操作数据库的所有公共方法,方便子类继承
 * @author zhukang
 *
 */
public class BaseDao {

    // 数据库操作对象
    protected Connection conn = null;
    protected PreparedStatement pstmt = null;
    protected ResultSet rs = null;

    /**
     * 获取数据库连接,返回获取连接成功还是失败
     */
    public boolean getConnection(){
        try {
            // 创建Properties属性对象
            Properties properties = new Properties();

            // 使用反射机制,读取外部配置文件
            InputStream inputStream = BaseDao.class.getClassLoader().getResourceAsStream("jdbc.properties");

            // 加载输入流对象,获取配置文件内容
            properties.load(inputStream);

            // 读取数据库连接信息
            String driverClass = properties.getProperty("driverClass");
            String jdbcUrl = properties.getProperty("jdbcUrl");
            String user = properties.getProperty("user");
            String password = properties.getProperty("password");

            // 加载驱动
            Class.forName(driverClass);

            // 获取数据库连接对象
            conn = DriverManager.getConnection(jdbcUrl, user, password);
        } catch (Exception e) {
            e.printStackTrace();
            // 获取连接失败
            return false;
        }

        // 获取连接成功
        return true;
    }

    /**
     * 增删改的通用方法:只需要提供执行的SQL语句和SQL语句需要的参数,使用预处理对象
     */
    public int executeUpdate(String executeSql, Object ... params){

        // 定义SQL语句执行的影响行数
        int row = 0;

        // 获取数据库连接,如果获取失败,不执行操作
        if(getConnection()){
            // 公共执行增删改的处理代码
            try {

                // 创建预处理操作对象
                pstmt = conn.prepareStatement(executeSql);

                // 实现动态传参,注意: 传入的预编译SQL的?和传入的参数个数和顺序要一致,即:要保证一一对应
                for (int i = 0; i < params.length; i++) {
                    pstmt.setObject(i + 1, params[i]);
                }

                // 执行增删改操作,并获取影响行数
                row = pstmt.executeUpdate();

                System.out.println("BaseDao增删改的SQL=>"+pstmt);

            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                releaseResource(conn, pstmt, null);
            }
        }

        // 返回影响行数
        return row;

    }

    /**
     * 查询的通用方法:只需要提供执行的SQL语句和SQL语句需要的参数,使用预处理对象
     */
    public void executeSelect(String executeSql, Object ... params){

        // 获取数据库连接,如果获取成功,执行查询,否则不执行
        if(getConnection()){
            // 公共执行查询的处理代码
            try {
                // 创建预处理操作对象
                pstmt = conn.prepareStatement(executeSql);

                // 实现动态传参,注意: 传入的预编译SQL的?和传入的参数个数和顺序要一致,即:要保证一一对应
                for (int i = 0; i < params.length; i++) {
                    pstmt.setObject(i + 1, params[i]);
                }

                // 执行查询操作,并获取结果集
                rs = pstmt.executeQuery();

                System.out.println("BaseDao查询的SQL=>"+pstmt);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                // 不释放资源,因为rs要返回,关闭后,直接外层不可以使用
            }
        }
    }

    /**
     * 释放数据库操作对象资源
     */
    public void releaseResource(Connection conn, Statement stmt, ResultSet rs){
        try {
            // 手动释放
            if (null != rs) {
                rs.close();
            }

            if (null != stmt) {
                stmt.close();
            }

            if (null != conn) {
                conn.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

2、一个 Servlet 多请求 参数 mothed

使用反射实现;

(全部查询当作条件查询的没有条件来查询会比较方便后面的操作);

@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

    //根据请求携带的方法参数名参数,调用不同业务的处理方法

    String mothedName = req.getParameter("mothed") == null ? "animes" : req.getParameter("mothed");

    //利用反射,根据方法名调用指定方法
    try {
        Method method = getClass().getDeclaredMethod(mothedName,HttpServletRequest.class,HttpServletResponse.class);
        method.setAccessible(true);
        method.invoke(this, req,resp);
    } catch (Exception e) {
        e.printStackTrace();
    }

}

//查询所有的动漫列表
protected void animes(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    System.out.println("======= AnimesServlet查询所有的动漫列表==========");
    String aname = req.getParameter("aname");
    String author = req.getParameter("author");
    String cid = req.getParameter("cid");

    List animes = animeService.animeList(aname, author, cid);

    String animesJson = JSON.toJSONStringWithDateFormat(animes,"yyyy-MM-dd");

    System.out.println(animesJson);
    System.out.println("=============================================");
    resp.getWriter().print(animesJson);

}

//删除动漫
protected void delAnime(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    System.out.println("==============删除动漫=====================");

}

//添加动漫
protected void addAnime(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    System.out.println("==============添加动漫=====================");

}

//修改动漫
protected void modAnime(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    System.out.println("==============修改动漫=====================");

}

3、搜索 点击搜索按钮,$(“form”).serialize()获取参数,并条件查询

$(function(){

    //页面初始化加载,主动查询列表
    //查询所有的数据,就是条件查询的没有条件
    showAnimeList();

    //动态获取动漫数据,动态显示
    function showAnimeList(){
        $.getJSON("animes",$("form").serialize() ,function(data){
            // 确定数据要动态显示的位置
            var $tbody = $("tbody");

            //如果没有数据,不能显示分页和提示暂无数据
            if(data == null || data == ""){
                //先清空再,显示提示信息
                $tbody.empty().append("暂无数据");
                //隐藏 tfoot
                $("tfoot").hide();
                //直接返回,因为没有数据,不需要拼接页面
                return;
            }

            // 隔行变色
            var count = 1;

            //定义动态展示内容,如果不定义为空字符的话,一直拼接新数据
            var animeCountent = "";

            // 数据解析
            $(data).each(function(){
                // 定义颜色
                var bgColor = count % 2 == 0 ? "style='background-color:#ddd;'" : "";
                animeCountent +=
""
                    + "" + this.id + ""
                    + "" + this.cname + ""
                    + "" + this.name + ""
                    + "" + this.author + ""
                    + "" + this.actor + ""
                    + "" + this.produce + ""
                    + "" + this.create_date + ""
                    + "修改  删除"
                    + "";

                count++;
            });
            $tbody.empty().append(animeCountent);
            //有数据就要展示tfoot
            $("tfoot").show();
        });
    }

    //点击搜索按钮,根据条件筛选数据
    $("#searchAnimes").click(function(){
        showAnimeList();
    });

 });

4、分页查询sql 动态拼接(apramsList)

public class AnimeDaoImpl extends BaseDao implements AnimeDao{

    @Override
    public List selectAnimeList(String aname, String author, String cid) {
        //查询动漫详情的SQL语句
        String executeSql = "select a.id, a.cid, a.name, a.author, a.actor, a.produce, a.create_date, c.name from animes a, category c where a.cid = c.id ";

        //执行查询的参数集合
        //此写法弊端,如果两个或者多个参数同时有,必须不停的增加判断,添加参数
        //Object[] params = new Object[]{};

        //动态参数,推荐使用
        List paramList = new ArrayList();

        //根据不同的查询条件,拼接SQL语句和参数
        //条件中有动漫名
        if(null != aname && !"".equals(aname)) {
            //模糊匹配
            executeSql += " and a.name like concat('%',?,'%')";

            paramList.add(aname);
        }

        //条件中有作者
        if(null != author && !"".equals(author)) {
            //模糊匹配
            executeSql += " and a.author like concat('%',?,'%')";

            paramList.add(author);
        }

        //条件中有类型
        if(null != cid && !"0".equals(cid)) {
            executeSql += " and a.cid = ?";
            paramList.add(cid);
        }

        //定义返回动漫列表的数据集合
        List animes = new ArrayList();

        try {
            // 执行查询
            this.executeSelect(executeSql, paramList.toArray());

            // 解析查询结果
            while(rs.next()){
                // 每条数据,创建一个动漫对象,存储数据
                Anime anime = new Anime();
                anime.setId(rs.getInt(1));
                anime.setCid(rs.getInt(2));

                //对动漫name结构处理
                if(null != aname && !"".equals(aname)) {
                    //标记name
                    String markname = rs.getString(3).replace(aname, ""+aname+"");
                    anime.setName(markname);
                }else {
                    anime.setName(rs.getString(3));
                }

                anime.setAuthor(rs.getString(4));
                anime.setActor(rs.getString(5));
                anime.setProduce(rs.getString(6));
                anime.setCreate_date(rs.getDate(7));
                anime.setCname(rs.getString(8));

                // 将每条动漫数据对象放入集合
                animes.add(anime);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //关闭资源
            this.releaseResource(conn, pstmt, rs);
        }

        //返回动漫集合
        return animes;
    }

}

5、作业总结技巧(BaseDao 页面不跳转 Ajax)

//$(function() jQuery标志
$(function(){
    //定位z展示分类的下拉元素
    var $cidSelect = $("#cid");

    //获取动漫分类,动态展示
    $.getJSON("categories",function(data){
        //遍历返回的分类集合json集合数,动态加载分类选项
        $(data).each(function(){
            //alert(this.id+this.name);
            $cidSelect.append(""+this.name+"");
        });
    });
});

加载动漫数据的时候,直接考虑到模糊匹配查询,全部查询就是不带条件查询;

(这里的代码又展示了一遍,主要是提示后面的操作是基于这些代码操作的);

//$(function() jQuery标志
$(function(){
    //页面初始化加载,主动查询列表
        showAnimeList();

        //动态获取动漫数据,动态显示
        function showAnimeList(){
            $.getJSON("animes",$("form").serialize() ,function(data){
                // 确定数据要动态显示的位置
                var $tbody = $("tbody");

                //如果没有数据,不能显示分页和提示暂无数据
                if(data == null || data == ""){
                    //先清空再,显示提示信息
                    $tbody.empty().append("暂无数据");
                    //隐藏 tfoot
                    $("tfoot").hide();
                    //直接返回,因为没有数据,不需要拼接页面
                    return;
                }

                // 隔行变色
                var count = 1;

                //定义动态展示内容,如果不定义为空字符的话,一直拼接新数据
                var animeCountent = "";

                // 数据解析
                $(data).each(function(){
                    // 定义颜色
                    var bgColor = count % 2 == 0 ? "style='background-color:#ddd;'" : "";
                    animeCountent +=
""
                        + "" + this.id + ""
                        + "" + this.cname + ""
                        + "" + this.name + ""
                        + "" + this.author + ""
                        + "" + this.actor + ""
                        + "" + this.produce + ""
                        + "" + this.create_date + ""
                        + "修改  "
                        + "删除"
                        +""
                        + "";

                    count++;
                });
                $tbody.empty().append(animeCountent);
                //有数据就要展示tfoot
                $("tfoot").show();
            });
        }

        //点击搜索按钮,根据条件筛选数据
        $("#searchAnimes").click(function(){
            showAnimeList();
        });
});

没有同名字段时可以使用;

//条件中有作者
if(null != author && !"".equals(author)) {
    //标记关键字 author
    String markAuthor = "replace(author,'"+author +"',\""+author+"\") as 'a.author'";

    //标记
    executeSql  = executeSql.replace("a.author", markAuthor);

    //模糊匹配
    executeSql += " and a.author like concat('%',?,'%')";

    paramList.add(author); //添加参数
}
//对动漫name结构处理
if(null != aname && !"".equals(aname)) {
    //如果有这个条件 标记name
    String markname = rs.getString(3).replace(aname, ""+aname+"");
    anime.setName(markname);
}else {
    //没有这个条件则不需要标记
    anime.setName(rs.getString(3));
}
" 要不然会类型不匹配
request.setAttribute("upAnimes", anime);
%>

 //异步获取并遍历动漫类型
$(function(){
    //获取动漫分类,动态展示
    $.getJSON("categories",function(data){
        //定位z展示分类的下拉元素
        var $cidSelect = $("#cid");

        //遍历返回的分类集合json集合数,动态加载分类选项
        var cid =  $("#mycid").val();
        $(data).each(function(){
            //alert(this.id+this.name);
            if(cid == this.id){
                $cidSelect.append("<option value='"+this.id+"' selected>"+this.name+"</option>");
            }else{
                $cidSelect.append("<option value='"+this.id+"'>"+this.name+"</option>");
            }
        });
    });
});
</code></pre><p>cilck无法直接给动态的元素添加事件;</p><pre><code class="language-javascript">//确认删除提示  错误,click事件不能动态绑定事件
$(".delAnime").click(function(){
    if(!confirm("是否确认删除 ${anime.name } ")){
        return false;
    }
});
</code></pre><pre><code class="language-javascript"> "<a class='delAnime' href='animes?mothed=delAnime&id="+this.id+"' onClick='return confirm(\"确认删除《"+this.name+"》?\")'>删除</a></td>"
</code></pre><pre><code class="language-javascript">//动态绑定事件(当前和以后添加的元素都可以绑定)
//$(document).on 绑定动态加载子元素的事件   document是父级元素即可
$(document).on('click', '.delAnime', function(){
    if(!confirm("是否确认删除 ${anime.name }")){
        return false;
    }
});
</code></pre><h2 id="56-分页条件查询-不需要pagesupper类">5.6 分页条件查询 (不需要pageSupper类)</h2><p>分页条件查询,包括了一般查询,所以一个分页条件查询就够了;</p><p>前端处理分页参数;</p><p class="node-read-div2p">参数 说明 提交 aname 条件查询参数 表单提交 author 条件查询参数 表单提交 cid 条件查询参数 表单提交 pageNo 当前页面页码 获取tfoot的pageNum,Ajax提交的时候拼接参数 pageSize 页面大小 获取tfoot的pageSize,Ajax提交的时候拼接参数 totalCount 数据总条数 Ajax获取,然后填入 totalCount 中,分页请求时直接获取</p><pre><code class="language-html"><!-- 条件查询参数 aname author cid -->
<form action="#">
    <p style="text-align: center">
        名称:<input type="text" name="aname" size="15"/>
        作者:<input type="text" name="author" size="15"/>
        分类:<select name="cid" id="cid">
        <option value="0">全部</option>
        </select>
        <input type="button" value = "搜索" id = "searchAnimes" />
    </p>
</form>

<!-- totalCount -->
共&nbsp;<span id="totalCount">5</span>&nbsp;条&nbsp;&nbsp;

<!-- pageSize 和 pageNum -->
每页&nbsp;
<!--  <span id = "pageSize">5</span>&nbsp;  -->
<select name="pageSize" id="pageSize">
    <option value="3" selected>3</option>
    <option value="5">5</option>
    <option value="10">10</option>
</select>
条&nbsp;
当前第&nbsp;<span id = "pageNum">1</span>&nbsp;页&nbsp;/&nbsp;
</code></pre><pre><code class="language-html"><tfoot>
    <tr>
        <td colspan="8" style="height: 40px; text-align: center">
            <input type="button" value="添加" id="addAnime"/>&nbsp;&nbsp;
            <a href="#">首页</a>&nbsp;|&nbsp;
            <a href="#">&lt;&lt;上一页</a>&nbsp;|&nbsp;
            <a href="#">下一页&gt;&gt;</a>&nbsp;|&nbsp;
            <a href="#">尾页</a>&nbsp;|&nbsp;
            共&nbsp;<span id="totalCount">5</span>&nbsp;条&nbsp;&nbsp;
            每页&nbsp;
            <!--  <span id = "pageSize">5</span>&nbsp;  -->
            <select name="pageSize" id="pageSize">
                <option value="3" selected>3</option>
                <option value="5">5</option>
                <option value="10">10</option>
            </select>
            条&nbsp;
            当前第&nbsp;<span id = "pageNum">1</span>&nbsp;页&nbsp;/&nbsp;
            共&nbsp;<span id="totalPage">1</span>&nbsp;页
        </td>
    </tr>
</tfoot>
</code></pre><p>Ajax请求 分页查询的数据总量,并填写到页面上,方便后面分页处理</p><pre><code class="language-javascript">//设置数据总量 函数
function totalCount(){
    //通过 不分页 的条件查询,查询出总数据量
    $.getJSON("animes?mothed=animesCount",$("form").serialize() ,function(data){
        //定义数据总量
        var totalCount = data;

        //alert(" totalCount 数据总量:"+totalCount);
        //获取数据总量元素
        var $totalCount = $("#totalCount");
        //重置数据总量
        $totalCount.text(totalCount);
    });
}
</code></pre><p>包括 上一页,下一页的隐藏处理</p><pre><code class="language-javascript">//分页处理函数
function pageSearch(pageSize,pageNum,totalPage){
    //后去分页数据
    //页面容量 (页面容量可以不操作,我是为了可以手动改变页面容量)
    var $pageSize = $("#pageSize");
    //当前页码
    var $pageNum = $("#pageNum");
    //页面总数
    var $totalPage = $("#totalPage");

    //重置分页数据
    //页面容量 (页面容量可以不处理,因为Ajax异步的,页面不会刷新)
    //$pageSize.text(pageSize);
    $pageSize.val(pageSize);
    //当前页码
    $pageNum.text(pageNum);
    //页面总数
    $totalPage.text(totalPage);

    //处理上一页和下一页
    //上一页
    if(pageNum <= 1){
        $("tfoot a:eq(1)").hide();
    }else{
        $("tfoot a:eq(1)").show();
    }

    //下一页
    if(pageNum >= totalPage){
        $("tfoot a:eq(2)").hide();
    }else{
        $("tfoot a:eq(2)").show();
    }
}

</code></pre><ul><li>获取处理总页数</li><li>分页参数获取 pageNum,pageSize</li><li>动态拼接数据</li><li>处理pageSize,pageNum,totalPage</li></ul><pre><code class="language-javascript">//===页面初始化加载,主动分页条件查询处理===
//分页条件查询处理
pageAnimeList();

//动态 分页 条件 获取动漫数据,动态显示
function pageAnimeList(){
    //处理总页数
    totalCount();

    //获取分页查询的数据
    //页面容量
    var $pageSize = $("#pageSize");
    //pageSize 用 <span> 标签
    //var pageSize = $pageSize.text();
    //pageSize 用 <select> 标签
    var pageSize = $pageSize.val();
    //当前页码
    var $pageNum = $("#pageNum");
    var pageNum = $pageNum.text();

    //数据总数
    //$.getJSON("animes",$("form").serialize() ,function(data){
    //分页查询
    $.getJSON("animes?mothed=pageAnimes&pageNum="+pageNum+"&pageSize="+pageSize,$("form").serialize() ,function(data){
        // 确定数据要动态显示的位置
        var $tbody = $("tbody");

        //如果没有数据,不能显示分页和提示暂无数据
        if(data == null || data == ""){
            //先清空再,显示提示信息
            $tbody.empty().append("<tr align='center'><td colspan='8'>暂无数据</td></tr>");
            //隐藏 tfoot
            $("tfoot").hide();
            //直接返回,因为没有数据,不需要拼接页面
            return;
        }

        // 隔行变色
        var count = 0;

        //定义动态展示内容,如果不定义为空字符的话,一直拼接新数据
        var animeCountent = "";

        // 数据解析
        $(data).each(function(){
            // 定义颜色
            var bgColor = count % 2 == 1 ? "style='background-color:#ddd;'" : "";
            animeCountent +=
                "<tr align='center' " + bgColor + ">"
                + "<td>" + this.id + "</td>"
                + "<td>" + this.cname + "</td>"
                + "<td>" + this.name + "</td>"
                + "<td>" + this.author + "</td>"
                + "<td>" + this.actor + "</td>"
                + "<td>" + this.produce + "</td>"
                + "<td>" + this.create_date + "</td>"
                + "<td><a href='modAnime.jsp?id="+this.id
                +"&cid="+this.cid
                +"&cname="+this.cname
                +"&name="+this.name
                +"&author="+this.author
                +"&actor="+this.actor
                +"&produce="+this.produce
                +"&create_date="+this.create_date+"'>修改</a>&nbsp;&nbsp;"
                + "<a class='delAnime' href='animes?mothed=delAnime&id="+this.id+"'>删除</a>"
                +"</td>"
                + "</tr>";

            count++;
        });
        //清空原来的tbody,添加新的数据
        $tbody.empty().append(animeCountent);
        //有数据就要展示tfoot
        $("tfoot").show();

        //分页处理
        //获取总数据量  处理 页面数量
        //数据总量
        var $totalCount = $("#totalCount");
        var totalCount = $totalCount.text();
        //处理总页数
        var totalPage = 1;

        if((totalCount%pageSize) == 0){
            //alert("totalCount="+totalCount+"pageSize"+pageSize);
            totalPage = totalCount/pageSize;
        }else{
            //alert("totalCount="+totalCount+"pageSize"+pageSize);
            totalPage = ((parseInt(totalCount/pageSize))+1);
        }

        //alert("处理总页数==>>totalPage==>"+totalPage);
        pageSearch(pageSize,pageNum,totalPage);

    });
}

//点击搜索按钮,根据条件筛选数据
$("#searchAnimes").click(function(){
    //分页条件查询
    pageAnimeList();
});

</code></pre><pre><code class="language-javascript">//分页跳转
//首页
$("tfoot a:eq(0)").click(function(){
    $("#pageNum").text(1);
    //分页条件查询
    pageAnimeList();
    return false;
});

// 上一页
$("tfoot a:eq(1)").click(function(){
    var pageNum = parseInt($("#pageNum").text()) - 1;
    $("#pageNum").text(pageNum);
    //分页条件查询
    pageAnimeList();
    return false;
});

// 下一页
$("tfoot a:eq(2)").click(function(){
    //alert("下一页");
    //alert(parseInt($("#pageNum").text()) + 1);
    $("#pageNum").text(parseInt($("#pageNum").text()) + 1);
    //分页条件查询
    pageAnimeList();
    return false;
});

// 尾页
$("tfoot a:eq(3)").click(function(){
    $("#pageNum").text(parseInt($("#totalPage").text()));
    //分页条件查询
    pageAnimeList();
    return false;
});
</code></pre><pre><code class="language-javascript">//修改pageSize
//select标签的change()事件, 切换选项时触发
$("#pageSize").change(function(){
    //获取修改后的 currentPageSize
    var pageSize = $(this).children('option:selected').val();
    //修改页面大小后,再主动查询一次动漫数据
    pageAnimeList();
});
</code></pre><pre><code class="language-java">//条件查询所有的动漫列表条数
protected void animesCount(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    System.out.println("======= AnimesServlet查询所有的动漫的总数量==========");
    String aname = req.getParameter("aname");
    String author = req.getParameter("author");
    String cid = req.getParameter("cid");

    int totalCount = animeService.animeListCount(aname, author, cid);

    String totalCountJson = JSON.toJSONString(totalCount);

    System.out.println("AnimesServlet == >animesCount=动漫总条数==>>"+totalCountJson);
    System.out.println("=============================================");
    resp.getWriter().print(totalCountJson);

}
</code></pre><pre><code class="language-java">//分页条件查询所有的动漫
protected void pageAnimes(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    System.out.println("======= 分页条件查询  AnimesServlet查询所有的动漫列表==========");
    //条件查询参数
    String aname = req.getParameter("aname");
    String author = req.getParameter("author");
    String cid = req.getParameter("cid");

    //分页参数
    Integer pageNum = new Integer(req.getParameter("pageNum"));
    Integer pageSize = new Integer(req.getParameter("pageSize"));

    System.out.println("pageAnimes==> pageNum==>"+pageNum);
    System.out.println("pageAnimes==> pageSize==>"+pageSize);

    List<Anime> animes = animeService.PageSelectAnimeList(aname, author, cid, pageNum, pageSize);

    String animesJson = JSON.toJSONStringWithDateFormat(animes,"yyyy-MM-dd");

    System.out.println(animesJson);
    System.out.println("=============================================");
    resp.getWriter().print(animesJson);

}
</code></pre><p>多个Ajax请求,javaScript<strong>无法控制其执行顺序</strong>,有时候会出错;</p><p>一个请求拿到另外一个请求的<strong>rs中数据</strong>;(这里数据总条数取到了某条数据的id)</p><p>或第二个请求还<strong>没有从rs中取出数据</strong>,<strong>rs就被关闭</strong>(No operations allowed after statement closed.);</p><p>(另外这里还有一个特殊点,<strong>我的setvlet请求是同一个类的多个方法通过反射执行的</strong>);</p><p>这里需要将用来反射调用方法的公共 **dopost方法上锁 synchronized **;</p><pre><code class="language-java">//doPost  方法上锁,保证一次只有一个请求,就保证 一次只有一个SQL执行,一次只有一个rs,就不会数据错乱;
@Override
protected synchronized void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

    //根据请求携带的方法参数名参数,调用不同业务的处理方法

    String mothedName = req.getParameter("mothed") == null ? "animes" : req.getParameter("mothed");

    //利用反射,根据方法名调用指定方法
    try {
        Method method = getClass().getDeclaredMethod(mothedName,HttpServletRequest.class,HttpServletResponse.class);
        method.setAccessible(true);
        method.invoke(this, req,resp);
    } catch (Exception e) {
        e.printStackTrace();
    }

}
</code></pre><h2 id="57-删除">5.7 删除</h2><p>直接带着id到后台删除;</p><pre><code class="language-javascript">+ "<a class='delAnime' href='animes?mothed=delAnime&id="+this.id+"'>删除</a>"

//动态绑定事件(当前和以后添加的元素都可以绑定)
//$(document).on 绑定动态加载子元素的事件
$(document).on('click', '.delAnime', function(){
    if(!confirm("是否确认删除 ${anime.name }")){
        return false;
    }
});
</code></pre><pre><code class="language-java">resp.getWriter().print("<script type='text/javascript'>alert('删除成功!!!'); location.href = 'animeList.jsp'");

5.8 修改

这种方式比较的麻烦,携带的参数太多,不过也是一个方法,可以扩张一下思维;

+ "修改  "

5.9 添加


//添加按钮处理 跳转到添加页面
$("#addAnime").click(function(){
    location.href = "addAnime.jsp";
});

Original: https://www.cnblogs.com/xiaoqigui/p/16564953.html
Author: 化羽羽
Title: Javaweb07-三层架构(BaseDao)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/620378/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Docker Mysql安装和启动

    1、拉取mysql镜像 前往docker官网dockerhub在这里插入图片描述可以在红框内选择指定版本,例如 <span class=”token function”&gt…

    数据库 2023年6月6日
    074
  • java 百度人脸识别 接口代码

    package org.fh.util; import org.json.JSONObject; import java.io.BufferedReader; import jav…

    数据库 2023年6月6日
    082
  • Question06-查询”李”姓老师的数量

    问题比较简单,一个单表查询就可以解决,这里就不过多地讲解 Original: https://www.cnblogs.com/OnlyOnYourself-lzw/p/165738…

    数据库 2023年6月16日
    066
  • 3. 视图-触发器-存储过程-索引

    404. 抱歉,您访问的资源不存在。 可能是URL不正确,或者对应的内容已经被删除,或者处于隐私状态。 [En] It may be that the URL is incorre…

    数据库 2023年5月24日
    078
  • 内部类

    🐓内部类 可以将一个类定义在另一个类或方法中,这样的类称为内部类 将类定义在另一个类中成员的位置 public class Inner { // 定义在类内部 class Demo…

    数据库 2023年6月14日
    064
  • 容器化 | 一文搞定镜像构建方式选型

    作者:安树博 青云科技 PaaS 中间件开发工程师从事 PaaS 中间件服务(Redis/Memcached 等)开发工作,热衷对 NoSQL 数据库领域内技术的学习与研究 官方镜…

    数据库 2023年5月24日
    071
  • Spring Boot yml 公共抽取

    项目里面的yml文件为了区别线上、测试、本地环境,分别有application-prod.yml,application-dev.yml,application-local.yml…

    数据库 2023年6月6日
    078
  • Consul 入门-集群搭建

    集群搭建 通过 Docker 来搭建一个由3个 Server 组成的数据中心集群,再启动一个 Client 容器来做服务注册和发现的入口,开模拟看看 Server 启动命令 拉取最…

    数据库 2023年6月6日
    082
  • MySQL连接的建立与使用

    在 MYSQL的启动过程中,可以看到在 mysqld_main() 函数的最后调用了 mysqld_socket_acceptor->connection_event_loo…

    数据库 2023年6月9日
    071
  • 2022-8-26 jq简单了解

    Query 是一个 JavaScript 函数库。 jQuery 是一个轻量级的”写的少,做的多”的 JavaScript 库。jQuery 库包含以下功能…

    数据库 2023年6月14日
    0114
  • mysql练习题emp,dept

    DROP DATABASE IF EXISTS emp; CREATE DATABASE emp; USE emp; &#xA0;CREATE TABLE dept( &a…

    数据库 2023年6月9日
    0168
  • Our Feeling

    走过春夏秋冬走过五湖四海就是没有走过你 看过日出日落看过潮起潮落就是看不到你 本文来自博客园,作者:ukyo–BlackJesus,转载请注明原文链接:https://…

    数据库 2023年6月11日
    086
  • 尚硅谷Git教程

    尚硅谷Git教程BV1vy4y1s7k6 免费 开源 分布式版本控制工具 / 集中式版本控制工具 本地库、暂存区域、工作流分支 弹幕:应该是git比SVN多了个本地仓库。SVN中央…

    数据库 2023年6月11日
    088
  • 用Python自动实现图表可视化操作,提高工作效率,又能有更多的时间摸鱼了~

    在数据分析过程中,一般提取数据库里面的数据时候,拿着表格数据反复思索,希望能够根据自己所想立马生成一张数据可视化的图表来更直观的呈现数据。 但想要进行数据可视化的时候,往往需要调用…

    数据库 2023年6月14日
    049
  • ShardingSphere 异构迁移最佳实践:将3.5亿量级的顾客系统 RTO 减少60倍

    Apache ShardingSphere 助力当当 3.5 亿用户量级顾客系统重构,由 PHP+SQL Server 技术栈无缝转型为 Java+ShardingSphere+M…

    数据库 2023年6月16日
    0103
  • 【数据库】– MySQL SQL调优笔记(1)

    1.索引 1.1.定义 MySQL官方对索引的定义为:索引(Index)是帮助MySQL高效获取数据的数据结构。 我们平常所说的索引,如何没有特别的指明,都是B树(多路搜索树,并不…

    数据库 2023年5月24日
    0110
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球