javaWeb Ajax
异步加载、客户端和服务器数据交互更新在局部页面的技术、局部刷新
局部刷新、效率高
用户体验好
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 <%@ page contentType="text/html;charset=UTF-8" language="java" %> <script type="text/javascript" src="lib/jquery-3.2.1.min.js" ></script> <html> <head> <title>首页</title> <script type="text/javascript" > $(function () { var btn = $("#btn" ); btn.click(function () { $.ajax({ url: "/test" , type: "post" , data: "id=1" , dataType: "json" , success: function (data) { var id = $("#id" ); var name = $("#name" ); var score = $("#score" ); id.val(data.id); name.val(data.name) score.val(data.score) } }); }); }); </script> </head> <body> <h1 style="color: aqua" >${String }</h1> 编号<input id="id" type="text" /><br/> 姓名<input id="name" type="text" /><br/> 分数<input id="score" type="text" /><br/> <input id="btn" type="button" value="点击添加" > </body> </html>
1 2 3 4 5 6 7 8 9 10 11 12 13 public class User { private Integer id; private String name; private double score; public User (Integer id, String name, double score) { this .id = id; this .name = name; this .score = score; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 @WebServlet("/test") public class testServlet extends HttpServlet { @Override protected void doPost (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setCharacterEncoding("UTF-8" ); try { TimeUnit.SECONDS.sleep(3 ); } catch (InterruptedException e) { e.printStackTrace(); }finally { User user = new User(1 ,"小博" ,99.99 ); JSONObject jsonObject = JSONObject.fromObject(user); resp.getWriter().write(jsonObject.toString()); } } }
url:请求的后端服务地址
type:请求方式、默认get
data:请求参数
dataType:服务器返回的数据类型、text/json/html/xml、一般为text/json
success:请求成功的回调函数
error:请求失败的回调函数
complete:请求完成的回调函数、无论成功或者失败都会调用
Ajax大致原理
传统Web数据交互和Ajax数据交互的区别
客户端请求方式
传统Web发送同步请求 Ajax发送异步请求
服务器响应方式
传统Web响应整个JSP页面 Ajax响应需要的数据
客户端处理方式
传统Web需要等待服务器完成响应并重新加载整个页面后、用户才能继续后续操纵 Ajax动态更新页面中局部内容、不影响用户其他操作
JSON
一种轻量级数据交互格式、完成js与后端开发语言对象之间的转换
1 2 3 4 5 var user = { id : 1 , name : "小博" , score : 99.99 }
省市区分级联动模拟 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 <%@ page contentType="text/html;charset=UTF-8" language="java" %> <script type="text/javascript" src="js/jquery-3.2.1.min.js" ></script> <html> <head> <title>地区</title> <script type="text/javascript" > $(function () { $("#shi" ).change(function () { var id = $(this ).val(); $.ajax({ url: "/servlet" , type: "post" , data: "id=" + id + "&type=shi" , dataType: "json" , success: function (data) { var common = "" ; for (var i = 0 ; i < data.length; i++) { common += "<option>" + data[i] + "</option>" ; } $("#qu" ).html(common); } }) }); $("#sheng" ).change(function () { var id = $(this ).val(); $.ajax({ url: "/servlet" , type: "post" , data: "id=" + id + "&type=sheng" , dataType: "json" , success: function (data) { var common = "" ; var shi = data.shi; for (var i = 0 ; i < shi.length; i++) { common += "<option>" + shi[i] + "</option>" ; } $("#shi" ).html(common); var common = "" ; var qu = data.qu; for (var i = 0 ; i < qu.length; i++) { common += "<option>" + qu[i] + "</option>" ; } $("#qu" ).html(common); } }); }); }); </script> </head> <body> 省<select id="sheng" > <option value="请选择" >请选择</option> <option value="辽宁省" >辽宁省</option> <option value="吉林省" >吉林省</option> <option value="黑龙江省" >黑龙江省</option> </select> 市<select id="shi" > <option value="请选择" >请选择</option> </select> 区<select id="qu" > <option>请选择</option> </select> </body> </html>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 @WebServlet("/servlet") public class AjaxServlet extends HttpServlet { private static Map<String, List<String>> map = null ; private static Map<String, List<String>> map1 = null ; static { map = new HashMap<>(); List<String> list = new ArrayList<>(); list.add("沈北新区" ); list.add("皇姑区" ); list.add("和平区" ); map.put("沈阳市" ,list); list = new ArrayList<>(); list.add("昌图县" ); list.add("西丰县" ); list.add("铁岭县" ); map.put("铁岭市" ,list); list = new ArrayList<>(); list.add("西岗区" ); list.add("甘井子区" ); list.add("高薪园区" ); map.put("大连市" ,list); list = new ArrayList<>(); list.add("吉林一区" ); list.add("吉林二区" ); map.put("吉林市" ,list); list = new ArrayList<>(); list.add("长春一区" ); list.add("长春二区" ); map.put("长春市" ,list); list = new ArrayList<>(); list.add("四平一区" ); list.add("四平二区" ); map.put("四平市" ,list); map1 = new HashMap<>(); list = new ArrayList<>(); list.add("沈阳市" ); list.add("大连市" ); list.add("铁岭市" ); map1.put("辽宁省" ,list); list = new ArrayList<>(); list.add("吉林市" ); list.add("四平市" ); list.add("长春市" ); map1.put("吉林省" ,list); list = new ArrayList<>(); list.add("哈尔滨市" ); list.add("齐齐哈尔市" ); list.add("鹤岗市" ); map1.put("黑龙江省" ,list); } @Override protected void doPost (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setCharacterEncoding("UTF-8" ); String id = req.getParameter("id" ); String type = req.getParameter("type" ); if (type.equals("shi" )){ List<String> list = map.get(id); JSONArray jsonArray = JSONArray.fromObject(list); resp.getWriter().write(jsonArray.toString()); }else if (type.equals("sheng" )){ List<String> shi = map1.get(id); String s = shi.get(0 ); List<String> qu = map.get(s); Region region = new Region(); region.setShi(shi); region.setQu(qu); JSONObject jsonObject = JSONObject.fromObject(region); resp.getWriter().write(jsonObject.toString()); } } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public class Region { private List<String> shi; private List<String> qu; public List<String> getShi () { return shi; } public void setShi (List<String> shi) { this .shi = shi; } public List<String> getQu () { return qu; } public void setQu (List<String> qu) { this .qu = qu; } }
JDBC
DriverManager类
Connection接口
Statement接口
ResultSet接口
加载数据驱动 获取Connection、java于数据库一次连接 创建Statement对象、由Connection产生执行SQL 创建ResultSet对象、保存Statement执行之后所查询到的结果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 public static void main (String[] args) { try { Class.forName("com.mysql.cj.jdbc.Driver" ); String url = "jdbc:mysql://localhost:3306/test_jdbc?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC" ; Connection connection = DriverManager.getConnection(url, "root" , "123" ); String sql = "SELECT * FROM student" ; Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery(sql); while (resultSet.next()){ int id = resultSet.getInt("id" ); String name = resultSet.getString("name" ); double score = resultSet.getDouble("score" ); System.out.println(id + "-" + name + "-" + score); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } }
需要频繁拼接String字符串、出错率高
存在SQL注入风险
Statement的子类、提供了SQL占位符的功能
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 public static void main (String[] args) { try { Class.forName("com.mysql.cj.jdbc.Driver" ); String url = "jdbc:mysql://localhost:3306/test_jdbc?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC" ; Connection connection = DriverManager.getConnection(url, "root" , "123" ); String userName = "xiaobo" ; String passWord = "xiaobo" ; String sql = "SELECT * FROM user WHERE name = ? AND password = ?" ; PreparedStatement preparedStatement = connection.prepareStatement(sql); preparedStatement.setString(1 ,"xiaobo" ); preparedStatement.setString(2 ,"xiaobo" ); ResultSet resultSet = preparedStatement.executeQuery(); while (resultSet.next()){ if (userName.equals(resultSet.getString("password" )) && passWord.equals(resultSet.getString(2 ))){ System.out.println("登录成功" ); }else { System.out.println("登录失败" ); } } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } }
数据库连接池
为数据库建立一个缓冲区、预先向缓冲区放入一定数量的连接对象、当需要获取数据库连接时、只需要从缓冲池取出对象、用完之后在放回缓冲池中、供下一次请求使用、使资源重复利用 当数据库连接池中没有空闲的连接时、新的请求就会进入等待队列、等待其他线程释放资源
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public static void main (String[] args) { ComboPooledDataSource dataSource = new ComboPooledDataSource(); try { dataSource.setDriverClass("com.mysql.cj.jdbc.Driver" ); dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test_jdbc?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC" ); dataSource.setUser("root" ); dataSource.setPassword("123" ); dataSource.setInitialPoolSize(20 ); dataSource.setAcquireIncrement(5 ); dataSource.setMinPoolSize(2 ); dataSource.setMaxPoolSize(50 ); } catch (PropertyVetoException e) { e.printStackTrace(); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 <?xml version="1.0" encoding="UTF-8"?> <c3p0-config > <named-config name ="testc3p0" > <property name ="user" > root</property > <property name ="password" > 123</property > <property name ="driverClass" > com.mysql.cj.jdbc.Driver</property > <property name ="jdbcUrl" > jdbc:mysql://localhost:3306/test_jdbc?useUnicode=true& characterEncoding=UTF-8& serverTimezone=UTC</property > <property name ="acquireIncrement" > 5</property > <property name ="initialPoolSize" > 5</property > <property name ="minPoolSize" > 5</property > <property name ="maxPoolSize" > 10</property > </named-config > </c3p0-config >
1 ComboPooledDataSource dataSource = new ComboPooledDataSource("testc3p0" );
初始化ComboPooledDataSource传入named-config标签name属性值即可
DBUtils
BeanHandler:将结果映射成java对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 public class Student { private Integer id; private String name; private Double score; public Student () { } public Integer getId () { return id; } public void setId (Integer id) { this .id = id; } public String getName () { return name; } public void setName (String name) { this .name = name; } public Double getScore () { return score; } public void setScore (Double score) { this .score = score; } @Override public String toString () { return "Student{" + "id=" + id + ", name='" + name + '\'' + ", score=" + score + '}' ; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public static void main (String[] args) { ComboPooledDataSource dataSource = new ComboPooledDataSource("testc3p0" ); Connection connection = null ; Student student = null ; try { connection = dataSource.getConnection(); String sql = "SELECT * FROM student WHERE id = 1" ; QueryRunner queryRunner = new QueryRunner(); student = queryRunner.query(connection, sql, new BeanHandler<>(Student.class)); System.out.println(student); } catch (SQLException e) { e.printStackTrace(); }finally { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } }
Student类当中必须有无参构造、因为通过反射获取到的Stduent、Student中属性需要和数据库字段相同形成映射关系
BeanListHandler:将结果映射成List集合
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 public static void main (String[] args) { ComboPooledDataSource dataSource = new ComboPooledDataSource("testc3p0" ); Connection connection = null ; try { connection = dataSource.getConnection(); String sql = "SELECT * FROM student" ; QueryRunner queryRunner = new QueryRunner(); List<Object> list = queryRunner.query(connection, sql, new BeanListHandler<>(Student.class)); list.add(queryRunner.query(connection, sql, new BeanListHandler<>(User.class))); System.out.println(list); } catch (SQLException e) { e.printStackTrace(); }finally { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } }
MapHandler:将结果映射成Map对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public static void main (String[] args) { ComboPooledDataSource dataSource = new ComboPooledDataSource("testc3p0" ); Connection connection = null ; try { connection = dataSource.getConnection(); String sql = "SELECT * FROM student WHERE id = 1" ; QueryRunner queryRunner = new QueryRunner(); Map<String, Object> map = queryRunner.query(connection, sql, new MapHandler()); System.out.println(map.get("id" )); System.out.println(map.get("name" )); System.out.println(map.get("score" )); } catch (SQLException e) { e.printStackTrace(); }finally { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } }
MapListHandler:将结果映射成MapList集合
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public static void main (String[] args) { ComboPooledDataSource dataSource = new ComboPooledDataSource("testc3p0" ); Connection connection = null ; try { connection = dataSource.getConnection(); String sql = "SELECT * FROM student" ; QueryRunner queryRunner = new QueryRunner(); List<Map<String,Object>> list = queryRunner.query(connection,sql,new MapListHandler()); for (Map<String,Object> map : list){ System.out.println(map); } } catch (SQLException e) { e.printStackTrace(); }finally { try { connection.close(); } catch (SQLException e) { e.printStackTrace(); } } }