Bootstrap

Java AJAX

第01节 基础理论

1、概念说明

1. 什么是 AJAX ?
    AJAX是一项技术合集。他是由一套技术组合得到的新技术方案。 异步请求技术
​
2. AJAX有什么作用呢?
    使用Ajax技术网页应用能够快速地将增量更新呈现在用户界面上,
    而不需要重载(刷新)整个页面,这使得程序能够更快地回应用户的操作。
    
3. 异步和同步的概念说明?
    A. 异步: 多个操作是相互独立的过程, 各自完成各自的操作,互不影响。
    B. 同步: 多个操作是有先后顺序的执行,只有前面的操作执行完成,才能执行下一步的操作。
​
4. 常见的应用常见?
    A. 校验用户名是否占用
    B. 搜索联想的效果
    C. 省级联动
    D. 分页效果

2、异步理解

画图说明(异步和同步)

3、实现方案

方案一:  JavaScript 的原生态方式实现 Ajax
方案二:  JQuery 的方式实现 Ajax

第02节 原生JS实现

1、操作步骤

1、在JS的事件函数当中, 去创建 XMLHttpRequest() 的对象
2、设置回调函数,当异步请求ajax完毕之后的效果  xhttp.onreadystatechange = functin(){ ... }
3、打开链接 xhttp.open("请求方式","请求的链接URL",是否支持异步)
4、发送请求 xhttp.send();

2、案例代码

位置 src/blb.chc01.ReginServlet

//定义注册的Servlet类

/****
 * http://localhost:8080/JavaWebDay24/ReginServlet?username=zhangsan
 */
@WebServlet("/ReginServlet")
public class ReginServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("ReginServlet.doGet");
        doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("ReginServlet.doPost");
        //接收到客户端浏览器发送过来的参数信息
        String username = req.getParameter("username");
        //判断是否包含有指定的信息
        ArrayList<String> mList = new ArrayList<>();
        mList.add("zhangsan");
        mList.add("lisi");
        mList.add("wangwu");
        //=====[线程休眠10秒,模拟网络卡顿]======
        try {
            Thread.sleep(10*1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //==============================
        String message;
        //判断一下数据是否存在? 判断集合当中是否包含有 username值
        if (mList.contains(username)){
            //数据已经存在
            message = "<span style='color:red'>用户名已经被占用</span>";
        }else{
            //数据已经存在
            message = "<span style='color:green'>用户名可以使用</span>";
        }
        //回复数据
        resp.setContentType("text/html;charset=UTF-8");
        resp.getWriter().println(message);
    }
}

位置 web/page/regin01.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>注册页面-原生JS实现AJAX</title>
</head>
<body>


<h3> 采用原生的JavaScript实现 AJAX </h3>

<form method="get" action="/JavaWebDay24/ReginServlet">

    <div>
        <label for="username">账号:</label>
        <input type="text" id="username" name="username" placeholder="请输入账号">
        <span id="usernameSpan"></span>
    </div>
    <div>
        <label for="password">密码:</label>
        <input type="text"  id="password" name="password" placeholder="请输入密码">
        <span id="passwordSpan"></span>
    </div>
    <div>
        <input type="submit" value="确认注册">
    </div>
</form>

</body>
</html>

<script>
    //页面加载完毕之后的函数,类似于 JQuery的入口函数
    window.onload = function () {
        //给我们的 用户名的输入框,绑定事件,绑定失去焦点的事件。
        document.querySelector("#username").onblur = function () {
            //获取到输入框当中输入的数据
            let username = this.value;
            //----------------------------
            //1. 准备XMLHttpRequest的对象
            let xhttp = new XMLHttpRequest();
            //2. 设置回调函数,当请求发送完毕,接收数据之后做的事情
            xhttp.onreadystatechange = function () {
                //判断当前的状态。200响应成功,4表示请求成功。
                if (xhttp.readyState===4 && xhttp.status === 200){
                    document.querySelector("#usernameSpan").innerHTML = xhttp.responseText;
                }
            }
            //3. 打开链接
            let urlMessage = "/JavaWebDay24/ReginServlet?username="+username;
            //参数1: 请求的方式
            //参数2: 请求的URL地址
            //参数3: 是否支持异步操作 true 表示支持
            xhttp.open("GET",urlMessage,true);
            //4. 发送请求
            xhttp.send();
        }
    }
</script>

第03节 JQuery实现Ajax

1、发送GET请求

操作步骤

$.get("请求的URL地址",function回调函数);

案例代码

位置 src/blb.chc01.ReginServlet

//定义注册的Servlet类

/****
 * http://localhost:8080/JavaWebDay24/ReginServlet?username=zhangsan
 */
@WebServlet("/ReginServlet")
public class ReginServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("ReginServlet.doGet");
        doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("ReginServlet.doPost");
        //接收到客户端浏览器发送过来的参数信息
        String username = req.getParameter("username");
        Map<String, String[]> map = req.getParameterMap();
        map.forEach((key,value)-> System.out.println(key+","+value));
        //判断是否包含有指定的信息
        ArrayList<String> mList = new ArrayList<>();
        mList.add("zhangsan");
        mList.add("lisi");
        mList.add("wangwu");
        String message;
        //判断一下数据是否存在? 判断集合当中是否包含有 username值
        if (mList.contains(username)){
            //数据已经存在
            message = "<span style='color:red'>用户名已经被占用</span>";
        }else{
            //数据已经存在
            message = "<span style='color:green'>用户名可以使用</span>";
        }
        //回复数据
        resp.setContentType("text/html;charset=UTF-8");
        resp.getWriter().println(message);
    }
}

位置 web/page/regin04.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>注册页面-采用JQuery发送GET请求,实现AJAX</title>
</head>
<body>

<h3> 采用JQuery发送GET请求,实现AJAX </h3>

<form method="get" action="${pageContext.request.contextPath}/ReginServlet">

    <div>
        <label for="username">账号:</label>
        <input type="text" id="username"
               name="username" placeholder="请输入账号">
        <span id="usernameSpan"></span>
    </div>
    <div>
        <label for="password">密码:</label>
        <input type="text" id="password"
               name="password" placeholder="请输入密码">
        <span id="passwordSpan"></span>
    </div>
    <div>
        <input type="submit" value="确认注册">
    </div>
</form>
</body>
</html>

<script src="../js/jquery-3.3.1.min.js"></script>
<script>
    $(function () {
        //输入框失去焦点之后的事件处理
        $("#username").blur(function () {
            //获取到输入框的数据值
            let username = this.value;
            //采用Ajax发送get请求
            let url = "${pageContext.request.contextPath}/ReginServlet" + "?username="+username;
            //参数1: 发送请求的URL地址
            //参数2: 回调函数,当请求发送之后,响应的数据,响应的数据值就是 data
            $.get(url,function (data) {
                $("#usernameSpan").html(data);
            });
        });
    });
</script>

2、发送POST请求

操作步骤

$.post("请求的URL地址",请求参数,function回调函数);

案例代码

位置 src/blb.chc01.ReginServlet

//定义注册的Servlet类

/****
 * http://localhost:8080/JavaWebDay24/ReginServlet?username=zhangsan
 */
@WebServlet("/ReginServlet")
public class ReginServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("ReginServlet.doGet");
        doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("ReginServlet.doPost");
        //接收到客户端浏览器发送过来的参数信息
        String username = req.getParameter("username");
        Map<String, String[]> map = req.getParameterMap();
        map.forEach((key,value)-> System.out.println(key+","+value));
        //判断是否包含有指定的信息
        ArrayList<String> mList = new ArrayList<>();
        mList.add("zhangsan");
        mList.add("lisi");
        mList.add("wangwu");
        String message;
        //判断一下数据是否存在? 判断集合当中是否包含有 username值
        if (mList.contains(username)){
            //数据已经存在
            message = "<span style='color:red'>用户名已经被占用</span>";
        }else{
            //数据已经存在
            message = "<span style='color:green'>用户名可以使用</span>";
        }
        //回复数据
        resp.setContentType("text/html;charset=UTF-8");
        resp.getWriter().println(message);
    }
}

位置 web/page/regin05.jsp

<html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>注册页面-采用JQuery发送POST请求,实现AJAX</title>
</head>
<body>

<h3> 采用JQuery发送POST请求,实现AJAX </h3>

<form method="post" action="${pageContext.request.contextPath}/ReginServlet">

    <div>
        <label for="username">账号:</label>
        <input type="text" id="username"
               name="username" placeholder="请输入账号">
        <span id="usernameSpan"></span>
    </div>
    <div>
        <label for="password">密码:</label>
        <input type="text" id="password"
               name="password" placeholder="请输入密码">
        <span id="passwordSpan"></span>
    </div>
    <div>
        <input type="submit" value="确认注册">
    </div>
</form>
</body>
</html>

<script src="../js/jquery-3.3.1.min.js"></script>
<script>
    $(function () {
        //输入框失去焦点之后的事件处理
        $("#username").blur(function () {
            //获取到输入框的数据值
            let username = this.value;
            //采用Ajax发送get请求
            let url = "${pageContext.request.contextPath}/ReginServlet";
            let params = {
                "username":username
            };
            //参数1: 发送请求的URL地址
            //参数2: 请求参数
            //参数3: 回调函数,当请求发送之后,响应的数据,响应的数据值就是 data
            $.post(url,params,function (data) {
                $("#usernameSpan").html(data);
            });
        });
    });
</script>

3、发送通用请求

操作步骤

$.ajax({
    键1:"值1",
    键2:"值2",
    键3:"值3"
});

案例代码

位置 src/blb.chc01.ReginServlet

//定义注册的Servlet类

/****
 * http://localhost:8080/JavaWebDay24/ReginServlet?username=zhangsan
 */
@WebServlet("/ReginServlet")
public class ReginServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("ReginServlet.doGet");
        doPost(req,resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("ReginServlet.doPost");
        //接收到客户端浏览器发送过来的参数信息
        String username = req.getParameter("username");
        Map<String, String[]> map = req.getParameterMap();
        map.forEach((key,value)-> System.out.println(key+","+value));
        //判断是否包含有指定的信息
        ArrayList<String> mList = new ArrayList<>();
        mList.add("zhangsan");
        mList.add("lisi");
        mList.add("wangwu");
        String message;
        //判断一下数据是否存在? 判断集合当中是否包含有 username值
        if (mList.contains(username)){
            //数据已经存在
            message = "<span style='color:red'>用户名已经被占用</span>";
        }else{
            //数据已经存在
            message = "<span style='color:green'>用户名可以使用</span>";
        }
        //回复数据
        resp.setContentType("text/html;charset=UTF-8");
        resp.getWriter().println(message);
    }
}

位置 web/page/regin06.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>注册页面-采用JQuery发送通用请求,实现AJAX</title>
</head>
<body>

<h3> 采用JQuery发送通用请求,实现AJAX </h3>

<form method="get" action="${pageContext.request.contextPath}/ReginServlet">

    <div>
        <label for="username">账号:</label>
        <input type="text" id="username"
               name="username" placeholder="请输入账号">
        <span id="usernameSpan"></span>
    </div>
    <div>
        <label for="password">密码:</label>
        <input type="text" id="password"
               name="password" placeholder="请输入密码">
        <span id="passwordSpan"></span>
    </div>
    <div>
        <input type="submit" value="确认注册">
    </div>
</form>
</body>
</html>

<script src="../js/jquery-3.3.1.min.js"></script>
<script>
    $(function () {
        //输入框失去焦点之后的事件处理
        $("#username").blur(function () {
            //获取到输入框的数据值
            let username = this.value;
            //采用通用的方式去发送 ajax请求
            /***
             * url: 表示的是请求的URL地址
             * data: 请求的参数信息
             * async: 表示是否支持异步操作,true表示支持,false表示不支持。默认是true
             * type: 请求的类型,GET或者POST
             * success: 请求成功之后的回调函数,当成功之后,做什么
             */
            $.ajax({
                url:"${pageContext.request.contextPath}/ReginServlet",
                data:{
                    "username":username
                },
                async:true,
                type:"POST",
                success:function (data) {
                    $("#usernameSpan").html(data);
                }
            });
        });
    });
</script>

第二章 JSON

第01节 基础理论

1、三种json格式

格式一:
    A. 类型: 
        对象类型
    B. 语法:
        {"name":"zhangsan","age":23,"gender":"男"}
    C. 说明:
        键是字符串类型, 值是任意类型。对象类型,采用大括号包起来。
​
格式二:
    A. 类型:
        数组类型
    B. 语法:
        [{"name":"zhangsan","age":23,"gender":"男"},{"name":"lisi","age":24,"gender":"男"}]
    C. 说明:
        对象类型,采用是中括号,包裹着对象,对象是大括号包裹着,里面由键值对组成
​
格式三:
    A. 类型:
        混合类型
    B: 语法:
        {message:[{"name":"zhangsan","age":23,"gender":"男"},{"name":"lisi","age":24,"gender":"男"}]}
    C. 说明:
        由对象和数组,综合在一起组成的效果

2、常用的类

操作步骤

在这里我们采用的是 jacksonJSON 解析的方式。SpringMVC 当中内置的解析方式。
​
操作步骤:
    A. 导入jar包   
        jackson-annotations-2.2.1.jar
        jackson-core-2.2.1.jar
        jackson-databind-2.2.1.jar
    B. 创建ObjectMapper的对象
    C. 读写数据 readAs...  writeAs...

常用类

1. ObjectMapper 他是我们 JacksonJson的核心类
2. TypeReference 主要是针对于集合的泛型,进行操作的

第02节 案例代码

1、对象变成JSON

//专门用于测试,写对象的操作
@SuppressWarnings("all")
public class Demo01 {

    //写对象
    //{"name":"张三","age":23,"gender":"男"}
    @Test
    public void testWriteObject() throws Exception {
        //创建对象
        Student stu = new Student("张三", 23, "男");
        //写对象
        ObjectMapper mapper = new ObjectMapper();
        String json = mapper.writeValueAsString(stu);
        System.out.println(json);
        //将数据保存到文件当中
        String path = "C:\\develop\\workspace\\java210712A\\JavaWebDay24\\web\\dir\\object.txt";
        BufferedWriter bw = new BufferedWriter(new FileWriter(path));
        bw.write(json);
        bw.newLine();
        bw.flush();
        bw.close();
    }

    //写数组
    //[{"name":"张三","age":23,"gender":"男"},{"name":"李四","age":24,"gender":"女"}]
    @Test
    public void testWriteArray() throws Exception {
        //创建对象
        Student stu1 = new Student("张三", 23, "男");
        Student stu2 = new Student("李四", 24, "女");
        ArrayList<Student> mlist = new ArrayList<>();
        mlist.add(stu1);
        mlist.add(stu2);
        //写数组
        ObjectMapper mapper = new ObjectMapper();
        String json = mapper.writeValueAsString(mlist);
        System.out.println(json);
        //将数据保存到文件当中
        String path = "C:\\develop\\workspace\\java210712A\\JavaWebDay24\\web\\dir\\array.txt";
        BufferedWriter bw = new BufferedWriter(new FileWriter(path));
        bw.write(json);
        bw.newLine();
        bw.flush();
        bw.close();
    }

	//写复杂类型
    //{"message":[{"name":"张三","age":23,"gender":"男"},{"name":"李四","age":24,"gender":"女"}],"status":200}
    @Test
    public void testWriteComplex() throws Exception{
        //创建对象
        Student stu1 = new Student("张三", 23, "男");
        Student stu2 = new Student("李四", 24, "女");
        List<Student> mlist = new ArrayList<>();
        mlist.add(stu1);
        mlist.add(stu2);
        HashMap<String, Object> map = new HashMap<>();
        map.put("message",mlist);
        map.put("status",200);
        ObjectMapper mapper = new ObjectMapper();
        String json = mapper.writeValueAsString(map);
        System.out.println(json);

        //将数据保存到文件当中
        String path = "C:\\develop\\workspace\\java210712A\\JavaWebDay24\\web\\dir\\complex.txt";
        BufferedWriter bw = new BufferedWriter(new FileWriter(path));
        bw.write(json);
        bw.newLine();
        bw.flush();
        bw.close();
    }
}

2、JSON转变对象

//如果是JSON转换成为对象
@SuppressWarnings("all")
public class Demo02 {

    //读取对象的操作
    //{"name":"张三","age":23,"gender":"男"}
    @Test
    public void testReadObject() throws Exception {
        String json;
        String path = "C:\\develop\\workspace\\java210712A\\JavaWebDay24\\web\\dir\\object.txt";
        BufferedReader br = new BufferedReader(new FileReader(path));
        json = br.readLine();
        br.close();
        System.out.println("json = " + json);
        //将数据转换成为对象
        ObjectMapper mapper = new ObjectMapper();
        Student stu = mapper.readValue(json, Student.class);
        System.out.println("stu = " + stu);
    }

    //读取数组的操作
    //[{"name":"张三","age":23,"gender":"男"},{"name":"李四","age":24,"gender":"女"}]
    @Test
    public void testReadArray() throws Exception {
        String json;
        String path = "C:\\develop\\workspace\\java210712A\\JavaWebDay24\\web\\dir\\array.txt";
        BufferedReader br = new BufferedReader(new FileReader(path));
        json = br.readLine();
        br.close();
        System.out.println("json = " + json);
        //将数据转换成为数组
        ObjectMapper mapper = new ObjectMapper();
        List<Student> mList = mapper.readValue(json, new TypeReference<List<Student>>() {
        });
        //展示结果
        mList.forEach(System.out::println);
    }


    //读取复杂的操作
    //{"message":[{"name":"张三","age":23,"gender":"男"},{"name":"李四","age":24,"gender":"女"}],"status":200}
    @Test
    public void testReadComplex() throws Exception {
        String json;
        String path = "C:\\develop\\workspace\\java210712A\\JavaWebDay24\\web\\dir\\complex.txt";
        BufferedReader br = new BufferedReader(new FileReader(path));
        json = br.readLine();
        br.close();
        System.out.println("json = " + json);
        //将数据转换成为数组
        ObjectMapper mapper = new ObjectMapper();
        //更换另外一套API操作
        JsonNode rootNode = mapper.readTree(json);
        String s = rootNode.get("message").toString();
        //对message的信息,再次进行JSON解析
        List<Student> mlist = mapper.readValue(s,new TypeReference<List<Student>>(){});
        mlist.forEach(System.out::println);
    }
}

第三章 综合案例

第01节 需求说明

1、需求介绍

制作一个搜索联想的案例,在输入框当中输入人物的姓,可以展示所有的与姓相关的名字。
​
例如:
    在输入框当中, 输入数据 "宋"
    可以展示得到以下几个数据:  "宋江"、"宋清"、"宋万"

2、分析说明

第02节 案例代码

1、数据准备

-- 01. 使用数据库
DROP DATABASE IF EXISTS db01;
CREATE DATABASE IF NOT EXISTS db01;
USE db01;
 
-- 02. 删除表,如果存在则删除
DROP TABLE IF EXISTS waterhero;
 
-- 03. 创建表
CREATE TABLE IF NOT EXISTS waterhero (
  id INT(3) PRIMARY KEY AUTO_INCREMENT,     -- 编号
  rank VARCHAR(16),                         -- 排名
  star VARCHAR(16),                         -- 星座
  nicename VARCHAR(16),                     -- 人物花名
  truename VARCHAR(16),                     -- 真实姓名
  description VARCHAR(1024)                 -- 性格描述 
);
 
-- 04. 插入数据
INSERT INTO waterhero VALUES ('1', '一', '天魁星', '及时雨(呼保义)', '宋江', '孝顺忠君 有领导才能');
INSERT INTO waterhero VALUES ('2', '二', '天罡星', '玉麒麟', '卢俊义', '武功高强,为人固执');
INSERT INTO waterhero VALUES ('3', '三', '天机星', '智多星', '吴用', '足智多谋,善用计策');
INSERT INTO waterhero VALUES ('4', '四', '天闲星', '入云龙', '公孙胜', '正直大气,武艺高强');
INSERT INTO waterhero VALUES ('5', '五', '天勇星', '大刀', '关胜', '文武双全,赤胆忠心');
INSERT INTO waterhero VALUES ('6', '六', '天雄星', '豹子头', '林冲', '为人正直,隐忍善良');
INSERT INTO waterhero VALUES ('7', '七', '天猛星', '霹雳火', '秦明', '性格急躁,声如雷霆');
INSERT INTO waterhero VALUES ('8', '八', '天威星', '双鞭', '呼延灼', '正直,大气');
INSERT INTO waterhero VALUES ('9', '九', '天英星', '小李广', '花荣', '武功高强,为人仗义');
INSERT INTO waterhero VALUES ('10', '十', ' 天贵星', '小旋风', '柴进', ' 为人慷慨,见义勇为');
INSERT INTO waterhero VALUES ('11', '十一', '天富星', '扑天雕', '李应', '嫉恶如仇,见义勇为');
INSERT INTO waterhero VALUES ('12', '十二', '天满星', '美髯公', '朱仝', '仗义疏财,义字当头');
INSERT INTO waterhero VALUES ('13', '十三', '天孤星', '花和尚', '鲁智深', '心地刚直,生性凶顽');
INSERT INTO waterhero VALUES ('14', '十四', '天伤星', '行者', '武松', '光明磊落,敢作敢为');
INSERT INTO waterhero VALUES ('15', '十五', '天立星', '双枪将', '董平', '冲动 忠肝义胆  好胜');
INSERT INTO waterhero VALUES ('16', '十六', '天捷星', '没羽箭', '张清', '性格内向,非常内敛');
INSERT INTO waterhero VALUES ('17', '十七', '天暗星', '青面兽', '杨志', '勤快,身手不凡');
INSERT INTO waterhero VALUES ('18', '十八', '天佑星', '金枪手', '徐宁', '胆大,有万夫不挡之勇');
INSERT INTO waterhero VALUES ('19', '十九', '天空星', '急先锋', '索超', '性子急,执着,鲁莽');
INSERT INTO waterhero VALUES ('20', '二十', '天速星', '神行太保', '戴宗', '嫉恶如仇、侠肝义胆、脾气火爆');
INSERT INTO waterhero VALUES ('21', '二十一', '天异星', '赤发鬼', '刘唐', '勇猛莽撞');
INSERT INTO waterhero VALUES ('22', '二十二', '天杀星', '黒旋风', '李逵 ', '正直粗鲁,勇猛无比');
INSERT INTO waterhero VALUES ('23', '二十三', '天微星', '九纹龙', '史进', '武艺高超,嫉恶如仇');
INSERT INTO waterhero VALUES ('24', '二十四', '天究星', '没遮拦', '穆弘', '平凡善良、耐心平和、持重端庄');
INSERT INTO waterhero VALUES ('25', '二十五', '天退星', '插翅虎', '雷横', '脾气暴躁,为人耿直');
INSERT INTO waterhero VALUES ('26', '二十六', '天寿星', '混江龙', '李俊', '为人正直,水中功夫超强');
INSERT INTO waterhero VALUES ('27', '二十七', '天剑星', '立地太岁', '阮小二', '武艺出众,英勇善战');
INSERT INTO waterhero VALUES ('28', '二十八', '天平星', '船火儿', '张横', '英勇善战');
INSERT INTO waterhero VALUES ('29', '二十九', '天罪星', '短命二郎', '阮小五', '水中好汉,奋勇杀敌');
INSERT INTO waterhero VALUES ('30', '三十', '天损星', '浪里白条', '张顺', '水中功夫好,豪爽仗义,惩恶济善,有仇必报');
INSERT INTO waterhero VALUES ('31', '三十一', '天败星', '活阎罗', '阮小七', '心快口快');
INSERT INTO waterhero VALUES ('32', '三十二', '天牢星', '病关索', '杨雄', '为人正直');
INSERT INTO waterhero VALUES ('33', '三十三', '天慧星', '拼命三郎', '石秀', '打抱不平');
INSERT INTO waterhero VALUES ('34', '三十四', '天暴星', '两头蛇', '解珍', '作战英勇');
INSERT INTO waterhero VALUES ('35', '三十五', '天哭星', '双尾蝎', '解宝', '为人灵活,作战英勇');
INSERT INTO waterhero VALUES ('36', '三十六', '天巧星', '浪子', '燕青', '武功高强,为人风流');
INSERT INTO waterhero VALUES ('37', '三十七', '地魁星', '神机军师', '朱武', '精通阵法,广有谋略');
INSERT INTO waterhero VALUES ('38', '三十八', '地煞星', '镇三山', '黄信', '一身好武艺,英勇善战');
INSERT INTO waterhero VALUES ('39', '三十九', '地勇星', '病尉迟', '孙立', '精熟弓马,武艺过人,正直');
INSERT INTO waterhero VALUES ('40', '四十', '地杰星', '丑郡马', '宣赞', '相貌丑陋,武艺出众');
INSERT INTO waterhero VALUES ('41', '四十一', '地雄星', '井木犴', '郝思文', '仗义侠胆,有勇有谋');
INSERT INTO waterhero VALUES ('42', '四十二', '地威星', '百胜将', '韩滔', '力大无穷,有勇有谋');
INSERT INTO waterhero VALUES ('43', '四十三', '地英星', '天目将', '彭玘', '扶危救困,义气第一');
INSERT INTO waterhero VALUES ('44', '四十四', '地奇星', '圣水将', '单廷圭', '风流潇洒,气宇轩昂');
INSERT INTO waterhero VALUES ('45', '四十五', '地猛星', '神火将', '魏定国', '风流潇洒,礼貌待人');
INSERT INTO waterhero VALUES ('46', '四十六', '地文星', '圣手书生', '萧让', '擅长写字,不爱说话');
INSERT INTO waterhero VALUES ('47', '四十七', '地正星', '铁面孔目', '裴宣', '忍辱负重,忠诚憨厚');
INSERT INTO waterhero VALUES ('48', '四十八', '地阔星', '摩云金翅', '欧鹏', '武功不低,挫折感强,比较谨慎');
INSERT INTO waterhero VALUES ('49', '四十九', '地阖星', '火眼狻猊', '邓飞', '武功不差,舍己为人');
INSERT INTO waterhero VALUES ('50', '五十', '地强星', '锦毛虎', '燕顺', '有情有义,重英雄');
INSERT INTO waterhero VALUES ('51', '五十一', '地暗星', '锦豹子', '杨林', '聪明,比较谨慎');
INSERT INTO waterhero VALUES ('52', '五十二', '地轴星', '轰天雷', '凌振', '精通武艺,是一个非常厉害的人物');
INSERT INTO waterhero VALUES ('53', '五十三', '地会星', '神算子', '蒋敬', '武艺高强,胆大');
INSERT INTO waterhero VALUES ('54', '五十四', '地佐星', '小温侯', '吕方', '为人忠义 武功高强 不服输');
INSERT INTO waterhero VALUES ('55', '五十五', '地佑星', '赛仁贵', '郭盛', '有勇无谋,义气为重');
INSERT INTO waterhero VALUES ('56', '五十六', '地灵星', '神医', '安道全', '医术高明,好色');
INSERT INTO waterhero VALUES ('57', '五十七', '地兽星', '紫髯伯', '皇甫端', '医道高明,诊治马病,手到病除,胡须大紫');
INSERT INTO waterhero VALUES ('58', '五十八', '地微星', '矮脚虎', '王英', '身材矮小,脾气暴躁');
INSERT INTO waterhero VALUES ('59', '五十九', '地慧星', '一丈青', '扈三娘', '机智聪明,为人仗义');
INSERT INTO waterhero VALUES ('60', '六十', '地暴星', '丧门神', '鲍旭', '正直粗鲁,勇猛无比');
INSERT INTO waterhero VALUES ('61', '六十一', '地然星', '混世魔王', '樊瑞', '阴柔有余、阳刚不足');
INSERT INTO waterhero VALUES ('62', '六十二', '地猖星', '毛头星', '孔明', '为人行侠仗义 武艺平平 忠肝义胆');
INSERT INTO waterhero VALUES ('63', '六十三', '地狂星', '独火星', '孔亮', '本事低微,武功很差');
INSERT INTO waterhero VALUES ('64', '六十四', '地飞星', '八臂哪吒', '项充', '有情有义,武艺高强');
INSERT INTO waterhero VALUES ('65', '六十五', '地走星', '飞天大圣', '李衮', ' 武艺高强 四海之内皆兄');
INSERT INTO waterhero VALUES ('66', '六十六', '地巧星', '玉臂匠', '金大坚', '技艺高超,善于雕刻');
INSERT INTO waterhero VALUES ('67', '六十七', '地明星', '铁笛仙', '马麟', '好勇斗狠,讲义气');
INSERT INTO waterhero VALUES ('68', '六十八', '地进星', '出洞蛟', '童威', '能伏水,会驾船');
INSERT INTO waterhero VALUES ('69', '六十九', '地退星', '翻江蜃', '童猛', '水性极好');
INSERT INTO waterhero VALUES ('70', '七十', '地满星', '玉幡竿', '孟康', '人高马大,善于制造大小船只');
INSERT INTO waterhero VALUES ('71', '七十一', '地遂星', '通臂猿', '侯健', '飞针走线,技艺高超');
INSERT INTO waterhero VALUES ('72', '七十二', '地周星', '跳涧虎', '陈达', '体魄强健,生性粗鲁');
INSERT INTO waterhero VALUES ('73', '七十三', '地隐星', '白花蛇', '杨春', '使一口大杆刀,武艺精熟');
INSERT INTO waterhero VALUES ('74', '七十四', '地异星', '白面郎君', '郑天寿', '鲁莽,比较重义气');
INSERT INTO waterhero VALUES ('75', '七十五', '地理星', '九尾龟', '陶宗旺', '力大无比,正直勇敢');
INSERT INTO waterhero VALUES ('76', '七十六', '地俊星', '铁扇子', '宋清', '为人诚恳,热情好客');
INSERT INTO waterhero VALUES ('77', '七十七', '地乐星', '铁叫子', '乐和', '文武全行、且兴趣广泛、聪明绝顶');
INSERT INTO waterhero VALUES ('78', '七十八', '地捷星', '花项虎', '龚旺', '一生行侠仗义,性格耿直');
INSERT INTO waterhero VALUES ('79', '七十九', '地速星', '中箭虎', '丁得孙', '为人勇猛 武艺高强 艺高 胆大 有义气');
INSERT INTO waterhero VALUES ('80', '八十', '地镇星', '小遮拦', '穆春', '武艺高强 崇尚忠义');
INSERT INTO waterhero VALUES ('81', '八十一', '地羁星', '操刀鬼', '曹正', '平时像个孩子,性格天真 活泼。但战斗时,不顾一切战斗');
INSERT INTO waterhero VALUES ('82', '八十二', '地魔星', '云里金刚', '宋万', '高大威猛,武艺平常');
INSERT INTO waterhero VALUES ('83', '八十三', '地妖星', '摸着天', '杜迁', '本事平平,武艺一般');
INSERT INTO waterhero VALUES ('84', '八十四', '地幽星', '病大虫', '薛永', '讲义气,重朋友');
INSERT INTO waterhero VALUES ('85', '八十五', '地僻星', '打虎将', '李忠', '做事悭吝小气 不慷慨');
INSERT INTO waterhero VALUES ('86', '八十六', '地空星', '小霸王', '周通', '鲁莽,粗暴,不仗义');
INSERT INTO waterhero VALUES ('87', '八十七', '地孤星', '金钱豹子', '汤隆', '为人义气,性情耿直,为山寨尽心竭力');
INSERT INTO waterhero VALUES ('88', '八十八', '地全星', '鬼脸儿', '杜兴', '鲁莽,讲义气');
INSERT INTO waterhero VALUES ('89', '八十九', '地短星', '出林龙', '邹渊', '冲动 好赌 贪婪');
INSERT INTO waterhero VALUES ('90', '九十', '地角星', '独角龙', '邹润', '慷慨大义');
INSERT INTO waterhero VALUES ('91', '九十一', '地囚星', '旱地忽律', '朱贵', '性格直率,善良');
INSERT INTO waterhero VALUES ('92', '九十二', '地藏星', '笑面虎', '朱富', '行侠仗义 嫉恶如仇 仔细 谨慎');
INSERT INTO waterhero VALUES ('93', '九十三', '地伏星', '金眼彪', '施恩', '使得一身好拳棒,会施展恩惠');
INSERT INTO waterhero VALUES ('94', '九十四', '地平星', '铁臂膊', '蔡福', '替天行道,正义');
INSERT INTO waterhero VALUES ('95', '九十五', '地损星', '一枝花', '蔡庆', '大义,武功高强');
INSERT INTO waterhero VALUES ('96', '九十六', '地奴星', '催命判官', '李立', '武艺高超,为人仗义');
INSERT INTO waterhero VALUES ('97', '九十七', '地察星', '青眼虎', '李云', '率直 仗义');
INSERT INTO waterhero VALUES ('98', '九十八', '地恶星', '没面目', '焦挺', '拳脚熟练,讲义气');
INSERT INTO waterhero VALUES ('99', '九十九', '地丑星', '石将军', '石勇', '武功一般,粗蛮胆大');
INSERT INTO waterhero VALUES ('100', '一百', '地数星', '小尉迟', '孙新', '正直勇敢,讲义气');
INSERT INTO waterhero VALUES ('101', '一百零一', '地阴星', '母大虫', '顾大嫂', '豪爽急躁,倔强暴躁');
INSERT INTO waterhero VALUES ('102', '一百零二', '地刑星', '菜园子', '张青', '性格内向,憨厚老实');
INSERT INTO waterhero VALUES ('103', '一百零三', '地壮星', '母夜叉', '孙二娘', '性情暴躁,举止粗鲁');
INSERT INTO waterhero VALUES ('104', '一百零四', '地劣星', '活闪婆', '王定六', '嫉恶如仇 识英雄 路见不平拔刀相助');
INSERT INTO waterhero VALUES ('105', '一百零五', '地健星', '险道神', '郁保四', '忠义双全 重英雄');
INSERT INTO waterhero VALUES ('106', '一百零六', '地耗星', '白日鼠', '白胜', '仗义,坚定');
INSERT INTO waterhero VALUES ('107', '一百零七', '地贼星', '鼓上蚤', '时迁', '聪明机智,社会经验丰富 ,善于乔装打扮');
INSERT INTO waterhero VALUES ('108', '一百零八', '地狗星', '金毛犬', '段景住', '性格沉稳,脾气好');
 

-- 05. 查询数据表
SELECT * FROM waterhero;

2、Dao和Service实现

位置 src/blb.chc03.bean.HeroBean

public class HeroBean {

    private int id;
    private String rank;
    private String star;
    private String nicename;
    private String truename;
    private String description;

    public HeroBean() {
    }

    public HeroBean(int id, String rank, String star, String nicename, String truename, String description) {
        this.id = id;
        this.rank = rank;
        this.star = star;
        this.nicename = nicename;
        this.truename = truename;
        this.description = description;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getRank() {
        return rank;
    }

    public void setRank(String rank) {
        this.rank = rank;
    }

    public String getStar() {
        return star;
    }

    public void setStar(String star) {
        this.star = star;
    }

    public String getNicename() {
        return nicename;
    }

    public void setNicename(String nicename) {
        this.nicename = nicename;
    }

    public String getTruename() {
        return truename;
    }

    public void setTruename(String truename) {
        this.truename = truename;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    @Override
    public String toString() {
        return "HeroBean{" +
                "id=" + id +
                ", rank='" + rank + '\'' +
                ", star='" + star + '\'' +
                ", nicename='" + nicename + '\'' +
                ", truename='" + truename + '\'' +
                ", description='" + description + '\'' +
                '}';
    }
}

位置: src/blb.chc03.dao.HeroDao

package blb.chc03.dao;

import blb.chc03.bean.HeroBean;

import java.util.List;

public interface HeroDao {

    //定义一个方法,根据名称查询所有
    public abstract List<HeroBean> selectByName(String name);
}

位置:src/blb.chc03.dao.impl.HeroDaoImpl

import blb.chc03.bean.HeroBean;
import blb.chc03.dao.HeroDao;
import blb.chc03.util.JDBCUtil;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;

import java.util.List;

public class HeroDaoImpl implements HeroDao {
    @Override
    public List<HeroBean> selectByName(String name) {
        //定义sql语句
        String sql = "SELECT * FROM waterhero WHERE truename LIKE '" + name + "%'";
        //采用 JdbcTemplate 去完成
        JdbcTemplate template = new JdbcTemplate(JDBCUtil.getDataSource());
        List<HeroBean> mList = template.query(sql, new BeanPropertyRowMapper<>(HeroBean.class));
        return mList;
    }
}

位置 src/blb.chc03.service.HeroService

package blb.chc03.service;

import blb.chc03.bean.HeroBean;

import java.util.List;

public interface HeroService {

    //定义一个方法,根据名称查询所有
    public abstract List<HeroBean> selectByName(String name);
}

位置 src/blb.chc03.service.impl.HeroServiceImpl

package blb.chc03.service.impl;

import blb.chc03.bean.HeroBean;
import blb.chc03.dao.HeroDao;
import blb.chc03.dao.impl.HeroDaoImpl;
import blb.chc03.service.HeroService;

import java.util.List;

public class HeroServiceImpl implements HeroService {
    @Override
    public List<HeroBean> selectByName(String name) {
        //只需要创建 HeroDao 里面的对象,得到结果
        HeroDao dao = new HeroDaoImpl();
        List<HeroBean> heroBeanList = dao.selectByName(name);
        return heroBeanList;
    }
}

位置 src/blb.chc03.util.JDBCUtil

package blb.chc03.util;


import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.FileInputStream;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

public class JDBCUtil {

    private static DataSource ds = null;

    static {
        try {
            String path = "C:\\develop\\workspace\\java210712A\\JavaWebDay24\\web\\dir\\druid.properties";
            FileInputStream is = new FileInputStream(path);
            Properties pp = new Properties();
            pp.load(is);
            is.close();
            ds = DruidDataSourceFactory.createDataSource(pp);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取到连接池对象的方法
     */
    public static DataSource getDataSource(){
        return ds;
    }


    /***
     * 获取到连接的对象
     */
    public static Connection getConnection() {
        Connection conn = null;
        try {
            //预防空指针异常。如果我们的 Properties 内容错误
            if (ds != null) {
                conn = ds.getConnection();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return conn;
    }


    /**
     * 释放资源
     */
    public static void close(Connection conn, Statement stat){
        close(conn,stat,null);
    }

    public static void close(Connection conn, Statement stat, ResultSet resu){
        if (resu!=null){
            try {
                resu.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (stat!=null){
            try {
                stat.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (conn!=null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

3、Servlet的实现

/***
 * http://localhost:8080/JavaWebDay24/HeroServlet?truename=宋
 */

@WebServlet("/HeroServlet")
public class HeroServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("HeroServlet.doGet");
        doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("HeroServlet.doPost");
        //编码方式和数据的获取
        req.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=UTF-8");
        String truename = req.getParameter("truename");
        //访问服务层 service 的代码
        HeroService service = new HeroServiceImpl();
        List<HeroBean> mList = service.selectByName(truename);
        //封装成为JSON数据
        ObjectMapper mapper = new ObjectMapper();
        String json = mapper.writeValueAsString(mList);
        //响应数据给浏览器
        resp.getWriter().println(json);
    }
}

4、JSP页面实现

<%@ page import="com.fasterxml.jackson.databind.ObjectMapper" %>
<%@ page import="blb.chc03.bean.HeroBean" %>
<%@ page import="java.util.List" %>
<%@ page import="com.fasterxml.jackson.core.type.TypeReference" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>搜索联想案例</title>
</head>
<body>

<form method="get" action="${pageContext.request.contextPath}/HeroServlet">

    <input id="truename" type="text" name="truename" placeholder="请输入水浒英雄的名字">
</form>
<div id="divid">

</div>

</body>
</html>

<script src="../js/jquery-3.3.1.min.js"></script>
<script>
    $(function () {
        $("#truename").change(function () {
            //获取到数据值
            let truename = this.value;
            //准备发送ajax请求
            $.ajax({
                url:"${pageContext.request.contextPath}/HeroServlet",
                data:{
                    "truename":truename
                },
                async:true,
                type:"GET",
                success:function (data) {
                   //直接展示结果
                    $("#divid").html(data);
                }
            });
        });
    });
</script>

;